使用 Scipy 记录正态随机变量

Log Normal Random Variables with Scipy

我无法理解创建对数正态变量的最基本知识 here

The log normal distribution takes on mean and variance as parameters。我想使用这些参数创建一个冻结分布,然后获取 cdf、pdf 等。

但是,在文档中,他们使用

获得冻结分发
from scipy.stats import lognorm
s = 0.953682269606
rv = lognorm(s)

's' 似乎是标准偏差。我尝试使用 'loc' 和 'scale' 参数而不是 's',但这会产生错误(s 是必需参数)。如何生成具有参数值 'm'、's' 的位置和比例的冻结分布?

谜底揭晓(编辑3)

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

我认为这是一个严重的问题,没有明确记录。我猜想很多人在使用 SciPy.

中的对数正态分布进行简单测试时就上当了

这是为什么?

stats 模块对所有分布的 locscale 都一视同仁(这没有明确写下来,但可以从字里行间中推断出来)。我怀疑是 x 减去 loc,结果除以 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

值匹配。

WolframAlpha 以及 SciPy 通过评估 分析 项得出均值和标准差。让我们通过从 SciPy 分布中获取许多样本来进行实证检验,并计算它们的均值和标准差 "manually"(来自整个样本集):

>>> 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 distribution - parameters

另一个编辑:现在我知道它的行为方式,我意识到原则上的行为是记录在案的。在the "notes" section中我们可以读到:

with shape parameter sigma and scale parameter exp(mu)

只是真的不明显(我们都没有意识到这句话的重要性)。我想我们无法理解这句话的原因是注释部分显示的解析表达式包括locscale。我想这值得一个错误报告/文档改进。

原回答:

确实,在查看特定发行版的文档页面时,形状参数主题没有得到很好的记录。我建议看看主要的统计文档——有一个关于形状参数的部分:

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

好像应该有个lognorm.shapes属性,具体说一下s这个参数是什么意思

编辑: 只有一个参数,确实是:

>>> lognorm.shapes
's'

比较对数正态分布的一般定义时(来自维基百科):

和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

这匹配 WA's output.

现在,因为 loc 不为零,所以存在不匹配。示例:

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

WA gives 均值为 20.08,标准差为 147。你知道了,loc 对应于经典中的 μ对数正态分布的定义。