拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ML-For-Beginners 分类入门实战:用 scikit-learn 与 SMOTE 构建均衡的亚洲美食多类分类数据集

ML-For-Beginners 分类入门实战用 scikit-learn 与 SMOTE 构建均衡的亚洲美食多类分类数据集【免费下载链接】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 课程体系中的「分类Classification」入门单元展开以泛亚洲与印度美食数据集为实战载体系统讲解监督学习中二元分类与多类分类的核心概念并带领读者完成从数据清洗、分布探查、特征筛选到使用 SMOTE 过采样均衡数据集的完整数据准备流程。学完本文你将掌握如何使用 pandas 与 matplotlib 探查多类数据集、如何用 imblearn 库的 SMOTE 技术消除类别不平衡偏差并产出一份可供后续分类算法直接训练的均衡数据集cleaned_cuisines.csv。上图直观对比了分类算法需要处理的二元binary问题与多类multiclass问题。分类作为机器学习研究者与数据科学家的基础活动之一从最基础的二元判断这封邮件是不是垃圾邮件到借助计算机视觉完成的复杂图像分类与分割其本质都是将数据归入类别并据此回答问题。更严谨地说分类方法构建了一个预测模型让你能够建立输入变量到输出变量之间的映射关系。从回归到分类一次概念回顾分类是监督学习supervised learning的一种形式与回归技术有大量共通之处。在进入分类课程之前先回顾此前回归单元的两类关键成果线性回归帮助我们预测变量之间的关系并准确判断一个新数据点相对于回归线的落点。例如可以预测南瓜在九月与十二月之间的价格差异。逻辑回归帮助我们发现二元类别例如在某个价格区间下这个南瓜是橙色的还是非橙色的。而分类则利用多种算法以另外的方式为数据点确定标签或类别。在本文的美食数据集上我们要回答的问题是通过观察一组食材能否判断这道菜的菜系来源从统计学衍生的视角看经典机器学习中的分类使用诸如smoker是否吸烟、weight体重、age年龄等特征来判断患某疾病的可能性。作为与前面回归练习类似的监督学习技术分类的前提是数据带有标签机器学习算法利用这些标签对数据集进行分类、预测类别或特征并将其归入某个组或结果。你好分类器这是一个多类分类问题我们想对美食数据集提出的问题实际上是一个多类问题multiclass question因为数据中包含了多种潜在的菜系类别给定一批食材数据将匹配到这众多类别中的哪一个Scikit-learn 根据你要解决的问题类型提供了多种不同的数据分类算法。本文所在课程的后两课更多的分类器 与 其他分类器将逐一介绍这些算法而本文的全部重心是先把数据准备到位——清洗并均衡数据以获得更好的分类结果。动手练习一清洗与均衡数据课程为每一课都准备了一个空白的 notebook.ipynb请以它作为起点逐单元执行。安装 imblearn首先要安装 imblearnimbalanced-learn这是一个用于处理不平衡数据的 scikit-learn 配套包稍后我们将借助其中的 SMOTE 技术来均衡数据pip install imblearn仓库中已完成的 solution/notebook.ipynb 记录了当时的运行环境imbalanced-learn 0.8.0、scikit-learn 0.24.2、numpy 1.19.2、scipy 1.4.1、Python 3.7。具体依赖版本以你当前环境的实际安装结果为准。导入依赖导入读取与可视化数据所需的包并从imblearn引入SMOTEimport pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np from imblearn.over_sampling import SMOTE读取数据原始数据位于仓库的 cuisines.csv即课程文档中../data/cuisines.csv所指的位置。使用read_csv()读取 CSV 内容并放入变量dfdf pd.read_csv(../data/cuisines.csv)查看数据形状用head()查看前五行df.head()前五行输出如下| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini | | --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- | | 0 | 65 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 1 | 66 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 2 | 67 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 3 | 68 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 4 | 69 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |可以看到数据集的每一行代表一道菜cuisine列是目标标签如indian其余 380 列是各种食材的 0/1 出现标记。用info()获取整体结构df.info()输出类似class pandas.core.frame.DataFrame RangeIndex: 2448 entries, 0 to 2447 Columns: 385 entries, Unnamed: 0 to zucchini dtypes: int64(384), object(1) memory usage: 7.2 MB即2448 个样本、385 列Unnamed: 0是 CSV 自带的无效索引列后续将删除其中 384 列为数值型int64仅cuisine一列为对象型object。动手练习二了解各菜系的数据分布接下来探查数据在各菜系上的分布情况。绘制分布条形图调用barh()绘制横向条形图df.cuisine.value_counts().plot.barh()可以看到菜系种类有限但数据分布很不均匀——这正是后续需要修复的问题。在动手修复之前先进一步探索。统计各菜系样本数按菜系过滤出子集并打印形状thai_df df[(df.cuisine thai)] japanese_df df[(df.cuisine japanese)] chinese_df df[(df.cuisine chinese)] indian_df df[(df.cuisine indian)] korean_df df[(df.cuisine korean)] print(fthai df: {thai_df.shape}) print(fjapanese df: {japanese_df.shape}) print(fchinese df: {chinese_df.shape}) print(findian df: {indian_df.shape}) print(fkorean df: {korean_df.shape})输出thai df: (289, 385) japanese df: (320, 385) chinese df: (442, 385) indian df: (598, 385) korean df: (799, 385)各类别样本量从泰餐的 289 条到韩餐的 799 条不等最大类别与最小类别相差约 2.8 倍。如果直接拿去训练模型会天然偏向样本更多的类别因此必须引入均衡手段。发现食材分析各菜系的典型配料在均衡之前还需要深入了解每个菜系的典型食材并剔除那些在多个菜系中反复出现、容易造成混淆的通用食材。编写食材统计函数create_ingredient_df()的作用是转置 DataFrame删除cuisine与Unnamed: 0两列后按行求和得到每种食材在该菜系样本中的总出现次数并排序返回def create_ingredient_df(df): ingredient_df df.T.drop([cuisine,Unnamed: 0]).sum(axis1).to_frame(value) ingredient_df ingredient_df[(ingredient_df.T ! 0).any()] ingredient_df ingredient_df.sort_values(byvalue, ascendingFalse, inplaceFalse) return ingredient_df绘制各菜系 Top 10 食材对五个菜系分别调用该函数并绘制前 10 种食材thai_ingredient_df create_ingredient_df(thai_df) thai_ingredient_df.head(10).plot.barh()japanese_ingredient_df create_ingredient_df(japanese_df) japanese_ingredient_df.head(10).plot.barh()chinese_ingredient_df create_ingredient_df(chinese_df) chinese_ingredient_df.head(10).plot.barh()indian_ingredient_df create_ingredient_df(indian_df) indian_ingredient_df.head(10).plot.barh()korean_ingredient_df create_ingredient_df(korean_df) korean_ingredient_df.head(10).plot.barh()仓库 images 目录下保存了这五张图表对应的成品图片thai.png、japanese.png、chinese.png、indian.png、korean.png可以直接对照检查自己的绘图结果。从图表可以直观看出米rice、大蒜garlic、姜ginger是几乎所有菜系都高频使用的通用食材——它们对区分菜系几乎没有帮助反而会制造混淆。剔除通用混淆食材调用drop()删除这些通用食材列同时删掉无用的Unnamed: 0索引列并单独提取标签列feature_df df.drop([cuisine,Unnamed: 0,rice,garlic,ginger], axis1) labels_df df.cuisine #.unique() feature_df.head()此步之后特征空间从 385 列缩减为380 个食材特征列385 − 2 个标签/索引列 − 3 个通用食材。均衡数据集使用 SMOTE 过采样数据清洗完成后使用 SMOTE——合成少数类过采样技术Synthetic Minority Over-sampling Technique——来均衡各类别。调用 fit_resample 合成新样本oversample SMOTE() transformed_feature_df, transformed_label_df oversample.fit_resample(feature_df, labels_df)为什么要均衡以二元分类为例如果绝大多数数据属于某一个类别机器学习模型就会更频繁地预测该类别——仅仅因为属于它的数据更多。均衡数据能够消除这种偏差。SMOTE 的实现思路是针对样本量不足的少数类在样本点与其 k 个最近邻默认k_neighbors5之间进行线性插值合成新的少数类样本而不是简单地复制已有样本从而在扩充少数类的同时避免过拟合。对比均衡前后的标签计数print(fnew label count: {transformed_label_df.value_counts()}) print(fold label count: {df.cuisine.value_counts()})输出new label count: korean 799 chinese 799 indian 799 japanese 799 thai 799 Name: cuisine, dtype: int64 old label count: korean 799 indian 598 chinese 442 japanese 320 thai 289 Name: cuisine, dtype: int64均衡后五个菜系各拥有 799 条样本总计3995 条数据变得干净、均衡。合并标签与特征并导出最后一步将均衡后的标签与特征按列合并成一个新的 DataFrame便于导出为文件transformed_df pd.concat([transformed_label_df,transformed_feature_df],axis1, joinouter)再检查一下合并后的数据并保存副本供后续课程使用transformed_df.head() transformed_df.info() transformed_df.to_csv(../data/cleaned_cuisines.csv)从 solution/notebook.ipynb 中记录的执行结果可以看到合并后的transformed_df结构为class pandas.core.frame.DataFrame RangeIndex: 3995 entries, 0 to 3994 Columns: 381 entries, cuisine to zucchini dtypes: int64(380), object(1) memory usage: 11.6 MB这份全新的 CSV 已位于数据根目录即仓库中的 cleaned_cuisines.csv3995 行数据 1 行表头381 列。它就是后续所有分类算法逻辑回归、SVM、决策树等训练的输入基础。顺带一提本课程还提供了 R 语言版本可以在 solution/R/lesson_10.html 中查看同一套数据准备流程在 R 中的实现方式。挑战为数据匹配分类方法本课程体系包含多个有趣的数据集。建议你翻一翻仓库中各章节的data目录例如 4-Classification/data 下的cuisines.csv、cleaned_cuisines.csv、ingredient_indexes.csv等思考哪些数据集适合做二元分类哪些适合做多类分类针对这个美食数据集你会提出什么问题例如给定一批食材能否判断它是否来自泰国菜本课的作业任务要求你浏览 scikit-learn 文档中的分类方法清单从中挑选算法为该数据集设计一个问题与对应的分类技术并整理成表格或文档说明数据与算法的匹配方式。回顾与自修深入学习 SMOTE 的 API它最适合哪些使用场景它解决了什么问题又存在哪些局限例如对高维稀疏数据的适用性、可能引入的噪声结合你在本课中亲手完成的从cuisines.csv2448 条、不平衡到cleaned_cuisines.csv3995 条、各类 799 条、完全均衡的转变你会对类别不平衡是分类模型最常见敌人之一这句话有更切身的体会。在接下来的课程中这些准备妥当的数据将直接输入各种分类算法进行训练与评估。核心文件索引本课原始文档4-Classification/1-Introduction/README.md英文原版课程总览4-Classification/README.md空白练习笔记本4-Classification/1-Introduction/notebook.ipynb完整参考答案含全部输出4-Classification/1-Introduction/solution/notebook.ipynb原始数据4-Classification/data/cuisines.csv均衡后数据4-Classification/data/cleaned_cuisines.csv作业与评分标准4-Classification/1-Introduction/assignment.md【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门