机器学习超参数怎么优化?用 GridSearchCV 搜索并保留测试集

用 GridSearchCV 在训练集内部搜索 SVC 参数,逐折拟合标准化,并把独立测试集留到最终一次检查。

机器学习调参的关键是先固定数据边界。用 GridSearchCV 在训练集内部做交叉验证搜索,找到参数后重拟合,再只用保留的测试集做最终检查。这样才能区分“这组参数适合搜索数据”和“它对未参与搜索的样本有效”。

搜索什么,为什么放进 Pipeline

本文用 scikit-learn 自带鸢尾花数据和 SVC 教学:C 控制正则化取舍,gamma 影响 RBF 核的作用范围。示例只搜索这两个参数,不保证找到所有任务的最好方案。数据为内置教学数据,不能推断真实生产性能。

机器学习超参数怎么优化?用 GridSearchCV 搜索并保留测试集

GridSearchCV 官方接口按给定参数网格搜索,用 scoring 比较候选;refit=True 会在传入的完整训练集上拟合最优候选。这里的完整训练集仍不包括留出的测试集。

官方常见错误指南建议先分割,再拟合预处理。把 StandardScaler 放进 Pipeline,可以让每一折只用该折训练部分学习均值与方差。先对全部样本标准化再搜索,会让验证折或测试集的信息提前流入。

准备独立 Python 环境

本文使用 Python 3.13。下面命令适用于 Windows PowerShell,在新建练习目录运行;其他系统用对应的 Python 路径。先用 python –version 确认版本,再创建环境。

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install "scikit-learn==1.9.1" "numpy==2.5.3" "pandas==3.0.6"

以下代码和数据只用于教学。本站于 2026-10-01 在 Windows、Python 3.13.14、scikit-learn 1.9.1、NumPy 2.5.3、pandas 3.0.6 环境运行了本文脚本;这只验证示例能执行和断言通过,不代表真实业务效果。

完整代码:9 个组合与独立测试

保存为 grid_demo.py,运行 .\.venv\Scripts\python.exe grid_demo.py。3 个 C 值乘 3 个 gamma 值,共 9 个组合;每个组合进行 3 折验证。30 条独立测试样本不参与缩放器拟合或 GridSearchCV 搜索。

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV
from sklearn.metrics import f1_score

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42)
pipeline = Pipeline([("scale", StandardScaler()), ("svc", SVC())])
grid = {"svc__C": [0.1, 1, 10], "svc__gamma": [0.01, 0.1, 1]}
cv = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)
search = GridSearchCV(pipeline, grid, cv=cv, scoring="f1_macro",
                      n_jobs=1, refit=True, error_score="raise",
                      return_train_score=True)
search.fit(X_train, y_train)
table = pd.DataFrame(search.cv_results_)
cols = ["param_svc__C", "param_svc__gamma", "mean_train_score",
        "mean_test_score", "std_test_score", "rank_test_score"]
print(table[cols].sort_values("rank_test_score").to_string(index=False))
print("best_params", search.best_params_)
print("best_cv_macro_f1", round(search.best_score_, 4))
pred = search.predict(X_test)
print("heldout_test_macro_f1", round(f1_score(y_test, pred, average="macro"), 4))
table[cols].to_csv("search_results.csv", index=False, encoding="utf-8-sig")
assert len(table) == 9 and len(X_test) == 30
assert len(pred) == len(y_test)

把交叉验证成绩和测试成绩分开读

 param_svc__C  param_svc__gamma  mean_train_score  mean_test_score  std_test_score  rank_test_score
          1.0              0.10          0.975054         0.974957        0.020193                1
         10.0              0.10          0.975068         0.966726        0.011446                2
         10.0              0.01          0.979261         0.966726        0.011446                3
          1.0              1.00          0.979171         0.958483        0.023100                4
         10.0              1.00          0.995883         0.958483        0.023100                4
          0.1              1.00          0.946287         0.909851        0.056266                6
          1.0              0.01          0.895041         0.891145        0.045921                7
          0.1              0.10          0.873195         0.874344        0.034063                8
          0.1              0.01          0.515268         0.515961        0.034744                9
best_params {'svc__C': 1, 'svc__gamma': 0.1}
best_cv_macro_f1 0.975
heldout_test_macro_f1 0.9666

这是上述内置教学数据的一次本地运行输出。best_cv_macro_f1 是被选参数在训练集内部三折上的平均成绩;heldout_test_macro_f1 是保留测试集上的成绩,二者不是同一口径。样本小,分数可能因分割方式改变,不能把某次高分当可靠商用表现。

search_results.csv 应有 9 行,每行对应一个 C 与 gamma 组合。检查最优参数是否与 rank_test_score 排名一致,并看 std_test_score 的折间波动。若多个组合分数相同或很接近,应结合复杂度和稳定性选择,不必声称第一名具有明显优势。

自己的任务怎样替换

换成表格后,先确定类别定义、独立样本单位和评分。重复客户或同一设备跨记录时,要用分组划分与相应交叉验证;时间任务按时间边界切分。类别不均衡时关注宏平均 F1 或业务需要的精确率、召回率,并检查每折是否含有足够正类。

网格变大前先算成本:参数组合数乘折数是交叉验证拟合次数,refit=True 通常再拟合一次。此例 9×3=27 次交叉验证拟合,再进行一次最终训练。电脑内存受限时先用 n_jobs=1;error_score=”raise” 让非法参数或拟合错误立即显现。

失败与限制

不能看测试分数后反复扩大网格再挑参数,那会让测试集变成调参集。若结果不理想,回到训练集内部分析,并另备最终测试数据;不要继续用同一测试集证明改进。

出现 svc__C 等参数名错误时先核对 Pipeline 步骤名;少数类别样本少于折数时减少折数或补充代表数据;训练分数很高但验证分数低时优先排查过拟合、泄漏和样本分布,而不是无限增大搜索范围。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30162.html

赞 (0)
AI小管家的头像AI小管家
模型为什么这样预测?用置换重要性解释特征作用
上一篇 1天前
GitHub Copilot 代码建议怎么用?在 VS Code 接受、拒绝并验证补全
下一篇 1天前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部