如何为Scikit-learn设置随机数生成器的种子?

4

我正在尝试为使用scikit-learn的代码编写单元测试。然而,我的单元测试似乎是不确定性的。

据我所知,在我的代码中scikit-learn使用随机性的唯一位置是它的LogisticRegression模型和train_test_split,因此我有以下内容:

RANDOM_SEED = 5
self.lr = LogisticRegression(random_state=RANDOM_SEED)
X_train, X_test, y_train, test_labels = train_test_split(docs, labels, test_size=TEST_SET_PROPORTION, random_state=RANDOM_SEED)

但是似乎这并不起作用——即使我传递了固定的docslabels,在一个固定的验证集上的预测概率也会因为每次运行而变化。
我还尝试在代码顶部添加numpy.random.seed(RANDOM_SEED)调用,但这也似乎没有起作用。
我是否遗漏了什么?有没有一种方法可以在单个位置传递一个种子给scikit-learn,以便该种子在scikit-learn的所有调用中都被使用?

2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - sascha
2
我不确定这是否能解决你的确定性问题,但这不是使用scikit-learn中固定种子的正确方法。实例化一个prng=numpy.random.RandomState(RANDOM_SEED)实例,然后将其作为random_state=prng传递给每个单独的函数。如果只传递RANDOM_SEED,每个单独的函数都会重新启动并在不同的位置给出相同的数字,导致不良相关性。 - Robert Kern
@RobertKern,您能详细说明一下吗?我不太明白您试图解释什么。但是,当然使用int-seed是使这些函数确定性的有效方法。也许您正在谈论分布式种子的问题,但即使是这样,我也无法理解它来自何处,而且还有比这更好的方法。 - sascha
不,这只是OP在解决确定性问题后遇到的下一个问题(可能是通过找到另一个省略了random_state=参数的管道部分来解决)。这就是为什么我把它放在评论中的原因。我要明确声明,我提到的方法是使用指定种子的OP环境/任务和PRNG的唯一正确方法。 - Robert Kern
如果您需要更多的帮助,可以发布更多的代码。 - serv-inc
显示剩余2条评论
1个回答

4
from sklearn import datasets, linear_model
iris = datasets.load_iris()
(X, y) = iris.data, iris.target
RANDOM_SEED = 5
lr = linear_model.LogisticRegression(random_state=RANDOM_SEED)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=RANDOM_SEED)
lr.fit(X_train, y_train)
lr.score(X_test, y_test)

现在已经多次生成了 0.93333333333333335。您所做的方法似乎可以。另一种方法是使用 set np.random.seed() 或使用 Sacred 进行文档化的随机性。使用 random_state文档中描述的

如果您的代码依赖于随机数生成器,则不应使用诸如 numpy.random.randomnumpy.random.normal 等函数。这种方法可能会导致单元测试中的可重复性问题。相反,应该使用一个 numpy.random.RandomState 对象,该对象是从传递给类或函数的 random_state 参数构建的。


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