首页 > 解决方案 > 可重现 NumPy 的随机结果:重新播种 vs 重新创建

问题描述

根据 NumPy 的numpy.random.seed() 文档

这是一个方便的遗留功能。

最佳做法是不要重新植入 BitGenerator,而是重新创建一个新的。出于遗留原因,此方法在这里。这个例子展示了最佳实践。

但是,我注意到重新创建位生成器的结果是不可重现的。相反,重新播种位生成器会产生可重现的结果。为什么会这样?我究竟做错了什么?

此外,他们的结果也不同。为什么会这样?使用的不是相同的 Mersenne Twister (MT) 算法吗?

我的重现我的观察的脚本如下所示。

import numpy as np
from numpy.random import MT19937
from numpy.random import RandomState, SeedSequence
import matplotlib.pyplot as plt

seed=123456789

# Reseed a BitGenerator
np.random.seed(seed)
r1 = np.random.random_integers(1, 6, 1000)
np.random.seed(seed)
r2 = np.random.random_integers(1, 6, 1000)

# Recreate a BitGenerator
rs = RandomState(MT19937(SeedSequence(seed)))
c1 = np.random.random_integers(1, 6, 1000)
rs = RandomState(MT19937(SeedSequence(seed)))
c2 = np.random.random_integers(1, 6, 1000)

# Visualise results
fig, axes = plt.subplots(1, 2)
axes[0].hist(r1, 11, density=True)
axes[0].hist(r2, 11, density=True)
axes[0].set_title('Reseed a BitGenerator')

axes[1].hist(c1, 11, density=True)
axes[1].hist(c2, 11, density=True)
axes[1].set_title('Recreate a BitGenerator')

plt.show()

结果

标签: pythonnumpyrandom-seed

解决方案


在您的示例中,当您重新创建RandomState对象时,您在获取随机数时没有使用它。

创建时,RandomState您不会重新播种整个 numpy 环境。而是创建一个新的随机生成器对象。

将您的代码更改为:

# Recreate a BitGenerator
rs1 = RandomState(MT19937(SeedSequence(seed)))
c1 = rs1.random_integers(1, 6, 1000)
rs2 = RandomState(MT19937(SeedSequence(seed)))
c2 = rs2.random_integers(1, 6, 1000)

推荐阅读