在 GridSearchCV 中对测试集进行预处理的问题

Posted

技术标签:

【中文标题】在 GridSearchCV 中对测试集进行预处理的问题【英文标题】:Problem of doing preprocessing for testing set in GridSearchCV 【发布时间】:2021-12-28 01:25:08 【问题描述】:

我使用 20% 的数据集作为我的测试集,并使用 GridSearchCV 实现 K 折交叉验证来调整超参数。

通过使用管道,我们可以将列转换器和机器学习算法一起放入 GridSearchCV。如果我为 GridSearchCV 设置 5 折交叉验证,该函数将使用 5 个不同的训练和验证集来训练和验证超参数的每个组合。据我所知,GridSearchCV 使用 5 折分数的平均值来选择最佳模型。

那么我的问题是,它如何转换测试集?

我对此很困惑,因为为了避免数据泄漏,我们应该只使用训练集来拟合转换器,但是在这种情况下,我们有 5 个不同的训练集,我不知道 GridSearchCV 函数是哪一个用于拟合和转换验证和测试集。

我的代码如下

X_other, X_test, y_other, y_test = train_test_split(X, y, test_size = 0.2, random_state = i)
kf = KFold(n_splits = 4, shuffle = True, random_state = i)
pipe = Pipeline(steps = [("preprocessor", preprocessor),("model", ML_algo)])

grid = GridSearchCV(estimator = pipe, param_grid=param_grid,
                    scoring = make_scorer(mean_squared_error, greater_is_better=False, 
                    squared=False),cv=kf, return_train_score = True, n_jobs=-1, verbose=False)

grid.fit(X_other, y_other)
test_score = mean_squared_error(y_test, grid.predict(X_test), squared=False)

【问题讨论】:

【参考方案1】:

简短的回答:没有数据泄漏,测试集不用于(也不应该用于)在您的代码中训练模型。

长答案:k fold cross-validation 将你的 X_other& y_other(training set) 随机分成 k 个 split,对于交叉验证的每次迭代,k-1 fold 数据用于训练然后使用您在scoring= 中指定的度量标准对模型进行评估,剩下的 1 折。 (详情参考下图来自sklearn:https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation)

GridSearchCV()找到最佳超参数集后,所有训练集数据都用于使用找到的超参数训练最终模型,然后,X_test,y_test(测试集)可以进行转换通过这个模型。注意,在这个过程中,X_test,y_test是没有被使用的,除了在最终的预测中,不应该使用。

【讨论】:

以上是关于在 GridSearchCV 中对测试集进行预处理的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 GridSearchCV 中显式指定测试/训练集

GridsearchCV 上的预处理

如何在 Weka 中对训练和测试数据集进行分类

如何在 python 的朴素贝叶斯分类器中对用户输入测试集进行分类?

在 gridsearchcv sklearn 中进行训练和验证集

使用单独的预定义验证集和 sklearn GridSearchCV