【问题标题】:Why using numpy.random.seed is not a good practice?为什么使用 numpy.random.seed 不是一个好习惯?
【发布时间】:2020-01-03 19:04:34
【问题描述】:

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

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

最好的做法是不要重新植入 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)))

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

【问题讨论】:

    标签: python numpy random random-seed


    【解决方案1】:

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

    获得可重现伪随机数的首选最佳实践是使用种子实例化生成器对象并将其传递。 numpy.random.* 便利函数背后的隐式全局 RandomState 可能会导致问题,尤其是在涉及线程或其他形式的并发时。全局状态总是有问题的。我们断然建议在涉及可重复性时避免使用便利函数。

    也就是说,人们确实使用它们并使用 numpy.random.seed() 来控制它们下面的状态。很难对 API 使用进行一致且有用的分类和计数,但一个非常常见的用法是在单元测试中,其中许多全局状态问题不太可能出现。

    本 NEP 不建议删除这些函数或更改它们以使用不太稳定的生成器分发实现。未来的 NEP 可能会。

    具体来说,新 PRNG 子系统的初始版本应将这些便利函数作为别名保留为使用 Mersenne Twister BitGenerator 对象初始化的全局 RandomState 上的方法。对 numpy.random.seed() 的调用将被转发到该 BitGenerator 对象。此外,在这个初始版本中,全局 RandomState 实例必须可以通过名称 numpy.random.mtrand._rand 访问:Robert Kern 很久以前就向 scikit-learn 承诺过这个名称将是稳定的。哎呀。

    为了允许某些变通方法,必须可以将全局 RandomState 下的 BitGenerator 替换为任何其他 BitGenerator 对象(我们将精确的 API 细节留给新的子系统)。此后调用 numpy.random.seed() 应该只将给定的种子传递给当前的 BitGenerator 对象,而不是尝试将 BitGenerator 重置为 Mersenne Twister。 numpy.random.* 便利函数集应保持与当前相同。它们应该是 RandomState 方法的别名,而不是新的不太稳定的分布类(上例中的生成器)。想要获得最快、最佳分布的用户可以遵循最佳实践并显式实例化生成器对象。

    本 NEP 并未提议永久保留这些要求。在我们对新的 PRNG 子系统有经验之后,我们可以而且应该在未来的 NEP 中重新审视这些问题。

    【讨论】:

    • 谢谢。这个 NEP 实际上对任何对可重现模拟感兴趣的人都非常有用。它涉及我忽略的其他重要方面......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2011-07-02
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2012-05-30
    相关资源
    最近更新 更多