我在实验实现CLT(中心极限定理)时,数据分布的差异,比较两种方法:一种是使用纯Python,另一种是Numpy。
这是我的代码。
from numpy.random import seed
from numpy.random import randint
from numpy import mean
import matplotlib.pyplot as plt
import random
# [With Numpy]
#
# Generate 1000 samples of 50 men, from 60 to 90 Kilos and calculate the mean
# of each sample, at once.
seed(1)
means = [mean(randint(60, 90, 50)) for _i in range(1000)]
# [Without Numpy]
#
# Generate 1000 samples of 50 men, from 60 to 90 Kilos.
# Calculate the mean of each sample, storing on a separated list.
random.seed(1)
samples = list()
for i in range(0, 1000):
samples.append([random.randint(60, 90) for n in range(50)])
means_without_numpy = [sum(s) / len(s) for s in samples]
# Plot distributions of sample means, side by side.
plt.subplot(1, 2, 1)
plt.title("Numpy")
plt.hist(means)
plt.subplot(1, 2, 2)
plt.title("Pure Python")
plt.hist(means_without_numpy)
plt.show()
print(f"The mean of means: {mean(means)}")
print(f"The mean of means (without numpy): {mean(means_without_numpy)}")
这段代码产生了以下直方图和一条消息,在关闭它们之后。
$ python3 clt_comparisson.py
The mean of means: 74.54001999999998
The mean of means (without numpy): 74.94394
我的问题是:
random
和 numpy
),提供随机数据?1
作为种子,它们是不是应该生成相同的随机数据集,因为它们有相同的种子值?numpy
和python的 random
使用不同的算法,我认为这对于一个用C和Fortran编写的数学包来说是很正常的。同样的算法用同样的种子会产生同样的值。
>>> import random
>>> random.seed(12345678)
>>> import numpy.random
>>> numpy.random.seed(12345678)
>>> random.randint(0, 100000)
94406
>>> numpy.random.randint(0, 100000)
67251
(不一样)
即使在一个巨大的范围内,两个实现之间的分布也会略有不同,因为你不会期望它们之间的随机性质量完全相等。如果你在同一个程序中创建第二个数据集,而不改变种子,它将会有一点变化,就像使用不同种子的数据集一样。
在密码学环境中,人们不会提供自己的种子,但在科学方面,如果你希望一个模型是可重复的,它可能是有用的。在这种情况下,你的代码可以基于 numpy.random.RandState
与一些众所周知的32整数,这样你就不用担心程序范围内的 numpy.random.seed()
别人可能需要或能够改变的。