☰
ML-For-Beginners 分类器参数调优实战:以菜品分类数据完成 Parameter Play 实验
2026/10/10 1:22:43 网站建设 项目流程
  • 教程
  • 机器学习
  • 人工智能

【免费下载链接】ML-For-Beginners

12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all

项目地址:https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners
点击查看免费下载

本指南以 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,解释为什么某些改动会提升模型质量,而另一些改动会使其变差。请详细作答。

拆解任务可以归纳为四个可执行步骤:

  1. 选定分类器:从本课涉及的 Linear SVC、K-Neighbors、SVC、Random Forest、AdaBoost 中任选一种(也可全部尝试)。
  2. 挖掘默认参数:借助 VS Code 的 Intellisense(悬停查看函数签名与文档)或 scikit-learn 文档,把每个可调参数找出来。
  3. 控制变量地重训:每次只改动一个参数,记录测试集上的准确率、precision、recall、f1 等指标变化。
  4. 解释因果:在 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 SVC78.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 环节也提示:"每种技术都有大量可调参数,请研究各自默认参数,思考调整它们对模型质量意味着什么。"

推荐的实验流程:

  1. 以基线配置为对照;
  2. 选定一个参数,取递增/递减序列(如C ∈ {0.1, 1, 10, 100});
  3. 逐档训练并在同一测试集上评估;
  4. 用交叉验证替代单次划分,避免偶然性(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 对该类噪声敏感"。

同时注意三点实操纪律:

  1. 固定随机种子:所有模型统一random_state,确保差异只来自参数而非数据划分;
  2. 同一评估口径:准确率、precision、recall、f1 统一在测试集上计算,并至少补一组交叉验证;
  3. 关注类别级指标:整体准确率会掩盖单类退化,务必逐类查看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

项目地址:https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners
点击查看免费下载

相关推荐

上一篇:从源码到应用:AndroidRTC完整开发路线图(含ProjectRTC服务搭建)
下一篇:【亲测免费】 GPGPU-Sim 模拟器:详尽的GPU仿真平台

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询