为啥用 shuffle 调用 KFold 生成器会给出相同的索引?

Posted

技术标签:

【中文标题】为啥用 shuffle 调用 KFold 生成器会给出相同的索引?【英文标题】:Why does calling the KFold generator with shuffle give the same indices?为什么用 shuffle 调用 KFold 生成器会给出相同的索引? 【发布时间】:2016-04-28 16:26:19 【问题描述】:

使用 sklearn,当您创建一个新的 KFold 对象并且 shuffle 为 true 时,它​​会生成一个不同的、新随机化的折叠索引。但是,即使 shuffle 为真,来自给定 KFold 对象的每个生成器都会为每个折叠提供相同的索引。为什么会这样?

例子:

from sklearn.cross_validation import KFold
X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
y = np.array([1, 2, 3, 4])
kf = KFold(4, n_folds=2, shuffle = True)
​
for fold in kf:
    print fold
​
print '---second round----'
​
for fold in kf:
    print fold

输出:

(array([2, 3]), array([0, 1]))
(array([0, 1]), array([2, 3]))
---second round----#same indices for the folds
(array([2, 3]), array([0, 1]))
(array([0, 1]), array([2, 3]))

这个问题的动机是对此answer 的评论。我决定将其拆分为一个新问题,以防止该答案变得过长。

【问题讨论】:

【参考方案1】:

具有相同 KFold 对象的新迭代不会重新调整索引,这只会在对象实例化期间发生。 KFold() 永远不会看到数据,但知道样本的数量,因此它使用它来打乱索引。来自 KFold 实例化期间的代码:

if shuffle:
    rng = check_random_state(self.random_state)
    rng.shuffle(self.idxs)

每次调用生成器以遍历每个折叠的索引时,它将使用相同的打乱索引并以相同的方式划分它们。

查看code 的KFold 基类_PartitionIterator(with_metaclass(ABCMeta)),其中定义了__iter__。基类中的 __iter__ 方法调用 KFold 中的 _iter_test_indices 来划分并生成每个折叠的训练和测试索引。

【讨论】:

以上是关于为啥用 shuffle 调用 KFold 生成器会给出相同的索引?的主要内容,如果未能解决你的问题,请参考以下文章

使用 sklearn 的 KFold 分离 pandas 数据框

k折交叉验证KFold()函数的使用

sklearn中的Kfold交叉验证每次都会给出不同的折叠

使用KFold进行训练集和验证集的拆分,使用准确率和召回率来挑选合适的阈值(threshold) 1.KFold(进行交叉验证) 2.np.logical_and(两bool数组都是正即为正)

使用KFold进行训练集和验证集的拆分,使用准确率和召回率来挑选合适的阈值(threshold) 1.KFold(进行交叉验证) 2.np.logical_and(两bool数组都是正即为正)

用exescript生成的exe文件为啥老是被360杀毒报木马?