对scipy的连续分布进行子类化

时间:2013-06-13 17:24:27

标签: statistics scipy

我正在试图弄清楚如何创建一个新的scipy.stats.rv_continuous子类。我的分布取决于“位置”和“形状”参数,但_pdf中的scipy.stats.distributions的每个示例都假设形状&位置参数可以简单地应用于X轴,而某些分布则不是这种情况。

例如,我正在使用的一个分布是对数正态的修改版本,其中X轴位置明确地取决于分布的宽度,即:

def _pdf(self, x, x0, s):
    Px = exp(-(log(x/x0)+s**2/2.)**2 / (2*s**2))
    return Px / (s*x0*sqrt(2*pi))

我希望能够loc使用x0scale使用s。有没有办法做到这一点,还是有更好的方法来继承rv_continuous

(请注意,仅仅使用我定义的PDF会导致其他rv_continuous方法出现问题,例如.fit,因为locscale仍在处理中作为“自由参数”,即使它们不应该是)

2 个答案:

答案 0 :(得分:1)

您真的不应该尝试更改locscale的含义。它们是标准的,定义明确的位置和比例参数,例如,在scipy.stats tutorial,维基百科herehere以及here中进行了解释。

正如我在评论中提到的,您的公式中似乎缺少1/x0因子。没有它,PDF的0到无穷大的积分是x0,而不是1。

通过更正,很明显x0实际上是比例参数。 s是形状参数。与仅在正实轴上定义的许多其他分布(例如,伽马或对数正态)一样,您可以简单地忽略位置参数 - 其默认值为0.(如果使用fit方法,请确保使用参数floc=0,以防止该方法将loc视为自由参数。)但是,我不确定你的意思是“X轴位置明确取决于宽度分布“ - 什么的X轴位置?

答案 1 :(得分:1)

除了沃伦的回答:

scipy.stats中的分布假设locscale是通常的标准化y = (x - loc) / scale。因此,如果不遵循该定义,则无法对分发进行子类化。

但是,您可以编写一个新的包装类,该类委托给scipy.stats.distributions的(子)类,并在此包装类中进行任何重新参数化。

在这种情况下,您可以修复一些参数,例如loc,并在调用标准类之前更改参数名称。

使用更标准的参数化创建一个lognorm包装器可以更容易在遵循例如教科书时使用,但不会做与scipy.stats中的分发不同的任何事情。