【问题标题】:Python Numpy Random Numbers - inconsistent?Python Numpy 随机数 - 不一致?
【发布时间】:2013-10-22 17:20:16
【问题描述】:

我正在尝试在 python 中生成对数正态分布的随机数(用于以后的 MC 模拟),当参数稍大时,我发现结果非常不一致。

下面我从 Normals(然后使用 Exp)和直接从 LogNormals 生成一系列 LogNormals。 结果均值是可以忍受的,但方差 - 非常不精确.. 这也适用于 mu = 4,5,...

如果您重新运行以下代码几次 - 结果会完全不同。

代码:

import numpy as np
mu = 10;
tmp1 = np.random.normal(loc=-mu, scale=np.sqrt(mu*2),size=1e7)
tmp1 = np.exp(tmp1)
print tmp1.mean(), tmp1.var()
tmp2 = np.random.lognormal(mean=-mu, sigma=np.sqrt(mu*2), size=1e7)
print tmp2.mean(), tmp2.var()
print 'True Mean:', np.exp(0), 'True Var:',(np.exp(mu*2)-1)

有什么建议可以解决这个问题吗? 我也在 Wakari.io 上尝试过 - 所以结果在那里也是一致的

更新: 我采用了来自维基百科的“真实”均值和方差公式:https://en.wikipedia.org/wiki/Log-normal_distribution

结果快照: 1)

0.798301881219 57161.0894726
1.32976988569 2651578.69947
True Mean: 1.0 True Var: 485165194.41

2)

1.20346203176 315782.004309
0.967106664211 408888.403175
True Mean: 1.0 True Var: 485165194.41

3) 最后一个有 n=1e8 个随机数

1.17719369919 2821978.59163
0.913827160458 338931.343819
True Mean: 1.0 True Var: 485165194.41

【问题讨论】:

  • 您可以为我们重新运行几次代码并发布结果吗?
  • 这段代码无法运行,因为您从未从任何地方导入任何这些函数。你可能想要from numpy import sqrt, exp,但这只是猜测。
  • 注意,numpy.random.normal 的比例是标准差,而不是方差。
  • 另外,你是从哪里得到这些算法的? -2*mu+mu*2 是 0,所以我不确定你要计算什么。
  • @abarnert 我敢打赌这就是方差不精确的来源......

标签: python random numpy


【解决方案1】:

即使您拥有大量样本,使用这些参数,估计的方差也会随着运行而发生巨大变化。这就是肥尾对数正态分布的本质。尝试多次运行np.exp(np.random.normal(...)).var()。您将看到与np.random.lognormal(...).var() 类似的值波动。

无论如何,np.random.lognormal() 只是实现为 np.exp(np.random.normal())(嗯,C 等效项)。

【讨论】:

  • 是的,就是肥尾巴。如果您浏览这些值,您会看到一些疯狂的异常值。
  • 好的,这确实有道理。我根本不期望当所选的平均值最高10,15。时,这些错误已经出现。
  • 不过,如果上面发布的值是真的,Vytautas 得到的值比它应该的值低几个数量级。所以,异常值实际上太少了。我确实同意肥尾,只是我认为我们没有得到足够的高分(见下面@Craig J Copi 的评论)。
【解决方案2】:

好的,因为您刚刚构建了示例,并使用了维基百科中的符号(第一部分,mu 和 sigma)以及您给出的示例:

from numpy import log, exp, sqrt
import numpy as np
mu = -10
scale = sqrt(2*10)   # scale is sigma, not variance
tmp1 = np.random.normal(loc=mu, scale=scale, size=1e8)
# Just checking
print tmp1.mean(), tmp1.std()
# 10.0011028634 4.47048010775, perfectly accurate
tmp1_exp = exp(tmp1)    # Not sensible to use the same name for two samples
# WIKIPEDIA NOTATION!
m = tmp1_exp.mean()     # until proven wrong, this is a meassure of the mean
v = tmp1_exp.var()  # again, until proven wrong, this is sigma**2
#Now, according to wikipedia
print "This: ", log(m**2/sqrt(v+m**2)), "should be similar to", mu
# I get This:  13.9983309499 should be similar to 10
print "And this:", sqrt(log(1+v/m**2)), "should be similar to", scale
# I get And this: 3.39421327037 should be similar to 4.472135955

因此,即使这些值并不完全完美,我也不会声称它们是完全错误的。

【讨论】:

  • 他们并没有“完全”错 - 但我确实想用它来建模并获得可靠的“收敛”结果......这个问题花了我一段时间才在完整代码中找到 - 我确定我在某处有一些“数学”错误......
  • @Vytautas 我认为您的分布宽度(您的比例)存在问题,或者您将需要更多样本。对于 scale=sqrt(20),对数正态分布中 x 的“3-sigma”范围跨越超过 11 个数量级! [即 exp[6*scale]~10^{11.6}.] 因此,我预计需要超过 10^{11} 个值才能正确采样分布。
猜你喜欢
  • 2018-01-09
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多