使用StratifiedShuffleSplit函数(scikit-learn)时random_state为None的不同结果
我正在进行交叉验证,以便更好地分类。最开始,我使用的是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 个回答
我也不是随机生成器方面的专家,但根据我的理解,如果你没有定义随机状态(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
这对你有帮助吗?
(分层)ShuffleSplit会在分割数据之前先随机打乱数据。这个随机打乱的过程是由random_state
这个参数来控制的。如果这个参数的默认值是None
,那么每次调用时数据的打乱顺序都会不同。如果你想要每次打乱的顺序都一样,可以传入一个整数作为种子值。