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

时间:2016-01-22 06:36:45

标签: python scikit-learn cross-validation

使用sklearn,当你创建一个新的KFold对象并且shuffle为真时,它会产生一个不同的,新随机化的折叠指数。但是,即使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 个答案:

答案 0 :(得分:3)

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

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

每次调用生成器迭代每个折叠的索引时,它将使用相同的混洗索引并以相同的方式划分它们。

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