You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SMOTE过采样、GridSearchCV与10折交叉验证组合使用的正确方法

二分类任务SMOTE+网格搜索+交叉验证流程实现解答

1 全量数据集跑GridSearch的正确性说明

你当前的代码已经避免了SMOTE过采样的数据泄露问题:把SMOTE放在Pipeline里执行,GridSearch每折交叉验证时,只会对当前折叠的训练子集做过采样,不会用到测试子集的信息,这部分逻辑是正确的。
是否需要提前划分70/30留出集,分两种场景判断:

  • 如果你的目标仅为调参得到最优超参数,最终要在全量数据集上训练最终模型部署,不需要额外划分留出集,直接用全量数据跑GridSearch即可。
  • 如果你的目标是得到无偏的模型泛化性能评估,必须提前做分层留出集划分,GridSearch仅在训练子集上执行,最终用完全未参与调参的测试子集评估性能。如果直接用GridSearch内部交叉验证的结果作为最终性能,会因为调参过程已经用到了所有折叠的测试信息,导致性能评估偏高,出现数据泄露。

2 获取accuracy、f1等评估指标的实现方法

可以直接通过GridSearch的scoring参数配置多指标评估,实现方式如下:

配置多指标网格搜索

给GridSearch传入scoring参数指定需要统计的指标列表,多指标场景下需要通过refit参数指定以哪个指标为标准选择最优超参数。

指标获取方式

  • 10折交叉验证的指标可以从grid_search.cv_results_属性中获取,对应字段为mean_test_accuracy、mean_test_f1等,找到最优参数对应的索引即可拿到对应平均指标。
  • 留出测试集的指标可以通过sklearn.metrics下的对应函数直接计算。

完整代码示例

from sklearn.model_selection import train_test_split, GridSearchCV, StratifiedKFold
from sklearn.pipeline import Pipeline
from sklearn.neighbors import KNeighborsClassifier
from imblearn.over_sampling import SMOTE
from sklearn.metrics import accuracy_score, f1_score

# 如需无偏泛化性能评估,先划分分层留出集
X_train, X_test, y_train, y_test = train_test_split(
    X_all, y_all, test_size=0.3, stratify=y_all, random_state=42
)

# 构建包含SMOTE的Pipeline
pipe = Pipeline([
    ('resample', SMOTE(sampling_strategy=1)),
    ('model', KNeighborsClassifier())
])

# 10折分层交叉验证
cv = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)

# 超参数搜索空间
params = [{
    'model__n_neighbors': [1,3,5,15,25,45],
    'model__weights': ['uniform','distance'],
    'model__leaf_size': [3,5,7,9,15,25]
}]

# 配置多指标网格搜索
grid_search = GridSearchCV(
    estimator=pipe, 
    param_grid=params, 
    cv=cv, 
    refit='f1', # 以F1为标准选择最优参数
    scoring=['accuracy', 'f1'], # 指定要统计的评估指标
    n_jobs=-1 # 多进程加速搜索
)

# 仅用训练集执行网格搜索(无需无偏评估可替换为X_all、y_all)
grid_search.fit(X_train, y_train)

# 输出最优参数
print("最优超参数:", grid_search.best_params_)

# 获取10折交叉验证的平均指标
best_idx = grid_search.best_index_
print("10折交叉验证平均准确率:", round(grid_search.cv_results_['mean_test_accuracy'][best_idx], 4))
print("10折交叉验证平均F1值:", round(grid_search.cv_results_['mean_test_f1'][best_idx], 4))

# (划分留出集的场景)在独立测试集上评估泛化性能
y_pred = grid_search.predict(X_test)
print("独立测试集准确率:", round(accuracy_score(y_test, y_pred), 4))
print("独立测试集F1值:", round(f1_score(y_test, y_pred), 4))

内容的提问来源于stack exchange,提问作者Vasu Mistry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 19:48:02