在`scikit-learn`中,控制随机数生成,我应该使用`random.seed`还是`numpy.random.seed`?

70
我正在使用scikit-learn和numpy,并希望设置全局种子,以便我的工作可重现性。
我应该使用`numpy.random.seed`还是`random.seed` ?从评论中的链接中,我了解到它们是不同的,而且numpy版本不是线程安全的。我想知道具体要使用哪一个来创建用于数据分析的IPython笔记本。一些来自scikit-learn的算法涉及生成随机数,我想确保笔记本在每次运行时显示相同的结果。

1
使用 np.random.seed() 不需要导入任何东西,但是如果要使用 random.seed(),则需要导入 random 模块。 - ZdaR
6
请勿设置全局种子,这是不安全的。您可以创建自己的 Random 对象并设置其种子。请查看 Muhammad Alkarouri 在此问题中的最后一条评论,以获取更安全的解决方法:http://stackoverflow.com/a/3717456/1524913 - jeromej
@Leb 谢谢你提供的链接,但是在我的情况下不清楚应该使用哪一个。我已经编辑了问题。 - shadowtalker
@JeromeJ,根据那个例子,如何使用color_rnd并不清楚。如果我运行color_rnd.seed(1234),像sklearn.cross_validation.KFold这样的函数会“知道”使用它而不是它通常使用的任何RNG吗? - shadowtalker
如果他们直接依赖于random,那么可能不会如愿以偿。我的观点是,无论何时编写代码,都要避免直接使用random本身。对于你的情况,我不确定该怎么办,这有点糟糕。也许可以使用一个装饰器,但我认为你可能需要调整函数上下文,但我不能百分之百确定,我需要更深入地研究一下才能确定。 - jeromej
1个回答

63
我应该使用 np.random.seed 还是 random.seed?
这取决于你的代码中是否使用了numpy的随机数生成器或者random中的随机数生成器。
在 numpy.random 和 random 中,随机数生成器有完全不同的内部状态,所以 numpy.random.seed() 不会影响 random.random() 产生的随机序列,同样地,random.seed() 也不会影响 numpy.random.randn() 等。如果您的代码中同时使用了 random 和 numpy.random,则需要为两者单独设置种子。
更新
你的问题似乎特别涉及scikit-learn的随机数生成器。据我所知,scikit-learn 在整个过程中都使用 numpy.random,因此你应该使用 np.random.seed() 而不是 random.seed()。
一个重要的注意事项是 np.random 不是线程安全的 - 如果你设置了全局种子,然后启动几个子进程并且在其中使用 np.random 生成随机数,那么每个子进程将从其父进程继承 RNG 状态,这意味着每个子进程中将获得相同的随机变量。解决这个问题的常规方法是向每个子进程传递不同的种子(或 numpy.random.Random 实例),使每个子进程都具有单独的本地 RNG 状态。

由于scikit-learn的某些部分可以使用joblib以并行方式运行,因此您会发现一些类和函数有一个选项,可以传递种子或np.random.RandomState实例(例如,sklearn.decomposition.MiniBatchSparsePCArandom_state=参数)。我倾向于为脚本使用单个全局种子,然后基于全局种子为任何并行函数生成新的随机种子。


1
我在控制台中使用 numpy.random 进行任何随机数生成。我不知道 sklearn 内部使用什么,因此提出了我的问题。 - shadowtalker
2
谢谢。我询问的原因之一是,将numpy.random.RandomState实例传递给sklearn.grid_search.GridSearchCV的唯一方法是通过显式传递对象到其cv参数,例如sklearn.cross_validation.StratifiedKFold。然而,该构造函数要求您在模型实例化时知道数据集中的行数。这意味着每当您想要将其拟合到新数据时,都必须重新实例化模型,这不是您应该使用这些对象的方式。我会提出有针对性的后续问题。 - shadowtalker
1
我不确定我真正理解你的动机。你是否有特别的原因想要在GridSearchCV中为不同的搜索参数使用不同的交叉验证折叠?就我所知,这并不重要。 - ali_m
1
这不是我的意思。我希望每次打开笔记本并按下“全部运行”时,折叠应该保持一致,因为我需要能够重现结果。 - shadowtalker
3
我认为一般原则是最好将任何类型的元优化代码与模型类分开。这不仅更加明确,而且还倾向于导致更可重用的代码。 - ali_m
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接