有没有选项可以防止交叉验证(和GridSearchCV)随机化数据集的行?

0 投票
2 回答
908 浏览
提问于 2025-04-17 20:38

有人知道有没有办法让scikit-learn里的gridsearchCV函数在处理我的数据集时不随机打乱记录吗?

我有一组行,它们对应同一种现象,我希望在现象ID上进行随机化,而不是对整行数据进行随机化。我已经用SQL在现象上进行了随机化,现在我只希望gridsearchCV在将数据集分成训练集和测试集之前,不再重新随机化。

这是我的数据集的一个例子:

id time feature1 feature2 feature3 feature4 
A 1 b c s a
A 2 b a s t
A 3 q w o j
B 1 l o j f
B 2 9 k l h
C 1 o k h u
C 2 o k h i
C 3 p j g d
D 1 l l d s
D 2 ...
D 3 ...
D 4 ...
D 5 ...

我不希望在训练集和测试集之间对ID进行分割。

有没有什么选项可以帮助我呢?

谢谢你的帮助。

2 个回答

0

一次性配置多个步骤是比较困难的(我也不确定在这里是否可行)——如果你想以不同的方式进行操作,可能专门的方法gridSearchCV不太适合你。所以我建议你把这些步骤分开,这样做其实并不复杂。

  1. 根据你的需求,把数据分成适合交叉验证的部分,可以使用sklearn.cross_validation中的某些方法。
  2. 进行网格搜索,可能需要用到sklearn.gridsearch中的ParameterGrid。
0

GridSearchCV 有一个叫 cv 的参数,它需要一个交叉验证对象;这个对象必须是一个可以迭代的东西,能够提供一对索引数组 train_index, test_index。标准的 KFold 的工作方式如下:

>>> from sklearn.cross_validation import KFold
>>> threefold = KFold(n=10, n_folds=3)
>>> for train, test in threefold:
...    print("train: %r" % train)
...    print("test:  %r" % test)
...     
train: array([4, 5, 6, 7, 8, 9])
test:  array([0, 1, 2, 3])
train: array([0, 1, 2, 3, 7, 8, 9])
test:  array([4, 5, 6])
train: array([0, 1, 2, 3, 4, 5, 6])
test:  array([7, 8, 9])

所以你需要以某种方式模仿这个,创建一个类

class CustomCV(object):
    def __init__(self, ids, n_folds):
        """Pass an array of phenomenon ids"""
        self.ids = ids
        self.n_folds = n_folds

    def __iter__(self):
        for i in range(self.n_folds):
            train = make_a_boolean_mask_for_the_training_set()
            test = np.logical_not(train)
            yield np.where(train)[0], np.where(test)[0]

在这个类里,你需要自己填充 make_a_boolean_mask_for_the_training_set 的逻辑。如果你需要帮助,我在网上有一个针对序列数据的变体

确保还要把 GridSearchCV 的参数 iid 设置为 False,否则你会得到偏差的结果。

撰写回答