为什么使用numpy.random.seed不是一个好习惯?

时间:2019-08-30 14:00:55

标签: python numpy random random-seed

我想进行使用随机数作为输入的可重复测试。我习惯在Matlab中调用rng,在Python中调用numpy.random.seed。但是,我注意到种子帮助的“注释”部分显示为:

  

这是一个方便的传统功能。

     

最佳实践是不要重新设置BitGenerator的种子,而要重新创建一个新的BitGenerator。由于遗留原因,此处使用此方法。此示例演示了最佳实践。

     
from numpy.random import MT19937
from numpy.random import RandomState, SeedSequence
rs = RandomState(MT19937(SeedSequence(123456789)))  
# Later, you want to restart the stream
rs = RandomState(MT19937(SeedSequence(987654321)))

与文档字符串建议相比,有人知道使用种子的注意事项吗?

1 个答案:

答案 0 :(得分:4)

来自https://numpy.org/neps/nep-0019-rng-policy.html

  

获取可复制的伪随机数的最佳最佳实践是使用种子实例化生成器对象并将其传递。便利函数numpy.random。*后面的隐式全局RandomState可能会引起问题,尤其是在涉及线程或其他形式的并发时。全球状态总是有问题的。我们强烈建议避免在涉及可重复性时使用便利功能。

     

也就是说,人们确实使用它们并使用numpy.random.seed()来控制它们下面的状态。很难始终如一地对有用的API进行分类和计数,但是在单元测试中,很常见的用法是很多全局状态问题的发生率较低。

     

此NEP并不建议删除这些功能或更改它们以使用不太稳定的Generator发行实现。未来的NEP可能会出现。

     

特别是,新PRNG子系统的初始发行版应将这些便利功能保留为使用Mersenne Twister BitGenerator对象初始化的全局RandomState上方法的别名。对numpy.random.seed()的调用将转发到该BitGenerator对象。另外,全局RandomState实例必须在此初始版本中以numpy.random.mtrand._rand的名称访问:Robert Kern早就向scikit-learn承诺此名称将是稳定的。哎呀。

     

为了允许某些解决方法,必须有可能用任何其他BitGenerator对象替换全局RandomState下的BitGenerator(我们将精确的API详细信息留给新的子系统)。此后调用numpy.random.seed()应该只将给定的种子传递给当前的BitGenerator对象,而不要尝试将BitGenerator重置为Mersenne Twister。便利函数numpy.random。*的集合应与当前保持不变。它们应该是RandomState方法的别名,而不是新的不稳定的分发类(在上面的示例中为Generator)。希望获得最快,最佳发行版的用户可以遵循最佳做法,并明确实例化生成器对象。

     

此NEP并不建议保留这些要求。在拥有新的PRNG子系统的经验之后,我们可以并且应该在以后的NEP中重新审视这些问题。