使用StratifiedShuffleSplit函数(scikit-learn)时random_state为None的不同结果

2 投票
2 回答
3457 浏览
提问于 2025-04-18 01:11

我正在进行交叉验证,以便更好地分类。最开始,我使用的是scikit-learn中的StratifiedKfold函数。后来,我想进行更多的迭代,就换成了StratifiedShuffleSplit这个函数。使用这个新函数后,我得到的结果发生了变化。最后,我发现如果我指定一个random_state的值,我又能得到和使用StratifiedKfold时类似的结果。

总结一下,如果我指定random_state,虽然不同的值会得到稍微不同的结果,但这些结果和我用StratifiedKfold得到的结果相似(无论是进行一次迭代,还是自己计算洗牌,像这里提到的那样)。但是,如果random_state是None或者没有指定,得到的结果就完全不同了。

我检查了一下,当random_state是None时,训练和测试的索引是不同的,并且是分层的,这也是我预期的结果。

我对随机数生成器没有经验,但这对我来说没有任何意义。

看代码的时候,我意识到当random_state是None时,会调用check_random_state这个函数。这个函数如果seed是None,就会返回np.random使用的RandomState单例(链接)。

我给你写了有问题的代码片段。如果我把注释掉的那一行换成下面的那一行,我得到的结果就会不同。

import numpy as np
import sklearn as skl

(...)
#skCVs=skl.cross_validation.StratifiedShuffleSplit(classes,n_iter=iterations*kfoldCV,test_size = 1/float(kfoldCV),random_state=5)
skCVs=skl.cross_validation.StratifiedShuffleSplit(classes,n_iter=iterations*kfoldCV,test_size = 1/float(kfoldCV))

for train,test in skCVs:

   (classification, ...)

我使用的是sklearn的0.14版本。

你有没有什么解释或者线索,能帮助我理解发生了什么?

2 个回答

1

我也不是随机生成器方面的专家,但根据我的理解,如果你没有定义随机状态(random_state),那么会调用不同类型的随机状态。这里有个解释:

“如果种子(seed)是None,那么RandomState会尝试从/dev/urandom(或者Windows的类似功能)读取数据,如果没有的话,就会从时钟获取种子。”

“如果大小(size)是一个整数,那么会返回一个填满生成值的一维数组。”

你可以在“check_random_state”中看到调用的两种不同随机生成器的代码,链接在这里。

[1] http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.RandomState.html

[2] https://github.com/scikit-learn/scikit-learn/blob/0.14.X/sklearn/utils/validation.py

这对你有帮助吗?

5

(分层)ShuffleSplit会在分割数据之前先随机打乱数据。这个随机打乱的过程是由random_state这个参数来控制的。如果这个参数的默认值是None,那么每次调用时数据的打乱顺序都会不同。如果你想要每次打乱的顺序都一样,可以传入一个整数作为种子值。

撰写回答