求助:GridSearchCV拆分数据集异常,需保持指定训练测试集大小
问题根源与解决方案
兄弟,你这问题的核心原因其实挺明显的——你把测试集传给了GridSearchCV的fit()方法,而GridSearchCV默认会对输入的数据执行交叉验证拆分,这直接打乱了你原本用train_test_split划分的训练/测试集结构。
具体问题拆解
- 你原本的计划是用
train_test_split得到50969条训练集、16990条测试集,但你却把X_test和y_test传给了grid_searcher.fit()。 - GridSearchCV默认会使用5折交叉验证(可通过
cv参数修改),它会把你传入的16990条测试集拆分成5份,轮流用其中4份做训练、1份做验证。这就是为什么你的T_scorer会打印出多个不同长度的y_pred和混淆矩阵——这些都是交叉验证中不同折的验证结果,加起来正好是16990条。 - 更关键的是:测试集的作用是最终评估模型的泛化能力,绝对不能用来做调参(包括GridSearch的交叉验证),否则模型会“记住”测试集的特征,导致最终评估结果失真。
修正后的代码
把GridSearchCV的训练数据换成X_train和y_train,之后用找到的最佳模型去预测真正的测试集X_test,这样就能保持你想要的训练/测试集规模了:
_scorer = make_scorer(T_scorer) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) clf = RandomForestClassifier() grid_searcher = GridSearchCV(clf, parameter_grid, verbose=20, scoring=_scorer) # 这里改成用训练集做交叉验证调参 grid_searcher.fit(X_train, y_train) clf_best = grid_searcher.best_estimator_ print('Best params = ', clf_best.get_params()) # 用最佳模型预测真正的测试集,得到的y_pred长度就是16990 y_pred = clf_best.predict(X_test) # 这里可以打印测试集的混淆矩阵,总和就是16990 print(confusion_matrix(y_test, y_pred))
额外说明
如果你想自定义GridSearchCV的交叉验证方式(比如指定折数、分层采样等),可以通过cv参数设置,比如GridSearchCV(..., cv=10)表示用10折交叉验证,cv=StratifiedKFold(n_splits=5)表示用分层5折(适合分类任务)。
内容的提问来源于stack exchange,提问作者user287629
相关产品推荐
相关产品推荐

