避免过拟合的秘诀:莫烦Python tutorials K折交叉验证与网格搜索参数调优实战
【免费下载链接】tutorials机器学习相关教程项目地址: https://gitcode.com/gh_mirrors/tut/tutorials
在机器学习项目中,模型"训练集上考99分、真实场景却不及格"的现象就是过拟合。莫烦Python tutorials 的 sklearn 教程提供了 K折交叉验证与网格搜索(Grid Search)的完整实战代码,帮你用最小代价找到稳定、不过拟合的最优模型,是新手参数调优的最佳入门路径。
为什么单次"训练-测试"划分不够可靠?
很多新手的第一反应是把数据切成训练集和测试集,然后盯着测试集准确率调参数。问题在于:单次划分的得分带有随机性——换个随机种子,分数可能上下浮动好几个百分点,你根本无法判断模型是真的变好了,还是只是"运气好"。
教程中 sk4_learning_pattern.py 演示了最基础的train_test_split划分方式:
X_train, X_test, y_train, y_test = train_test_split( iris_X, iris_y, test_size=0.3)它能跑通,但只能告诉你"这一次"的结果。要得到可复现、可比较的评估,就需要下一节的 K 折交叉验证。
快速上手:cross_val_score 一键计算 K 折得分
K 折交叉验证(K-Fold Cross Validation)的思想很直观:把数据分成 K 份,轮流用其中 1 份当验证集、其余 K-1 份训练,最终取 K 次得分的平均值。K 取 5 或 10 都是常见做法。
莫烦教程用鸢尾花(Iris)数据集演示了这一过程,核心就一行(见 full_code.py):
scores = cross_val_score(knn, X, y, cv=5, scoring='accuracy')新手要记住的 3 个要点:
cv=5:表示 5 折,数据被分成 5 份轮流验证,得分更稳健;scoring='accuracy':分类任务用准确率,回归任务可换成'mean_squared_error';- 拿到
scores是 K 个值,用它们的均值和方差来判断模型是否稳定,而不是只看某一个。
同目录下的 for_you_to_practice.py 是留白练习版,适合你自己动手补全这三段逻辑,效果比直接看答案好得多。
💡 小提示:仓库代码沿用了早期 scikit-learn 的
cross_validation模块名,新版 sklearn 中已迁移为model_selection,函数用法完全一致,替换导入路径即可。
用交叉验证选参数:画出 K 值与准确率曲线
验证机制建好后,就能解决参数调优的第一大问题:KNN 的邻居数 k 该取多少?
教程的做法非常巧妙——把 k 从 1 遍历到 30,每个 k 都跑一次 10 折交叉验证,把平均准确率画成折线图(见 full_code.py):
for k in k_range: knn = KNeighborsClassifier(n_neighbors=k) scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy') k_scores.append(scores.mean()) plt.plot(k_range, k_scores)读图有两个关键经验:
- k 太小 → 过拟合:曲线左端准确率虚高,模型对训练数据过度敏感;
- k 太大 → 欠拟合:曲线右端趋于平缓甚至下滑,模型失去区分能力。
取曲线"高位平台区"的 k 值,就是在偏差与方差之间取得平衡——这正是避免过拟合的核心操作。
网格搜索(GridSearchCV):参数调优的终极武器
当模型有多个参数需要同时调整时,手写循环就不够用了。网格搜索(Grid Search)会自动枚举你给定的所有参数组合,内部用交叉验证逐一评估,最后直接输出最优参数。以 SVM 为例,现代 sklearn 的写法是:
from sklearn.model_selection import GridSearchCV param_grid = {'C': [0.1, 1, 10], 'gamma': [0.01, 0.1, 1]} grid = GridSearchCV(SVC(), param_grid, cv=5, scoring='accuracy') grid.fit(X_train, y_train) print(grid.best_params_, grid.best_score_)它和手动交叉验证是同一套思想的自动化:交叉验证是"考官",网格搜索是"批量考试",best_params_就是最终录取名单。参数网格不宜太密,否则计算量会爆炸。
调参前别忘了先做归一化,否则量纲差异大的特征会拖垮 SVM 等距离敏感模型。教程 sk7_normalization.py 展示了preprocessing.scale的标准用法:
X = preprocessing.scale(X) # normalization step clf = SVC() clf.fit(X_train, y_train)学习曲线与验证曲线:判断过拟合的可视化手段
调完参数还要回答一个问题:我的模型到底是过拟合、欠拟合,还是刚刚好?sklearn 提供了两条"诊断曲线",教程用 digits 手写数字数据集做了完整演示。
1. 学习曲线(learning_curve)——诊断"数据够不够"
sk9_cross_validation2.py 改变训练集比例(10% → 100%),同时记录训练集与交叉验证集的得分:
- 两条曲线都高且接近 → 模型健康;
- 训练得分高、验证得分低且差距大 →过拟合,需要更多数据或更强正则化;
- 两条曲线都低且接近 → 欠拟合,需要更复杂的模型。
2. 验证曲线(validation_curve)——诊断"某个参数对不对"
sk10_cross_validation3.py 固定模型、只扫描 SVM 的gamma参数。gamma太小曲线整体低迷(欠拟合),gamma太大训练曲线飙高而验证曲线塌陷——那条"塌陷的绿线"就是过拟合最直观的证据。
📌 一句话总结:学习曲线回答"要不要更多数据",验证曲线回答"这个参数该往哪调",配合网格搜索就能完成闭环调优。
学习路径与代码索引
按以下顺序跟着仓库代码走一遍,K 折交叉验证与网格搜索调参就能完全掌握:
| 步骤 | 文件 | 学什么 |
|---|---|---|
| 1 | sk4_learning_pattern.py | 单数据集划分训练的基线写法 |
| 2 | sk7_normalization.py | 数据归一化,调参前的必修课 |
| 3 | sk8_cross_validation/full_code.py | cross_val_score + KNN 参数曲线 |
| 4 | sk9_cross_validation2.py | learning_curve 学习曲线 |
| 5 | sk10_cross_validation3.py | validation_curve 参数诊断 |
| 6 | sk11_save.py | 训练好的模型持久化保存 |
避坑清单:
- 交叉验证的 fold 划分要在划分后再做,且每折内部独立归一化,否则会发生数据泄漏,得分虚高;
- 调参只用训练集,测试集只在最终验收时看一次;
- 交叉验证分数是均值+方差一起看:
0.92 ± 0.03远好于孤零零的0.92。
掌握 K 折交叉验证 + 网格搜索这套组合拳,你的模型评估将从"碰运气"升级为"有依据",这正是机器学习工程化最重要的第一步。
【免费下载链接】tutorials机器学习相关教程项目地址: https://gitcode.com/gh_mirrors/tut/tutorials
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考