- 教程
- 机器学习
- 人工智能
【免费下载链接】ML-For-Beginners
12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all
本指南以 ML-For-Beginners 仓库中分类模块第 3 课(Cuisine classifiers 2)配套的Parameter Play(参数游戏)作业为骨架展开,面向希望系统掌握 scikit-learn 分类器调参思路的读者。你将基于清洗后的菜品数据集,在 Linear SVC、KNN、SVC、Random Forest 与 AdaBoost 五个分类器上逐一实验,理解C、kernel、n_neighbors、n_estimators、learning_rate等核心参数如何影响模型质量,并最终产出一份含完整解释的 Jupyter Notebook。
一、作业任务解读:什么是 Parameter Play
任务目标
作业原文(见 translations/bg/4-Classification/3-Classifiers-2/assignment.md 与英文版 4-Classification/3-Classifiers-2/assignment.md)给出如下要求:
在使用这些分类器时,有大量参数是默认设置的。VS Code 中的 Intellisense 可以帮助你深入查看这些参数。请采用本课中介绍的某一种 ML 分类技术,通过调整各种参数值重新训练模型,并构建一个 notebook,解释为什么某些改动会提升模型质量,而另一些改动会使其变差。请详细作答。
拆解任务可以归纳为四个可执行步骤:
- 选定分类器:从本课涉及的 Linear SVC、K-Neighbors、SVC、Random Forest、AdaBoost 中任选一种(也可全部尝试)。
- 挖掘默认参数:借助 VS Code 的 Intellisense(悬停查看函数签名与文档)或 scikit-learn 文档,把每个可调参数找出来。
- 控制变量地重训:每次只改动一个参数,记录测试集上的准确率、precision、recall、f1 等指标变化。
- 解释因果:在 notebook 的文本框中说明"为什么这个参数变大/变小会提升或恶化模型质量",而非只贴代码。
评分标准(Rubric)
作业自带的评分表是验收的唯一标尺,写作 notebook 时应逐条对齐:
| 评分维度 | 优秀(Exemplary) | 合格(Adequate) | 需改进(Needs Improvement) |
|---|---|---|---|
| 交付物 | 提交的 notebook 中分类器完整构建,参数经过调整,且每次改动都在文本框中有详细解释 | notebook 部分完成或解释不充分 | notebook 存在 bug 或明显错误 |
换言之,"改参数 + 跑结果"只是及格线,完整可复现的分类器代码与逐项参数解释才是拿优秀的关键。
二、实验基础:数据集与训练/测试划分
Parameter Play 不是凭空实验,它建立在上一课清洗好的数据之上。课程 README(4-Classification/3-Classifiers-2/README.md)明确要求:
- 数据文件:
cleaned_cuisines.csv,位于本模块根目录的data文件夹中,即 4-Classification/data/cleaned_cuisines.csv。 - 数据形态:每行是一条菜谱样本,
cuisine列是标签(chinese / indian / japanese / korean / thai 五类),其余 380 列是配料是否存在的一热编码特征(0/1)。
课程官方 notebook(4-Classification/3-Classifiers-2/notebook.ipynb)展示了数据加载与特征/标签切分的完整过程:
import pandas as pd cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv") # 4-Classification/data/cleaned_cuisines.csv cuisines_label_df = cuisines_df['cuisine'] # 标签 y cuisines_features_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1) # 特征 X,共 380 列 X_train, X_test, y_train, y_test = train_test_split( cuisines_features_df, cuisines_label_df, test_size=0.3 )随后导入实验所需的全部库(解答 notebook 4-Classification/3-Classifiers-2/solution/notebook.ipynb 与 README 中一致):
from sklearn.neighbors import KNeighborsClassifier from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier from sklearn.model_selection import train_test_split, cross_val_score from sklearn.metrics import accuracy_score, precision_score, confusion_matrix, classification_report, precision_recall_curve import numpy as np两个关键细节值得在实验笔记中写明:
test_size=0.3:30% 数据留作测试集;train_test_split默认随机划分,不做 random_state 固定会导致每次实验结果不同——这也是下面基线结果存在两套数值的原因。- 课程在打印准确率时使用了 "Accuracy (train)" 字样,但从代码
y_pred = classifier.predict(X_test)与accuracy_score(y_test, y_pred)可以看出,该指标实际计算于留出的测试集上,标签命名存在误导,解读结果时请以代码行为为准。
三、分类器选择路径:从 Scikit-learn 的 ML Map 出发
为什么要在这五个分类器上做 Parameter Play?课程给出了一个"决策地图"式的选择路径,这也是参数实验的前提——先选对模型家族,再谈调参。
沿着地图的路径走一遍,即可定位到本课的候选模型:
- 样本量 > 50;
- 目标是预测一个类别(分类任务);
- 数据有标签(监督学习);
- 样本数 < 100K;
- ✨ 可以优先尝试Linear SVC;
- 如果效果不佳,由于特征是数值型的:
- 可尝试KNeighbors 分类器;
- 若仍不佳,再尝试SVC与Ensemble(集成)分类器。
课程正是沿着这条路径依次实验,最终得到五个模型的横向对比。这意味着 Parameter Play 作业中的调参不是盲目搜索,而是在已选定的合理模型族内做精细化改进。
四、五个候选分类器及其关键参数剖析
本课代码将所有分类器放进一个字典统一训练(见 4-Classification/3-Classifiers-2/README.md):
C = 10 classifiers = { 'Linear SVC': SVC(kernel='linear', C=C, probability=True, random_state=0), 'KNN classifier': KNeighborsClassifier(C), 'SVC': SVC(), 'RFST': RandomForestClassifier(n_estimators=100), 'ADA': AdaBoostClassifier(n_estimators=100) } for name, classifier in classifiers.items(): classifier.fit(X_train, np.ravel(y_train)) y_pred = classifier.predict(X_test) print("Accuracy for %s: %0.1f%%" % (name, accuracy_score(y_test, y_pred) * 100)) print(classification_report(y_test, y_pred))下面逐一剖析每个分类器的核心参数——这些正是 Parameter Play 的"操作对象"。
4.1 Linear SVC:kernel 与 C(正则化)
Support-Vector Classifier(SVC)属于支持向量机(SVM)家族,其思想是将训练样本映射到特征空间,并找到一个能最大化两个类别之间间隔的决策边界。课程 README 明确指出:
kernel:决定如何划分标签的核函数,可取 linear、poly、rbf、sigmoid 等多种。本课设为'linear',即利用线性 SVC 的线性可分特性。C:正则化参数,调节参数的影响力。C 越大,对误分类的惩罚越强,边界越贴合训练数据(方差升高、过拟合风险加大);C 越小,模型越宽容、越平滑(偏差升高)。probability:默认False,设为True后可输出类别概率估计(代价是训练时间变长)。random_state:设为0使数据洗牌可复现,便于概率估计与结果对比。
下面的 SVM 示意图可以直观解释"为什么 C 和 kernel 会影响模型质量"——不同边界对离群点的容忍度不同,而 C 与核函数决定了边界允许的"违规量"与弯曲程度。
4.2 K-Neighbors:n_neighbors 是唯一"必调"参数
K-Neighbors 属于"邻居"类方法,可用于监督与无监督学习。它的机制是:为数据点确定一个预定义数量的邻近点,依据邻近点"投票"给出泛化标签。
课程代码KNeighborsClassifier(C)是一个值得记录的参数位次陷阱:KNeighborsClassifier构造函数的第一个位置参数是n_neighbors,因此这里传入的C = 10实际是把近邻数设为 10。Parameter Play 中建议显式写成KNeighborsClassifier(n_neighbors=10)以避免歧义。KNN 的核心参数包括:
n_neighbors(默认 5):近邻个数。k 过小 → 决策边界剧烈、高方差;k 过大 → 过度平滑、高偏差。weights(默认'uniform'):可改为'distance'让近邻按距离加权。p/metric:距离度量,默认欧氏距离(p=2)。
4.3 SVC:默认参数下的非线性内核
裸写SVC()时,scikit-learn 会启用非线性 RBF 核的默认配置(默认C=1.0、kernel='rbf'、probability=False)。相比线性 SVC,RBF 核通过"核技巧"在更高维空间构造非线性边界,这正是它在课程测试中准确率明显高于线性版本的原因(见下文基线对比)。调参时可关注:
C:正则化强度,同上。gamma(默认'scale'):RBF 核的影响半径,gamma 大 → 每个样本影响范围小、易过拟合;gamma 小 → 边界更平滑。degree:仅在 poly 核下生效的多项式次数。
4.4 集成分类器:Random Forest 与 AdaBoost
集成方法"组合多个基学习器的预测"来提升整体质量,课程选用随机森林与 AdaBoost 两个代表:
- Random Forest(RFST):平均法(bagging)的代表,构建一棵棵注入随机性的"决策树"组成的"森林"以避免过拟合。
n_estimators即树的数量,课程设为 100。可继续调整max_depth(树深,限制可防过拟合)、min_samples_split(分裂最小样本数)、max_features(每棵树的特征抽样数)等。 - AdaBoost(ADA):提升法(boosting)的代表。它先拟合一个分类器,再基于同一数据集拟合其副本,重点提高被错误分类样本的权重,迫使下一个分类器纠正前一个的错误。课程设为
n_estimators=100;learning_rate(默认 1.0)控制每一步对弱学习器权重的收缩程度,是 AdaBoost 调参的核心旋钮。
从源码结构看,R 语言版解答(4-Classification/3-Classifiers-2/solution/R/lesson_12.Rmd)给出了同族模型的另一套参数命名:SVM 中的
cost(对应 C)、KNN 中的neighbors(对应 n_neighbors)、随机森林中的mtry(对应 max_features 类的随机特征抽样)。做参数实验时,跨语言对照这些命名有助于理解参数本质。
五、基线结果:默认配置下的模型表现
课程 README 记录了五个分类器的基线结果(注意:因随机划分,每次运行数值略有浮动):
| 分类器 | 准确率 | 观察要点 |
|---|---|---|
| Linear SVC | 78.6% | 线性边界已能较好分离五类菜品 |
| KNN(n_neighbors=10) | 73.8% | 略低于 Linear SVC,korean 类 recall 仅 0.58 |
| SVC(RBF 默认) | 83.2% | 非线性边界带来明显提升 |
| Random Forest(100 棵树) | 84.5% | 本课基线最优,各类别 f1 均衡 |
| AdaBoost(100 个基学习器) | 72.4% | 准确率最低,chinese 类 recall 仅 0.49 |
解答 notebook 中因train_test_split未固定随机种子,得到另一组数值(Linear SVC 76.4%、KNN 70.7%、SVC 80.1%、RFST 82.8%、ADA 71.1%),但相对排名与结论一致:Random Forest ≈ SVC > Linear SVC > KNN ≈ AdaBoost。这本身就是一条值得写进 notebook 的观察:模型对比结论对随机划分具有一定稳健性,但精确数值会波动,因此固定random_state是参数实验的基本纪律。
六、参数调优实验设计:哪些改动提升、哪些恶化
6.1 方法学:单变量对照实验
Parameter Play 的核心方法是控制变量:只动一个参数,其余保持默认,记录指标,再解释机理。课程 README 的 Challenge 环节也提示:"每种技术都有大量可调参数,请研究各自默认参数,思考调整它们对模型质量意味着什么。"
推荐的实验流程:
- 以基线配置为对照;
- 选定一个参数,取递增/递减序列(如
C ∈ {0.1, 1, 10, 100}); - 逐档训练并在同一测试集上评估;
- 用交叉验证替代单次划分,避免偶然性(
cross_val_score已在导入清单中)。
6.2 各参数的影响机理速查
SVC 的 C(正则化)
- C 增大 → 误分类惩罚加重,边界贴合训练点,训练集表现变好但测试集可能变差(过拟合);
- C 减小 → 边界更平滑、对离群点更宽容,偏差上升但方差下降;
- 在菜品数据上,从
C=10出发尝试更小值往往更稳健。
SVC 的 kernel / gamma
- linear → rbf:从线性边界升级为非线性边界,通常带来显著准确率提升(本课 78.6% → 83.2% 即为佐证);
- gamma 过大 → 每个样本只影响极小邻域,容易过拟合;过小 → 边界过度平滑,欠拟合。
KNN 的 n_neighbors
- k 减小(如 3)→ 决策边界细碎,高方差,可能过拟合;
- k 增大(如 20/50)→ 边界平滑,高偏差,类别少而杂时准确率下降;
- 本课
k=10时 korean 类 recall 仅 0.58,说明近邻投票在该类上系统性误判——可结合weights='distance'观察改善。
Random Forest 的 n_estimators / max_depth
n_estimators增大 → 预测趋于稳定,收益边际递减(100 → 200 提升有限但训练变慢);max_depth过深 → 单棵树完全生长,过拟合风险上升;适当限制深度是正则化手段。
AdaBoost 的 n_estimators / learning_rate
learning_rate过小 → 每步修正幅度小,需要更多基学习器,欠拟合风险;learning_rate过大 → 权重更新剧烈,训练集易过拟合;- 本课基线 72.4% 偏低,chinese 类 recall 仅 0.49,可尝试降低 learning_rate 并同步加大 n_estimators。
6.3 用交叉验证让结论更可靠
课程导入了cross_val_score但主流程未使用,Parameter Play 中建议补上这一步:单次train_test_split的准确率方差较大,交叉验证的均值与标准差更能反映参数改动的真实收益。R 版解答(lesson_12.Rmd)中同样提到:实践中通常通过训练大量模型并度量表现来估计参数最佳值,这一过程称为调参(tuning),并常与交叉验证配合使用。
七、可复现的实验模板:从基线到对照实验
下面的模板整合了课程代码与 Parameter Play 所需的对照结构,可直接作为 notebook 的主体骨架:
# 1) 数据准备 import pandas as pd from sklearn.model_selection import train_test_split, cross_val_score from sklearn.neighbors import KNeighborsClassifier from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier from sklearn.metrics import accuracy_score, classification_report import numpy as np cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv") y = cuisines_df['cuisine'] X = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=0) # 固定种子,保证可比 # 2) 统一的评估函数:单次测试准确率 + 5 折交叉验证 def evaluate(name, model): model.fit(X_train, np.ravel(y_train)) y_pred = model.predict(X_test) acc = accuracy_score(y_test, y_pred) cv = cross_val_score(model, X_train, np.ravel(y_train), cv=5, scoring='accuracy') print(f"{name:<22} test_acc={acc:.3f} cv={cv.mean():.3f}±{cv.std():.3f}") return acc # 3) 基线(对照) C = 10 evaluate("Linear SVC C=10", SVC(kernel='linear', C=C, probability=True, random_state=0)) evaluate("KNN k=10", KNeighborsClassifier(n_neighbors=C)) evaluate("SVC default", SVC()) evaluate("RF n=100", RandomForestClassifier(n_estimators=100, random_state=0)) evaluate("ADA n=100", AdaBoostClassifier(n_estimators=100, random_state=0)) # 4) 对照实验示例:SVC 的 C 值扫描 for c in [0.1, 1, 10, 100]: evaluate(f"SVC(linear) C={c}", SVC(kernel='linear', C=c, probability=True, random_state=0)) # 5) 对照实验示例:KNN 的近邻数扫描 for k in [3, 5, 10, 20, 50]: evaluate(f"KNN k={k}", KNeighborsClassifier(n_neighbors=k)) # 6) 对照实验示例:AdaBoost 的学习率扫描 for lr in [0.1, 0.5, 1.0]: evaluate(f"ADA lr={lr} n=100", AdaBoostClassifier(n_estimators=100, learning_rate=lr, random_state=0))每个evaluate之后,建议在 notebook 中紧跟一个 Markdown 文本框,记录三件事:改了什么、数值怎么变、机理上为什么。这正是评分标准中"优秀"档的核心要求。
八、撰写解释与提交要点
要让 notebook 达到"优秀"档,解释部分应遵循"现象 → 机理 → 印证"的结构:
- 现象:报告
test_acc与cv的量化变化,例如"C 从 10 降到 1,测试准确率从 78.6% 升到 80.2%"; - 机理:说明该参数在算法中扮演的角色,例如"C 是正则化参数,控制误分类惩罚,过大的 C 使边界过度贴合训练点而损害泛化";
- 印证:引用分类报告或混淆矩阵佐证,例如"korean 类 recall 从 0.58 升至 0.70,说明小 k 对该类噪声敏感"。
同时注意三点实操纪律:
- 固定随机种子:所有模型统一
random_state,确保差异只来自参数而非数据划分; - 同一评估口径:准确率、precision、recall、f1 统一在测试集上计算,并至少补一组交叉验证;
- 关注类别级指标:整体准确率会掩盖单类退化,务必逐类查看
classification_report输出。
九、延伸:从手动调参走向系统化 Tuning
Parameter Play 是理解模型机制的起点,而系统化的参数搜索属于课程后续的进阶主题。R 版解答中已给出两条可迁移的思路:
- 工作流批量对比:定义函数把多个模型工作流(workflow)一次拟合、一次评估,用统一的 metric set(accuracy、sensitivity、PPV、F-measure)横向比较——对应到 Python 生态,可用
cross_val_score+ 结果 DataFrame 实现同等的批量对比脚本; - 交叉验证驱动的调参:手工扫描参数网格后,真正工程化时应借助交叉验证估计每个参数组合的泛化表现,再据此选择最优配置,这即是课程所定义的tuning过程。
完成 Parameter Play 作业后,你已经具备解释"为什么某个参数改动有效"的能力,这正是后续学习超参数搜索、正则化权衡与模型选择的基础。
参考资源(仓库内)
- 课程正文:4-Classification/3-Classifiers-2/README.md
- 作业英文原文:4-Classification/3-Classifiers-2/assignment.md
- 官方起始 notebook:4-Classification/3-Classifiers-2/notebook.ipynb
- Python 解答 notebook:4-Classification/3-Classifiers-2/solution/notebook.ipynb
- R 语言解答:4-Classification/3-Classifiers-2/solution/R/lesson_12.Rmd
- 实验数据集:4-Classification/data/cleaned_cuisines.csv
- 教程
- 机器学习
- 人工智能
【免费下载链接】ML-For-Beginners
12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all
相关推荐
ML-For-Beginners 参数实验(Parameter Play):菜系分类器参数调优实战指南
ML For Beginners 参数实验(Parameter Play):菜系分类器参数调优实战指南 面向经典 ML 教学课程 ML For Beginner
教程机器学习人工智能ML-For-Beginners 菜品分类之 Parameter Play:基于 Scikit-learn 的分类器参数调优实战指南
ML For Beginners 菜品分类之 Parameter Play:基于 Scikit learn 的分类器参数调优实战指南 本文围绕 ML For B
教程机器学习人工智能MCP Apps授权完全指南:整服务器与按工具OAuth两种方案对比
MCP Apps授权完全指南:整服务器与按工具OAuth两种方案对比 MCP Apps 允许你把交互式界面(图表、表单、仪表盘)直接嵌入 AI 聊天框,但真实业
MCP 服务前端AI 技能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考