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
我的问题是:
- 分布(来自随机数据集的平均值)是否受到每个模块(
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()
。
我正在尝试实施 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()
。