ML-For-Beginners 分类进阶:基于 Scikit-learn 路线图的五款分类器对比实战(Cuisine Classifiers 2)
2026/9/7 2:59:02 网站建设 项目流程

ML-For-Beginners 分类进阶:基于 Scikit-learn 路线图的五款分类器对比实战(Cuisine Classifiers 2)

【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners

本文基于 ML-For-Beginners 课程4-Classification章节的第二课「Cuisine classifiers 2」展开:以一份 3995 条、五国料理类别均衡的菜谱数据集为对象,沿着 Scikit-learn 官方算法路线图的决策路径,依次实战 Linear SVC、K-Neighbors、SVC(RBF 核)、Random Forest 与 AdaBoost 五款分类器,记录各自的训练代码、分类报告与准确率表现。读完后你能掌握"按数据画像选择估计器"的决策方法,以及每个分类器关键超参数(C、n_neighbors、n_estimators 等)的含义与调参思路。

前置条件与数据准备

本课程的默认假设是:你已经完成了分类章节的前序课程,并且在本四课文件夹根目录的data文件夹中有一份清洗好的数据集 cleaned_cuisines.csv(该数据集由 Lesson 1 中整理得到)。

从实际数据文件可以确认其规模:

  • 3995 行样本、382 列
  • 第一列为行索引Unnamed: 0,第二列为标签列cuisine,其余 380 列为二值化的食材特征(0/1,表示该菜谱是否含某种食材);
  • 五个类别完全均衡:indian、thai、chinese、japanese、korean 各799 条

本课程的 notebook.ipynb 已预置好数据加载代码,把数据集拆成了模型构建所需的两部分:

import pandas as pd cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv") cuisines_df.head() cuisines_label_df = cuisines_df['cuisine'] cuisines_label_df.head() cuisines_features_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1) cuisines_features_df.head()

从 notebook 的四个单元格结构看,准备工作只做了三件事:读入 CSV、取出cuisine列作为标签y、剔除索引列和标签列后剩余 380 列食材特征作为X。数据以 DataFrame 形式就位后,即可进入建模环节。该课程还提供了一份 R 语言平行实现 lesson_12.Rmd,供使用 R 生态的读者参考。

一张分类路线图:如何"走路"到决策

上一课(Cuisine classifiers 1)中,课程使用微软的机器学习选择 cheat sheet 来介绍分类选项。本课则引入 Scikit-learn 版本——一张更细粒度的算法路线图(即文首的 map.png),它把分类、回归、聚类、降维四大任务按"样本量、是否有标签、是否预测类别/数值"等维度组织成可点击的决策树。

当你已经对数据有清晰把握时,可以沿着图上的分支"走"出一条确定的路线。对本数据集而言,决策过程是:

  1. 样本数 > 50(实际 3995 条);
  2. 目标是预测一个类别(cuisine);
  3. 数据是有标签的(监督学习);
  4. 样本数 < 10 万;
  5. 于是路线指向 ✨Linear SVC(线性支持向量分类器);
  6. 如果效果不佳——由于我们的数据是数值型特征——可以继续尝试 ✨KNeighbors Classifier
  7. 仍不理想时,升级到 ✨SVC与 ✨Ensemble Classifiers(集成分类器)。

这正是本课实验的完整脚本:五个分类器,按路线图顺序逐一登场。

实验准备:导入库并划分训练/测试集

导入所需库

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

划分训练集与测试集

X_train, X_test, y_train, y_test = train_test_split(cuisines_features_df, cuisines_label_df, test_size=0.3)

test_size=0.3意味着约 30% 的样本(1199 条)进入测试集,其余约 2796 条用于训练——后续每份 classification_report 中的support合计 1199 正对应这个划分。

Linear SVC 分类器

支持向量分类(SVC)属于支持向量机(SVM)家族的一个分支。SVC 的关键参数在本课中都有明确取值:

参数本课取值含义
kernel'linear'核函数,决定如何划分类别簇;取'linear'即利用 Linear SVC
C10正则化强度,约束参数(权重)的影响大小
probabilityTrue默认关闭;打开后可获得概率估计
random_state0固定随机种子,配合概率估计时对数据洗牌过程可复现

实验:构建分类器字典并训练

课程建议用一个字典统一管理所有分类器,后续每测试一款就向字典追加一项:

C = 10 # Create different classifiers. classifiers = { 'Linear SVC': SVC(kernel='linear', C=C, probability=True, random_state=0) }

然后按统一流程训练并打印分类报告:

n_classifiers = len(classifiers) for index, (name, classifier) in enumerate(classifiers.items()): classifier.fit(X_train, np.ravel(y_train)) y_pred = classifier.predict(X_test) accuracy = accuracy_score(y_test, y_pred) print("Accuracy (train) for %s: %0.1f%% " % (name, accuracy * 100)) print(classification_report(y_test, y_pred))

两个值得注意的源码细节:其一,np.ravel(y_train)把标签 DataFrame 压平为一维数组,避免 fit 收到形状不符的二维标签;其二,打印语句虽写着 "Accuracy (train)",实际计算的是accuracy_score(y_test, y_pred),即测试集准确率——阅读输出时不要混淆。

Linear SVC 的结果已经相当不错(测试集准确率78.6%):

Accuracy (train) for Linear SVC: 78.6% precision recall f1-score support chinese 0.71 0.67 0.69 242 indian 0.88 0.86 0.87 234 japanese 0.79 0.74 0.76 254 korean 0.85 0.81 0.83 242 thai 0.71 0.86 0.78 227 accuracy 0.79 1199 macro avg 0.79 0.79 0.79 1199 weighted avg 0.79 0.79 0.79 1199

K-Neighbors 分类器

K-Neighbors 属于机器学习中的"邻居"方法族,同时可用于监督与无监督学习:先产生一组预先定义数量的参考点,把数据聚集在这些点周围,从而为数据预测泛化的标签。对本数据集,KNN 直接沿用了上面的C = 10作为邻居数。

实验:追加 KNN 到分类器字典

上一款分类器表现不错,但或许还能更好。在字典的 Linear SVC 项后补一个逗号,追加:

'KNN classifier': KNeighborsClassifier(C),

注意这里把C作为了KNeighborsClassifier的第一个位置参数,即n_neighbors=10——同一个数值 10,在 SVC 里是正则化系数,在 KNN 里是邻居数,含义完全不同。

结果略逊于 Linear SVC(测试集准确率73.8%):

Accuracy (train) for KNN classifier: 73.8% precision recall f1-score support chinese 0.64 0.67 0.66 242 indian 0.86 0.78 0.82 234 japanese 0.66 0.83 0.74 254 korean 0.94 0.58 0.72 242 thai 0.71 0.82 0.76 227 accuracy 0.74 1199 macro avg 0.76 0.74 0.74 1199 weighted avg 0.76 0.74 0.74 1199

从报告可以看出 KNN 的短板在 korean 类:precision 高达 0.94 但 recall 只有 0.58,即"判为韩料的多数是对的,但大量韩料菜谱被漏判"——邻居法在特征高度稀疏、维度高达 380 的食材空间中,受距离度量稀释的影响比线性模型更明显。

Support Vector 分类器(默认 RBF 核)

支持向量分类器是 SVM 家族的成员,用于分类与回归任务。SVM 的直观思想是"把训练样本映射到空间中的点",并最大化两类之间的间隔;后续新数据被映射进这个空间后即可预测其类别。

实验:追加默认配置的 SVC

在 KNN 项后加逗号,追加一行:

'SVC': SVC(),

不传任何参数即采用 Scikit-learn 默认配置(默认核为 RBF,C=1.0)。结果有了明显提升,达到83.2%

Accuracy (train) for SVC: 83.2% precision recall f1-score support chinese 0.79 0.74 0.76 242 indian 0.88 0.90 0.89 234 japanese 0.87 0.81 0.84 254 korean 0.91 0.82 0.86 242 thai 0.74 0.90 0.81 227 accuracy 0.83 1199 macro avg 0.84 0.83 0.83 1199 weighted avg 0.84 0.83 0.83 1199

与 Linear SVC 对比可以看到:非线性 RBF 核把 korean 的 recall 从 0.81 提到 0.82 以上,chinese 的 precision 从 0.71 提到 0.79,说明食材特征之间的非线性组合关系确实存在且被 RBF 核捕捉到了。

集成分类器:Random Forest 与 AdaBoost

即使上一轮结果已经相当好,课程仍要求把路线图走到终点:尝试"集成分类器"——具体是 Random Forest 与 AdaBoost。

'RFST': RandomForestClassifier(n_estimators=100), 'ADA': AdaBoostClassifier(n_estimators=100)

两者的机制各有侧重:

  • Random Forest是一种"平均法"(averaging)集成:构建一片由随机性注入的"决策树森林"以避免过拟合;n_estimators参数即树的棵数(本课设为 100)。
  • AdaBoost采用" boosting"策略:先对一个数据集拟合一个分类器,再用同样的分类器在同一数据上反复拟合,逐步把权重集中到被分错的样本上,并调整后续分类器的拟合以纠正这些错误。

结果中 Random Forest 成为全场最佳(84.5%),AdaBoost 则垫底(72.4%):

Accuracy (train) for RFST: 84.5% precision recall f1-score support chinese 0.80 0.77 0.78 242 indian 0.89 0.92 0.90 234 japanese 0.86 0.84 0.85 254 korean 0.88 0.83 0.85 242 thai 0.80 0.87 0.83 227 accuracy 0.84 1199 macro avg 0.85 0.85 0.84 1199 weighted avg 0.85 0.84 0.84 1199 Accuracy (train) for ADA: 72.4% precision recall f1-score support chinese 0.64 0.49 0.56 242 indian 0.91 0.83 0.87 234 japanese 0.68 0.69 0.69 254 korean 0.73 0.79 0.76 242 thai 0.67 0.83 0.74 227 accuracy 0.72 1199 macro avg 0.73 0.73 0.72 1199 weighted avg 0.73 0.72 0.72 1199

集成的本质是"融合多个基估计器的预测"以提升模型质量。Random Forest 在五个类别上的 precision/recall 全面均衡;AdaBoost 则暴露出典型问题——chinese 类 recall 仅 0.49,说明 boosting 对稀疏高维特征上的弱学习器组合并不占优。

五款分类器对比汇总

分类器关键参数测试集准确率优势类别(按 f1)薄弱类别
Linear SVCkernel='linear', C=10, probability=True78.6%indian (0.87)chinese (0.69)
KNNn_neighbors=1073.8%indian (0.82)korean (0.72)
SVC(默认 RBF)默认参数83.2%indian (0.89)chinese (0.76)
Random Forestn_estimators=10084.5%indian (0.90)chinese (0.78)
AdaBoostn_estimators=10072.4%indian (0.87)chinese (0.56)

可以看出两个跨模型的规律:indian 类在所有分类器下都最易识别,chinese 类则始终最难——这提示类别难度既来自模型也来自特征本身的判别力;而"路线图顺序"(Linear SVC → KNN → SVC → Ensemble)在本数据上大体对应着准确率的爬升路径。

挑战与课后作业:玩转超参数

课程给出的挑战是:这些技术各自都有大量可调参数。去查阅它们的默认参数,并思考调整这些参数对模型质量意味着什么。

具体到本课用到的五个估计器,值得重点研究的参数包括:

  • SVC / Linear SVCC(正则化强度)、kernel(linear/rbf/poly 等)、gammaprobability
  • KNeighborsClassifiern_neighborsweights('uniform' 或 'distance')、metric(距离度量)、p
  • RandomForestClassifiern_estimators(树棵数)、max_depthmin_samples_splitclass_weight
  • AdaBoostClassifiern_estimatorslearning_ratealgorithm(SAM/SAM_E/ADA);
  • 通用验证工具:cross_val_score(本课导入但留给读者在挑战中实践)、confusion_matrixprecision_recall_curve

正式作业见 assignment.md「Parameter Play」:选定本课任一分类技术,调整不同参数值重新训练,并产出一份解释"哪些改动提升了模型质量、哪些导致退化"的 notebook,评分标准(rubric)要求完整构建分类器、逐项调参并用文字解释每处改动。完整可运行的参考实现位于 solution/notebook.ipynb,其中分类器字典一次性包含全部五个估计器,训练循环与上文一致;R 语言版本参考 solution/R/lesson_12.Rmd。

小结

本课以一份 3995 条五类均衡的菜谱二值特征数据为载体,完整演示了"按 Scikit-learn 路线图选模型 → 逐一实验 → 用 classification_report 对比 → 归纳调参方向"的经典机器学习工作流。最终 Random Forest 以 84.5% 的测试集准确率胜出,而 AdaBoost 的落后则提醒我们:集成并非万能,算法选择必须结合数据特征(维度、稀疏度、类别结构)来判断。

【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners

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

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

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

立即咨询