我正在试图弄清楚如何创建一个新的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
使用x0
,scale
使用s
。有没有办法做到这一点,还是有更好的方法来继承rv_continuous
?
(请注意,仅仅使用我定义的PDF会导致其他rv_continuous
方法出现问题,例如.fit
,因为loc
和scale
仍在处理中作为“自由参数”,即使它们不应该是)
答案 0 :(得分:1)
您真的不应该尝试更改loc
和scale
的含义。它们是标准的,定义明确的位置和比例参数,例如,在scipy.stats tutorial,维基百科here和here以及here中进行了解释。
正如我在评论中提到的,您的公式中似乎缺少1/x0
因子。没有它,PDF的0到无穷大的积分是x0
,而不是1。
通过更正,很明显x0
实际上是比例参数。 s
是形状参数。与仅在正实轴上定义的许多其他分布(例如,伽马或对数正态)一样,您可以简单地忽略位置参数 - 其默认值为0.(如果使用fit
方法,请确保使用参数floc=0
,以防止该方法将loc
视为自由参数。)但是,我不确定你的意思是“X轴位置明确取决于宽度分布“ - 什么的X轴位置?
答案 1 :(得分:1)
除了沃伦的回答:
scipy.stats中的分布假设loc
和scale
是通常的标准化y = (x - loc) / scale
。因此,如果不遵循该定义,则无法对分发进行子类化。
但是,您可以编写一个新的包装类,该类委托给scipy.stats.distributions的(子)类,并在此包装类中进行任何重新参数化。
在这种情况下,您可以修复一些参数,例如loc
,并在调用标准类之前更改参数名称。
使用更标准的参数化创建一个lognorm包装器可以更容易在遵循例如教科书时使用,但不会做与scipy.stats中的分发不同的任何事情。