为何不建议使用numpy.random.seed?可复现随机测试实践疑问
我来给你掰扯清楚为什么numpy官方不推荐用numpy.random.seed(),以及它到底有哪些坑:
全局状态污染问题:
seed()是直接修改numpy全局默认的随机数生成器状态。这意味着如果你在自己的代码里设置了种子,之后调用的任何第三方库、函数只要用到了numpy的随机模块(比如numpy.random.rand()这类全局函数),都会共享这个全局状态。举个例子:你刚设了seed(123)准备生成实验用的随机数,结果调用了某个数据预处理库,里面偷偷调用了numpy.random.shuffle(),那你后续生成的随机序列就完全偏离预期了,可复现性直接失效。无法管理多独立随机流:如果你的实验需要同时维护多个互不干扰的随机序列(比如不同实验组用不同的随机数),
seed()根本做不到。因为它只能全局设置一次,每次重新seed()都会覆盖全局状态,没法同时运行多个独立的生成器。而官方推荐的方法可以创建多个RandomState实例,每个绑定自己的BitGenerator和种子,各玩各的,完全不冲突。BitGenerator选择受限:
numpy.random.seed()默认只能用MT19937这个旧的随机数生成算法。现在numpy已经支持更高效、统计特性更好的生成器(比如PCG64、Philox),但用seed()你没法直接切换到这些新算法,只能被局限在MT19937里。而官方推荐的写法可以轻松替换BitGenerator类型,比如把MT19937换成PCG64,只需要改一行代码,灵活性拉满。遗留函数的维护风险:官方明确说了
seed()是“遗留便捷函数”,这意味着它只是为了兼容老代码才保留的,未来的numpy版本可能会逐步弱化它的功能,甚至直接标记为废弃。现在用它写的代码,说不定哪天升级numpy就出问题了,而采用官方推荐的新写法,是符合未来版本的最佳实践,兼容性和稳定性更有保障。
对比下来,官方推荐的创建独立RandomState+BitGenerator的方式,既能保证随机序列的可复现性,又能避免全局状态的干扰,还能灵活选择更优的生成算法,显然是更可靠的方案。
内容的提问来源于stack exchange,提问作者Gabriel Gleizer

