如何使用Scikit Learn获得绝对可重复的结果?

9
关于使用Scikit-Learn运行机器学习算法时的种子系统,通常会提到三个不同的内容:
  • random.seed
  • np.random.seed
  • SkLearn中的random_state(交叉验证迭代器、ML算法等)

我已经在脑海中有了这个FAQSkLearn,以及articles指出这不应该只是一个简单的FAQ。

我的最终问题是,如何在使用SkLearn运行ML算法时获得完全可重复的结果?

更详细地说:

  • 如果我只使用np.random.seed而不在SkLearn中指定任何random_state,那么我的结果是否完全可重复?

至少出于知识的考虑,还有一个问题:

  • np.random.seedSkLearnrandom_state是如何在内部相关的?np.random.seed如何影响SkLearn的种子系统(random_state),并使其(至少从理论上讲)能够再现相同的结果?
3个回答

6
定义随机种子将确保每次运行算法时,随机数生成器会产生相同的数字。在我看来,只要使用相同的数据和任何其他参数的相同值,结果将始终相同。
正如您在sklearn的FAQ中所读到的那样,无论是通过全局定义numpy.random.seed()还是通过设置所有涉及算法的random_state参数,只要为这两种情况设置相同的数字,结果都是相同的。
我从sklearn的文档中引用了一个例子来说明这一点。
import numpy
from sklearn.model_selection import train_test_split
# numpy.random.seed(42)
X, y = np.arange(10).reshape((5, 2)), range(5)

#1 running this many times, Xtr will remain [[4, 5],[0, 1],[6, 7]].
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.33, random_state=42)

#2 try running this line many times, you will get various Xtr
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.33)

现在取消注释第三行。运行#2多次。Xtr将始终为[[4, 5],[0, 1],[6, 7]]
通过numpy.random.seed(),它将种子设置为默认值(None),然后尝试从/dev/urandom(或Windows的类似物)读取数据(如果可用)或从时钟中获取种子。 文档

1
是的,现在对我来说更清楚了,“每当没有提供RandomState实例或整数随机种子作为参数时,它依赖于numpy全局随机状态,可以使用numpy.random.seed进行设置”。 - Outcast
然而,我的一个问题是:如果您没有为 numpy.random.seed 设置任何值,那么它会自行随机选择一个值吗? - Outcast
是的,它会选择一个值,但当然不是以随机方式。你如何想象计算机中的“随机”?因此,如果您不定义种子,它将在使用当前时间戳作为种子的情况下生成。这就是为什么当您现在和以后生成它时会得到不同的数字。 - ipramusinto
显然,我在谈论这种随机性(比如根据时间戳等“随机”因素选择 numpy 种子值)。然而,我们知道它使用时间戳吗? - Outcast
@PoeteMaudit 如果答案的一部分没有回答你的问题,请在评论中提出,建议编辑删除它不是正确的行动。 - WhatsThePoint
显示剩余2条评论

0
在scikit-learn文档示例中,例如这里,他们使用np.random.seed(n),它似乎是有效的。

很酷,但我期望在StackOverflow的答案中对sklearn和numpy的种子系统进行更彻底的分析。 - Outcast
虽然这个链接可能有助于回答问题,但您可以通过提取链接的关键部分并将其放入您的答案中来改进此答案,这样可以确保如果链接被更改或删除,您的答案仍然是一个完整的答案 :) - WhatsThePoint

0

我刚刚在玩numpysklearn。显然,设置np.random.seed不能保证sklearn的随机状态固定。我们需要为每个sklearn函数设置random_state参数以确保可重复性。


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