随机种子不是复现咒语:numpy 的两种随机流为什么让同一张图分叉
【锚点】这一篇只钉一个判断:【“开放数据+代码+固定种子”不等于可复现;随机数生成器(RNG)是实验材料,不是实现细节。】
【显式】很多复现说明会写:set.seed(42) 或 np.random.seed(42)。这句话看起来像把随机性锁住了。
【隐式】但“种子”只决定某个特定 RNG 算法的起点;它不决定算法本身。
【细微】在 Python 里,np.random.seed(42) 走的是旧版 RandomState(MT19937 系),而 np.random.default_rng(42) 默认走 PCG64。同一个 42,会生成不同随机数序列;常见版本中,前者前三个均匀数以 0.37454012 开头,后者前三个均匀数以 0.77395605 开头。于是散点、抽样、bootstrap、置换检验的图可能完全不同。
【极难发现】更隐蔽的是:即使算法相同,跨版本、跨平台、跨依赖版本时,浮点运算顺序、BLAS 线程、库实现也可能改变中间值;随机流只是第一道门,不是最后一道门。
用一个最小推演: 【流程节点链路】:【读取同一 CSV】→【固定 seed=42】→【调用不同 RNG 抽样 1000 行】→【绘制箱线图/散点图】→【得到不同样本均值与误差棒】。 如果第一步和最后一步都相同,结论差异不是【分析错了】,而是【随机材料没有锁死】。
【反方立场】我要先反对一个很流行的说法:【只要代码和数据开放,别人就能复现】。这个说法错在把复现性当成文件可得性。可复现性至少需要四层: 1.【数据层】原始数据、清洗规则、缺失值处理; 2.【代码层】分析脚本、绘图参数、坐标轴范围; 3.【环境层】语言版本、包版本、操作系统、CPU/线程设置; 4.【随机层】RNG 算法、种子、抽样顺序、是否并行。
如果对方说【换几个 seed 看稳健性就行】,那其实已经承认:单 seed 不是复现,而是敏感性检查;它只能说明结论对随机扰动有多敏感,不能证明原图可被同一材料重造。
缺少任何一层,别人复现出来的【同一张图】可能只是相似,而不是同一。
【观点】在开放科学里,最诚实的可视化不是把误差棒画得漂亮,而是把【这张图依赖哪些不可见选择】写出来。可复现图表的最小单位不是 PNG,而是【数据+代码+环境+随机流】四元组。
【可辩论问题】如果随机数生成器足以改变结论,我们是否应该把 RNG 算法和版本写进论文的【方法】部分,像引用统计方法一样引用它?







0 评论