为什么结果总是在2.87左右

时间:2019-06-07 08:16:00

标签: python numpy math random

我有以下代码

result=0
loop_n=10000
for i in range(loop_n):
    result+=np.random.rand(3,4,10).std()
result=result/loop_n
print(result)

据我了解,如果我多次跑步,结果应该会有所不同,因为结果是随机产生的,但实际上结果总是在0.287左右

这背后有一些理论吗?

4 个答案:

答案 0 :(得分:6)

这只是证明np.random.rand是一个不错的制服随机生成器。您有10000条观测值的分布标准偏差遵循相同的定律。标准偏差是方差的平方根,因此理论(概率)的统一标准偏差为(max - min) / sqrt(12)。您的样本量相当大,因此 observed 估计量将接近理论标准偏差1/sqrt(12),约为0.28867513459481287。但这现在成为一个数学问题:-)


假设[0,1]上的分布均匀,则概率(理论)平均值E(X)是段[0-1]上x的积分,为0.5。根据定义,方差为E((XE(X)) 2 ),可以将其计算为段[-0.5,0.5]上x 2 的积分及其平方根给出上面写的结果。

答案 1 :(得分:3)

1。为什么变异性这么小?

那是大数定律。如果您经常从随机变量中采样,那么您会期望获得对真实均值的良好估计。

https://en.wikipedia.org/wiki/Law_of_large_numbers

2。为什么是0.287?

rand返回0到1之间的均匀分布的数字,因此真实均值是1/2,并且真实方差 是整数[-1 / 2..1 / 2] x ^ 2 dx,您可以将其检查为1/12。 std是该~0.289的平方根。

3。为什么不完全是sqrt(1/12)〜0.289?

但是等等,这有点不对劲。为什么?由于numpy返回的样本var / std是真实物体的有偏估计量,因此它会系统地低估它们。在以较小N=120大小进行批量采样时,这会产生很小但一致的差异。一旦插入校正N /(N-1)(标准差的校正数),我们就会得到更好的匹配。您可以通过将关键字ddof=1传递到std来在代码中进行尝试。

4。但是经过更正后,结果似乎有点太小了?

是正确的。校正因子N/(N-1)var产生了一个无偏估计量,而对于std却没有,这基本上是因为先取均值再取sqrt与先取sqrt再取均值是不同的

您可以使用var(仍带有参数ddof=1)而不是std进行检查,并取均值后再取sqrt:

loop_n=1000000
result=0
print_at = 1
for i in range(1, loop_n+1):
    result+=np.random.rand(3,4,10).var(ddof=1)
    if i == print_at:
        print(math.sqrt(result/i))
        print_at *= 10

print("...")
print(math.sqrt(1/12))

样品运行:

0.28103387158480164
0.2952158859220745
0.2902562660869275
0.28882685146952614
0.2887019908636715
0.2886783761564752
0.2886714244895549
...
0.28867513459481287

答案 2 :(得分:1)

让我们看看你在做什么:

  • 在每个步骤中,您需要np生成0到1之间的120个随机值,并获取其标准偏差。它始终在0.2887附近,有时更大,有时更少。解释如下。
  • 您将所有这些标准差相加并除以它们的计数。本质上,您可以得到它们的平均值。
  • 因为您有很多,所以它们越来越接近0.2887的期望值。

说明:

如果您在Python控制台中执行while 1: np.random.rand(3,4,10).std(),则会看到发出了很多数字(直到您按Ctrl-C为止),它们有时是.266,有时是.297,依此类推上。

但是它们是什么意思?好吧,标准偏差是(非常粗略地说)一组值与其平均值之间的距离的平均值。

  • 如果您使用[.5, .5, .5],则平均值为.5,std为0
  • 但是对于[0, .5, 1],平均值也为.5,但标准差为.408248
  • 使用np.f64([.0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]).std(),您将获得.316
  • 通过np.random.rand(300,300,300).std(),您将获得与您大致相同的结果:总是在.2887附近。 为何期望值精确地为.2887源自标准偏差的定义。本质上,它源于np.random.rand()产生的预期均匀分布。

答案 3 :(得分:0)

numpy函数rand从均匀分布[0, 1)中绘制一个随机数,这意味着从0到1之间获得任何数字的可能性均等。您的代码从中抽取了120个随机数分布并使用公式计算标准偏差的估计值

std = sqrt(mean(abs(x - x.mean())**2))

您的代码然后计算标准偏差估算值的平均值,该平均值应使估算值收敛到理论值。

要计算理论值,我们可以将variance(x) = 1/12用于均匀分布中的随机变量X。这意味着接近仿真结果的std(x) = sqrt(1/12) = 0.2887