Scipy中的对数正态随机变量

9
我不太理解如何按照这里所述创建对数正态变量的基础知识。 对数正态分布以均值和方差作为参数,我想使用这些参数创建一个冻结的分布,然后获取cdf、pdf等内容。
然而,在文档中,他们使用以下代码获取了冻结的分布:
from scipy.stats import lognorm
s = 0.953682269606
rv = lognorm(s)

's' 似乎是标准差。我尝试使用 'loc' 和 'scale' 参数代替 's',但是出现了错误(s 是必需的参数)。如何使用参数值 'm'、's' 生成一个带有固定参数的分布?

1个回答

15

谜团已解决(编辑3)

  • μ 对应于 ln(scale) (!)
  • σ 对应于形状 (s)
  • loc 在设置 σ 和 μ 时不需要

我认为这个问题严重,因为它没有得到清楚的记录。我猜很多人在使用 SciPy 中的对数正态分布时都会遇到这个问题。

为什么会这样呢?

对于所有分布,stats 模块将 locscale 视为相同的(虽然没有明确说明,但可以从字里行间推断出来)。我的怀疑是 loc 被从 x 中减去,结果被除以 scale(并且该结果被视为新的 x)。我进行了测试,证实了这一点。

那么对于对数正态分布意味着什么呢?在对数正态分布的规范定义中,术语 ln(x) 出现了。显然,在SciPy的实现中也出现了相同的术语。根据上述考虑,这就是为什么 locscale最终会出现对数中的原因:

ln((x-loc)/scale)

通过常用对数计算,这与以下式子相同:

ln(x-loc) - ln(scale)

在对数正态分布的经典定义中,术语只是 ln(x) - μ。比较SciPy的方法和经典方法,可以提供关键性的见解: ln(scale)代表μ 。然而,loc在经典定义中没有对应物,最好保持为0。下面我将进一步证明形状(s)为σ。

证明

>>> import math
>>> from scipy.stats import lognorm
>>> mu = 2
>>> sigma = 2
>>> l = lognorm(s=sigma, loc=0, scale=math.exp(mu))
>>> print("mean: %.5f  stddev: %.5f" % (l.mean(), l.std()))
mean: 54.59815  stddev: 399.71719

我使用WolframAlpha作为参考。它提供对数正态分布的平均值和标准差的解析确定值。

http://www.wolframalpha.com/input/?i=log-normal+distribution%2C+mean%3D2%2C+sd%3D2

enter image description here

这些值是匹配的。

WolframAlpha和SciPy都通过评估解析项来得出平均值和标准差。让我们通过从SciPy分布中取许多样本并从整个样本集计算它们的平均值和标准差“手动”进行经验测试:

>>> import numpy as np
>>> samples = l.rvs(size=2*10**7)
>>> print("mean: %.5f  stddev: %.5f" % (np.mean(samples), np.std(samples)))
mean: 54.52148  stddev: 380.14457

这仍然没有完全收敛,但我认为已经足以证明样本对应于WolframAlpha假设的相同分布,给定μ=2和σ=2。

另一个小修改:看起来正确使用搜索引擎会有所帮助,我们不是第一个陷入困境的人:

https://stats.stackexchange.com/questions/33036/fitting-log-normal-distribution-in-r-vs-scipy http://nbviewer.ipython.org/url/xweb.geos.ed.ac.uk/~jsteven5/blog/lognormal_distributions.ipynb scipy,lognormal 分布 - 参数

另一个修改:现在我知道它的行为方式,我意识到原则上的行为是有记录的。在“注释”部分中,我们可以读到:

具有形状参数sigma和比例参数exp(mu)

它只是真的不明显(我们都不能理解这个小句子的重要性)。我猜我们无法理解这个句子的原因是注释部分所显示的解析表达式不包括 loc 和 scale。我想这值得一个错误报告/文档改进。

原始回答:

确实,当查看特定分布的文档页面时,形状参数主题并不好记录。我建议查看主要的统计文档——其中有一个关于形状参数的部分:

http://docs.scipy.org/doc/scipy/reference/tutorial/stats.html#shape-parameters

看起来应该有一个 lognorm.shapes 属性,告诉你 s 参数的具体含义。

编辑: 实际上只有一个参数:

>>> lognorm.shapes
's'

当比较从维基百科得到的对数正态分布的一般定义:enter image description here

和Scipy文档中给出的公式时:

lognorm.pdf(x, s) = 1 / (s*x*sqrt(2*pi)) * exp(-1/2*(log(x)/s)**2)

很明显,s是真正的σ(sigma)。

然而,从文档中并不清楚loc参数与μ(mu)有何关系。

它可能是如ln(x-loc)那样,这将不会对应于一般公式中的μ,或者它可能是ln(x)-loc,这将确保loc和μ之间的对应。试试看!:)

编辑2

我已经比较了WolframAlpha(WA)和SciPy所说的内容。WA非常清楚地使用了通常理解的μ和σ(在链接的维基百科文章中定义)。

>>> l = lognorm(s=2, loc=0)
>>> print("mean: %.5f  stddev: %.5f" % (l.mean(), l.std()))
mean: 7.38906  stddev: 54.09584

这与WolframAlpha的输出相符。

现在,如果loc不为零,则存在不匹配的情况。例如:

>>> l = lognorm(s=2, loc=1)
>>> print("mean: %.5f  stddev: %.5f" % (l.mean(), l.std()))
mean: 8.38906  stddev: 54.09584

WA 给出 的平均值为20.08,标准差为147。这就是它,loc 不对应于 lognormal 分布的经典定义中的 μ。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接