我知道 numpy.random.seed(seed)
会输出相同的数字,如果我使用相同的种子。我的问题是,这是否会随着时间的推移而改变?如果我明天再调用它,它还会输出和昨天一样的随机数吗?
该 np.random
文档中描述了所使用的PRNGs。显然,有部分从 MT19937
到 PCG64
在最近的过去。如果你想保持一致性,你就需要。
RandomState
, Generator
)的任何变化,以便对 其他 外部库不会因为调用了 np.random
globals本身。在这个例子中,我们使用了较新的 BitGenerator
API,它提供了各种PRNGs的选择。
from numpy.random import Generator, PCG64
rg = Generator(PCG64(1234))
其中可以使用如下。
>>> rg.uniform(0, 10, 10)
array([9.767, 3.802, 9.232, 2.617, 3.191, 1.181, 2.418, 3.185, 9.641,
2.636])
如果我们重新运行任何次数(甚至在同一个REPL内!), 我们将始终得到相同的随机数发生器. PCG64和MT19937一样,提供了以下保证。
兼容性保证
PCG64做了一个保证,一个固定的种子和将始终产生相同的随机整数流。
虽然,正如 @user2357112 支持莫妮卡所指出的那样,对随机 API 函数的改变,即 使用 的随机整数序列(如 np.random.Generator.uniform
)在技术上仍然是可能的,尽管可能性不大。
为了生成多个发生器,可以利用 SeedSequence.spawn(k)
以产生 k
不同 SeedSequence
s. 这对一致的并发计算很有用。
from numpy.random import Generator, PCG64, SeedSequence
sg = SeedSequence(1234)
rgs = [Generator(PCG64(s)) for s in sg.spawn(10)]
遗留的 RandomState
API和模块级随机生成函数(实际上是一个隐藏的RandomState的方法)有一个 向后兼容性保证:
兼容性保证
一个使用固定种子的固定位发生器和一系列使用相同参数的'RandomState'方法的固定调用将始终产生相同的结果,直到roundoff错误,除非数值不正确。RandomState实际上是被冻结的,只有在Numpy内部发生变化时才会收到更新。更多实质性的变化,包括算法上的改进,都保留给 Generator。
来自相同种子的相同调用序列将产生相同到四舍五入的错误结果,除非旧的结果有问题(比如发现一个方法没有产生它应该产生的分布)。
这是以被锁定在错误的设计选择为代价的。比如说 numpy.random.choice
与 replace=False
是非常慢的,因为它的实现不好,如果不破坏向后的兼容性,就无法修复。numpy.random.Generator.choice
但它没有这个问题,因为它不受同样的兼容性保证的约束。