可重现的 NumPy 的随机结果:重新播种与重新创建
Reproducible NumPy's random results: Reseeding vs Recreating
根据 NumPy 的 numpy.random.seed()
documentation:
This is a convenience, legacy function.
The best practice is to not reseed a BitGenerator, rather to recreate
a new one. This method is here for legacy reasons. This example
demonstrates best practice.
但是,我注意到重新创建位生成器的结果不可重现。相反,重新播种位生成器会提供可重现的结果。为什么会这样?我做错了什么?
此外,他们的结果也不同。为什么会这样?使用的不是同一个 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()
在您的示例中,当您重新创建 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)
根据 NumPy 的 numpy.random.seed()
documentation:
This is a convenience, legacy function.
The best practice is to not reseed a BitGenerator, rather to recreate a new one. This method is here for legacy reasons. This example demonstrates best practice.
但是,我注意到重新创建位生成器的结果不可重现。相反,重新播种位生成器会提供可重现的结果。为什么会这样?我做错了什么?
此外,他们的结果也不同。为什么会这样?使用的不是同一个 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()
在您的示例中,当您重新创建 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)