可重现的 NumPy 随机结果:重新播种与重新创建

Sun*_*ear 5 python numpy random-seed

根据 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()
Run Code Online (Sandbox Code Playgroud)

结果

Jea*_*nMi 6

在您的示例中,当您重新创建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)
Run Code Online (Sandbox Code Playgroud)

  • 除非您需要与较旧的 MT 使用序列兼容,否则您不妨切换到 PCG,客观上它在每个轴上都更好(更好的统计属性、更快、更少的内存)。 (2认同)