经典机器学习实战06:分类入门:数据清洗与平衡(菜系)

本文收录于专栏 《经典机器学习实战》

摘要:菜系分类第一课:亚洲五菜系数据又脏又不平衡,删掉无判别力的通用食材、SMOTE 过采样把 2448 行变成五类各 799 行。这份数据将贯穿后面三课,从分类器横评一直到 ONNX 部署。

关键字:SMOTE,类别不平衡,数据清洗,独热编码,多分类,菜系数据集,过采样,特征选择
阶段 3 · 分类(菜系项目)| 来源:【原·10】| 知识更新至 2026-10

概念讲解

6.1 从二分类到多分类

第 4 课的逻辑回归做的是二分类(橙色/白色)。分类任务的另一半世界是多分类(multiclass classification) :标签不止两个。本阶段的问题是------给一袋食材,判断它属于哪个国家的菜系。

数据是亚洲与印度菜系数据集:2448 道菜、5 个菜系(korean / indian / chinese / japanese / thai)、380+ 种食材,每道菜在每个食材上标记 0 或 1(用没用)。换成第 3 课的词汇:X 是 380 维 0-1 向量,y 是 5 选 1 的菜系标签。

6.2 建模前先看分布:不平衡是毒药

拿到分类数据的第一件事是看类别分布:

复制代码
korean      799
indian      598
chinese     442
japanese    320
thai        289

最多(korean 799)是最少(thai 289)的 2.8 倍。这有什么问题?回忆第 3 课的实测:多数类会吸走模型的全部注意力------模型只要"偏向猜 korean",就能白拿一部分准确率,而 thai 会被系统性牺牲。第 4 课的白色南瓜(recall 0.67)已经演示过一次。

6.3 SMOTE:合成少数类样本

修复不平衡的办法之一:SMOTE(Synthetic Minority Over-sampling Technique,合成少数类过采样技术) 。它不是简单复制少数类样本,而是在特征空间里,取少数类样本与其近邻之间插值生成新样本------新样本"像"少数类但不重复,比硬复制更不容易过拟合。

工具是 imblearn 库(scikit-learn 的姊妹包,API 同构):

python 复制代码
from imblearn.over_sampling import SMOTE
oversample = SMOTE(random_state=42)
X_balanced, y_balanced = oversample.fit_resample(feature_df, labels_df)

fit_resample 返回平衡后的特征与标签:每个菜系都被"补"到与最多类相同的 799 条。

6.4 降噪:删掉"人人都用"的食材

平衡之前还有一步特征层面的清洗。看各菜系 top 10 食材(以 thai 为例):

复制代码
garlic 173, fish 153, cayenne 136, cilantro 121, ginger 114,
coconut 111, vegetable_oil 106, coriander 105, rice 102, chicken 97

注意 garlic(蒜)、ginger(姜)、rice(米)------这三个在所有亚洲菜系里都高频。所有菜系都用的食材没有区分度,留着只会增加类间混淆。直接删:

python 复制代码
feature_df = df.drop(['cuisine', 'Unnamed: 0', 'rice', 'garlic', 'ginger'], axis=1)

特征从 383 减到 380。删特征听起来损失信息,实际相反:把"噪声特征"去掉,剩下的特征每个都更有区分责任------这是特征选择(第 3 课概念)的实战。

案例实战:从脏数据到平衡数据

实测环境:conda env ml-course(pandas 3.0.6 / imbalanced-learn 0.14.2),2026-10-05 运行

完整脚本:stage3/assets/stage3_demos.py

目标:跑完"体检 → 删降噪食材 → SMOTE 平衡 → 存盘"全流程。

第 1 步:体检

复制代码
shape = (2448, 385)     # 2448 道菜 × (1 索引 + 1 标签 + 383 食材)

左图:5 个菜系分布明显不均(korean 接近 thai 的三倍)。右图:thai 的 top10 食材,garlic/ginger/rice 果然在列------全亚洲通用,删。

第 2 步:SMOTE 平衡

复制代码
SMOTE 后行数 = 3995
indian 799 / thai 799 / chinese 799 / japanese 799 / korean 799

2448 → 3995 行,5 个菜系完全均衡。SMOTE 为 thai 合成了 510 条新样本、为 japanese 合成 479 条,以此类推。

第 3 步:存盘

平衡后的数据保存为 cleaned_cuisines.csv,后续三课(11/12/13)全部用它。固定 random_state=42 保证每次生成的合成样本一致、数字可复现。

SMOTE 前后数据对比(实测):

平衡前 平衡后
总行数 2448 3995
每类样本 不均(最少 1xx) 799 × 5 类
删掉的食材 --- rice/garlic/ginger(全菜系通用,无判别力)
教学点 多数类淹没少数类 少数类合成过采样

小结

  1. 多分类 = 标签多于两个的分类任务;菜系数据集 2448 道 × 380 食材特征 × 5 菜系。
  2. 类别不平衡会让多数类"白捡"准确率、牺牲少数类------建模前先看分布。
  3. SMOTE 用插值合成少数类新样本(不是复制),本课把 2448 行补成 3995 行(每类 799)。
  4. 所有类别都高频的特征(rice/garlic/ginger)没有区分度,删掉是特征选择不是损失。
  5. 数据备好了,上分类器:参见第 7 课《分类器:选择思路与多分类器对比》。

扩展阅读


系列导航

  • 上一篇:第 05 课《把模型做成 Web 应用(UFO)》
  • 下一篇:第 07 课《分类器:选择思路与多分类器对比》

更多专栏:

蛋白 / 抗体 / 多肽 / 核酸 分子模拟 / 动力学 / 对接 药物 / 设计 / 案例 AI / Agent / 大模型
开源蛋白结构预测 分子模拟基础 小分子药物设计案例 AI Agent系列
开源蛋白生成方法实践 分子动力学模拟-Amber 蛋白药物设计案例 化学大模型
开源多肽设计模型 分子动力学模拟-Gromacs 多肽药物设计案例 《AI Agent原理与实战》
开源多肽性质预测 分子动力学模拟-OpenMM 开源小分子生成设计 CADD中的机器学习模型
DNA/RNA药物设计 結合自由能 高效计算配置 《MCP 入门实战》
siRNA药物设计模型 UCSF DOCK系列 我胡师兄说药 《AI入门实战2026》
ASO药物设计模型 rDock系列 LeDock系列 gnina系列 《经典机器学习实战》
相关推荐
Blockbuater_drug4 天前
《经典机器学习实战》第 2 课:回归入门——环境、工具与数据准备
线性回归·pandas·scikit-learn·数据可视化·数据清洗·最小二乘法·conda环境
Blockbuater_drug5 天前
《经典机器学习实战》第 1 课:导论——是什么、简史、负责任 AI 与标准流程
机器学习·scikit-learn·监督学习·数据清洗·过拟合·训练集测试集·公平性
Frag0ut5 天前
Notepad++ 正则表达式完全手册:文本处理的终极武器(2026实战版)
正则表达式·notepad++·数据清洗·日志分析·正则替换·提取ip·正则表达式实战
梯度下降者6 天前
Python使用统计建模解决业务预测问题的常见操作步骤【教程】
python·可解释性·数据清洗·模型选择·业务预测
东莞市云毅网络有限公司23 天前
监测问句清单去重:停用词表、数字归一与贪心聚类的参数取法
python·数据清洗·rag·企业知识库·文档解析
Helix25024 天前
Python数据分析实战:Pandas清洗豆瓣短评与情感分析完整指南
python·pandas·数据清洗·情感分析··snownlp·文本数据处理
星夜离尘5624 天前
MATLAB 清洗 CSV 采样日志:重复时间戳、无效行、分组统计与自动出图
开发语言·matlab·数据分析·数据清洗·csv
东莞市云毅网络有限公司24 天前
用 Python 给官网做字段级变更监控:快照、比对与变更清单
python·数据清洗·rag·企业知识库·文档解析
梅雅达编程笔记24 天前
15_综合实战全流程
pandas·数据清洗·seaborn·可视化分析·python数据实战·数据分析全流程·系列收尾