Python random.seed() 和 numpy.random.seed() 的实现是否不同?

Does Python random.seed() and numpy.random.seed() implementations differ one from another?

我正在尝试实施 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

我的问题是:

  1. 分布(来自随机数据集的平均值)是否受到每个模块(randomnumpy)提供随机数据的方式的影响?
  2. 如果第一个问题是正确的:因为我提供 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()