ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ML-For-Beginners 回归课组收官课:基于 Scikit-learn 与 Seaborn 的南瓜颜色 Logistic Regression 二分类实战

ML-For-Beginners 回归课组收官课:基于 Scikit-learn 与 Seaborn 的南瓜颜色 Logistic Regression 二分类实战 ML-For-Beginners 回归课组收官课基于 Scikit-learn 与 Seaborn 的南瓜颜色 Logistic Regression 二分类实战【免费下载链接】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 开源课程项目的2-Regression/4-Logistic课程回归课组的最后一课完整还原“用逻辑回归预测二分类类别”的全部实战流程从美国南瓜市场数据的清洗到 Seaborn 分类可视化、序数/独热编码等特征工程再到 Scikit-learn 建模、混淆矩阵解读与 ROC/AUC 评估。读完本文你可以独立地针对“纯文本类别数据”搭建一条可复现的二分类建模管线并能读懂分类评估报告中的每一项指标。课程定位与前置条件逻辑回归是经典机器学习classic ML中最基础的技术之一本课用它来预测二元类别这块糖果是不是巧克力这种疾病是否具有传染性这位顾客会不会选择这个产品在本课程中具体问题是——给定若干变量预测一颗南瓜最可能是什么颜色橙色或白色。本课在 ML-For-Beginners 中的前置上下文数据集US-pumpkins.csv即回归课组一直在使用的美国南瓜市场数据。从仓库实际文件确认该 CSV 共 1756 条记录、26 个字段包含City Name、Variety、Origin、Item Size、Color等列其中Color是可用于二分类的列。起始 notebooknotebook.ipynb已预置读取数据的第一格代码pd.read_csv(../data/US-pumpkins.csv)后续所有练习代码都追加在其后。参考解答solution/notebook.ipynb包含每一步的完整运行输出可对照验证本文所有代码结果另有 R 语言版解答 solution/R/lesson_4.html。课后作业assignment.md文末详述。为什么“分类方法”出现在回归课组里课程原文对此有明确说明这只是语言上的习惯——逻辑回归本质上是一种分类方法albeit a linear-based one建立在线性模型之上。其他分类方式SVM、随机森林等留到下一课组4-Classification展开。定义问题White 或 Not White课程将颜色问题表达为二分类“白色”或“非白色”。数据集中虽然还存在striped条纹类别但记录数很少不使用而且在下一步移除空值后该类别自然消失。课程原文的趣味补充白色南瓜有时被称为 “ghost”幽灵南瓜不太容易雕刻因此不如橙色南瓜流行但外观很酷。所以问题也可以表述为“Ghost 或 Not Ghost”。逻辑回归与线性回归的四点关键差异1. 输出是二元类别而非连续值线性回归预测的是连续数值例如给定南瓜产地和采收时间售价会涨多少逻辑回归预测的是二元类别“白色或非白色”。两者在能力上不可互换这也是课程信息图见文首中左右两图的本质区别。2. 还有多项与序数两类逻辑回归Multinomial多项类别数大于 1例如 “Orange、White、Striped” 三分类Ordinal序数类别之间存在逻辑顺序例如南瓜按有限的尺寸档位排序mini, sm, med, lg, xl, xxl适合对结果做逻辑排序的场景。3. 变量不要求强相关回忆一下线性回归变量相关性越强效果越好。逻辑回归正好相反——变量之间不需要对齐correlate。南瓜数据恰好相关性较弱因此适合演示这一点。4. 需要大量干净数据数据越多逻辑回归的结果越精确。南瓜数据集只有千行量级对这个任务来说并非最优课程提醒读者在解读评估分数时必须把这一点考虑在内。练习一清洗数据并保留目标列课程的第一步是清理数据删除空值并只保留建模需要的列。在 notebook 中追加以下代码columns_to_select [City Name,Package,Variety, Origin,Item Size, Color] pumpkins full_pumpkins.loc[:, columns_to_select] pumpkins.dropna(inplaceTrue)随时可以查看新的 dataframe 概况pumpkins.info结合仓库中的实际数据可以印证这一步的必要性原始 CSV 有 26 列其中大量列Grade、Sub Variety、Quality等稀疏度很高例如前几行中Variety即为NaN。选中 6 列后执行dropna只保留这 6 列全部非空的行。从后续混淆矩阵的 support 合计测试集 199 行与test_size0.2反推清洗后全量约 1000 行与课程原文“you have only about 1000 rows of data”的说法一致。可视化用 Seaborn 的 catplot 绘制分类图课程在此引入一个新库Seaborn构建在之前学过的 Matplotlib 之上用它的catplot函数比较每种Variety品种下Color的分布import seaborn as sns palette { ORANGE: orange, WHITE: wheat, } sns.catplot( datapumpkins, yVariety, hueColor, kindcount, palettepalette, )palette字典指定了每个颜色类别的绘图颜色映射橙色 →orange白色 →wheatkindcount表示统计每组的计数。运行结果与参考解答 solution/notebook.ipynb 中的输出一致即下图所示的“品种 × 颜色”计数条形格观察这张图可以看出颜色数据与品种之间的关联某些品种几乎清一色橙色个别品种则以白色居多。课程留了一个开放问题基于这张分类图你还能设想哪些有意思的探索数据预处理特征编码与标签编码南瓜数据集所有列都是文本值。类别数据对人类直观但对机器不友好——机器学习算法擅长处理数字。因此编码encoding是数据预处理阶段的关键一步它能在不丢失信息的前提下把类别数据转为数值数据。“好的编码带来好的模型”。1. 序数编码器OrdinalEncoder——适合有序变量Item Size列的取值存在逻辑顺序从小到超大属于序数变量ordinal variable。OrdinalEncoder会把每个类别映射为它在列中的顺序编号from sklearn.preprocessing import OrdinalEncoder item_size_categories [[sml, med, med-lge, lge, xlge, jbo, exjbo]] ordinal_features [Item Size] ordinal_encoder OrdinalEncoder(categoriesitem_size_categories)注意categories参数显式指定了 7 档尺寸的完整顺序sml→exjbo其中jbo/exjbo即 “jug boy”/“extra jug boy” 这类超大规格保证映射编号与真实大小顺序一致。2. 独热编码器OneHotEncoder——适合名义变量除Item Size外的其余特征City Name、Package、Variety、Origin都是名义变量nominal variable取值之间没有逻辑顺序应采用独热编码one-hot encoding每个类别变成一个二进制列该南瓜属于该类别时为 1否则为 0。from sklearn.preprocessing import OneHotEncoder categorical_features [City Name, Package, Variety, Origin] categorical_encoder OneHotEncoder(sparse_outputFalse)sparse_outputFalse让输出直接是稠密数组便于与 pandas 后续操作衔接。3. 用 ColumnTransformer 组合多个编码器ColumnTransformer把多个编码器打包成一个步骤分别作用于各自的列set_output(transformpandas)使输出保持带列名的 DataFrame其中序数列会被命名为ord__Item Size后面可视化会用到该列名from sklearn.compose import ColumnTransformer ct ColumnTransformer(transformers[ (ord, ordinal_encoder, ordinal_features), (cat, categorical_encoder, categorical_features) ]) ct.set_output(transformpandas) encoded_features ct.fit_transform(pumpkins)4. 标签编码LabelEncoder对标签列Color使用 scikit-learn 的LabelEncoder把标签归一化为0到n_classes-1之间的值这里即 0 和 1对应排序后ORANGE→ 0、WHITE→ 1from sklearn.preprocessing import LabelEncoder label_encoder LabelEncoder() encoded_label label_encoder.fit_transform(pumpkins[Color])5. 合并特征与标签编码完成后把编码特征与编码标签合并成新的 dataframeencoded_pumpkinsencoded_pumpkins encoded_features.assign(Colorencoded_label)课程思考题对Item Size列使用序数编码器有什么好处提示独热编码会为 7 档尺寸产生 7 个 0/1 列丢失“档位之间的大小关系”而序数编码用一个数值列即可保留顺序信息且不会让特征维度膨胀。分析变量之间的关系预处理完成后可以分析特征与标签之间的关系提前判断模型预测标签的能力。最好的方式就是画图再次使用 Seaborncatplot用编码后的Item Size列数值 0–6画 box 图更合理与未编码的Variety列按品种分行绘制palette { ORANGE: orange, WHITE: wheat, } pumpkins[Item Size] encoded_pumpkins[ord__Item Size] g sns.catplot( datapumpkins, xItem Size, yColor, rowVariety, kindbox, orienth, sharexFalse, margin_titlesTrue, height1.8, aspect4, palettepalette, ) g.set(xlabelItem Size, ylabel).set(xlim(0,6)) g.set_titles(row_template{row_name})这里kindbox画箱线图orienth横向布局rowVariety为每个品种生成一行g.set(xlim(0,6))把横轴限制在序数编码的 0–6 范围内。Swarm plot 展示数值分布由于Color是二分类White 或 Not课程指出它需要“专门化的可视化方法”。Seaborn 的 swarm plot蜂群图适合展示数值变量的分布palette { 0: orange, 1: wheat } sns.swarmplot(xColor, yord__Item Size, dataencoded_pumpkins, palettepalette)注意由于数据点较多Seaborn 可能无法在 swarm plot 中完整表示所有点而发出警告。一个可能的解决办法是用size参数减小标记大小但要留意这会影响图表可读性。数学视角Sigmoid 函数与最大似然Show Me The Math逻辑回归依赖**最大似然maximum likelihood**估计其核心是Sigmoid 函数。Sigmoid 曲线在图上呈 “S” 形把任意输入值映射到 0 与 1 之间其曲线又称“逻辑曲线”公式为f(x) L / (1 e^(-k(x - x₀)))其中 S 形曲线中点位于 x 轴的 x₀ 处L 是曲线的最大值k 是曲线的陡峭程度。若函数输出大于 0.5该样本被归入二元选择中的 “1” 类否则归入 “0” 类。仓库中保留了该公式的配图 images/sigmoid.png。结合上面的LabelEncoder可知0 对应ORANGE1 对应WHITE即模型最终是在输出“这颗南瓜是白色的概率是否越过 0.5 阈值”。构建模型三行代码完成训练与预测在 Scikit-learn 中构建这个二分类模型出奇地简单。1. 划分训练集与测试集from sklearn.model_selection import train_test_split X encoded_pumpkins[encoded_pumpkins.columns.difference([Color])] y encoded_pumpkins[Color] X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state0)encoded_pumpkins.columns.difference([Color])从全部列中剔除标签列剩余列作为特征矩阵 Xtest_size0.2留出 20% 作测试集random_state0固定随机种子保证结果可复现。2. 训练模型并打印评估报告from sklearn.metrics import f1_score, classification_report from sklearn.linear_model import LogisticRegression model LogisticRegression() model.fit(X_train, y_train) predictions model.predict(X_test) print(classification_report(y_test, predictions)) print(Predicted labels: , predictions) print(F1-score: , f1_score(y_test, predictions))模型的成绩单如下参考解答 notebook 中的实际输出precision recall f1-score support 0 0.94 0.98 0.96 166 1 0.85 0.67 0.75 33 accuracy 0.92 199 macro avg 0.89 0.82 0.85 199 weighted avg 0.92 0.92 0.92 199 Predicted labels: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1] F1-score: 0.7457627118644068对于只有约 1000 行数据来说这个成绩“不坏”整体 accuracy 0.92但类别 1WHITE只有 33 个样本且 recall 仅 0.67明显受到类别不平衡的影响——这正是下一节要深入分析的问题。用混淆矩阵更深入地理解模型classification_report能给出各项指标但**混淆矩阵confusion matrix又称误差矩阵**能让我们看清模型究竟在哪里犯错。混淆矩阵是一张表达“真实 vs 预测”正/负结果的表用于评估预测的准确性。调用confusion_matrix()from sklearn.metrics import confusion_matrix confusion_matrix(y_test, predictions)本模型的混淆矩阵输出array([[162, 4], [ 11, 22]])在 Scikit-learn 中混淆矩阵的行axis 0是真实标签列axis 1是预测标签010TNFP1FNTP结合南瓜场景类别 0 非白色类别 1 白色逐一解读四个格子左上162TN模型预测“非白色”南瓜实际上也属于“非白色”——真阴性右上4FP模型预测“白色”南瓜实际上属于“非白色”——假阳性左下11FN模型预测“非白色”南瓜实际上属于“白色”——假阴性右下22TP模型预测“白色”南瓜实际上也属于“白色”——真阳性。直觉上真阳性与真阴性越多、假阳性与假阴性越少模型表现越好。混淆矩阵与 precision / recall 的对应关系回忆分类报告中类别 1 的 precision 0.85 与 recall 0.67它们可以直接从混淆矩阵算出Precision TP / (TP FP) 22 / (22 4) 0.8461538461538461Recall TP / (TP FN) 22 / (22 11) 0.6666666666666666课程小结“按混淆矩阵看模型表现不差——真阴性数量可观但也存在若干假阴性。” 再用 TP/TN/FP/FN 的映射重访报告中出现的各项术语PrecisionTP/(TP FP)。被检索出的实例中真正相关的比例例如哪些标签被正确标记RecallTP/(TP FN)。真正相关的实例中被检索出来的比例无论其是否被正确标记f1-score(2 × precision × recall)/(precision recall)。precision 与 recall 的加权平均最好为 1、最差为 0Support每个被检索出的标签的出现次数上表中类别 0 为 166、类别 1 为 33Accuracy(TP TN)/(TP TN FP FN)。样本中被准确预测的标签百分比Macro Avg对每个标签的指标计算不加权平均不考虑标签不平衡Weighted Avg对每个标签的指标计算平均时按各自 support 加权从而考虑标签不平衡。课程思考题如果希望模型减少假阴性你应该盯住哪个指标答案Recall——假阴性 FN 直接出现在 recall 的分母中提高 recall 就意味着在真实正例中漏掉的更少。可视化模型的 ROC 曲线课程再补一个可视化ROCReceiver Operating Characteristic接收者操作特征曲线。from sklearn.metrics import roc_curve, roc_auc_score import matplotlib import matplotlib.pyplot as plt %matplotlib inline y_scores model.predict_proba(X_test) fpr, tpr, thresholds roc_curve(y_test, y_scores[:,1]) fig plt.figure(figsize(6, 6)) plt.plot([0, 1], [0, 1], k--) plt.plot(fpr, tpr) plt.xlabel(False Positive Rate) plt.ylabel(True Positive Rate) plt.title(ROC Curve) plt.show()关键点predict_proba返回每个类别的概率估计y_scores[:,1]取类别 1WHITE的得分传给roc_curve黑色虚线[0,1]-[0,1]是“随机猜测”的对角参考线。ROC 曲线通常以真阳性率TPR为 Y 轴、假阳性率FPR为 X 轴因此要看曲线的陡峭程度以及它与对角线之间的空隙理想的曲线应尽快向上拱起并越过对角线。本模型的结果正是如此——起点存在少量假阳性随后曲线迅速上扬并保持在参考线上方最后用roc_auc_score计算曲线下的真实面积AUCauc roc_auc_score(y_test, y_scores[:,1]) print(auc)结果为0.9749908725812341。AUC 的取值范围是 0 到 1分数越高越好——预测 100% 正确的模型 AUC 为 1本例中模型“相当不错pretty good”与混淆矩阵给出的判断相互印证整体判别能力强主要短板在少数类WHITE的召回上。进阶挑战、作业与延伸阅读课程在结尾给出三个延伸出口 Challenge找一套适合这类分析的数据集自己搭一个逻辑回归模型并总结学到了什么课程提示可从 Kaggle 等平台的公开数据集入手。课后作业assignment.md本课只用了南瓜数据的子集作业要求回到原始数据将其清洗并标准化后全部用上重新构建一个 Logistic Regression 模型。评分标准Rubric分三档优秀 提交一个解释充分且表现良好的 notebook合格 提交一个基本可用的模型待改进 模型表现不佳或没有模型。自学阅读斯坦福关于逻辑回归实际用途的教材章节课程原文附了 PDF 链接思考哪些任务更适合线性回归、哪些更适合逻辑回归。至此完成回归课组。后续4-Classification课组将学习如何迭代优化模型得分、使用更多分类器课程仓库中对应的 4-Classification/1-Introduction 可作为下一步入口。本文涉及的仓库文件索引文件作用2-Regression/4-Logistic/README.md本课英文原版讲义本文主体依据另有多语种翻译如 translations/cs/2-Regression/4-Logistic/README.md2-Regression/4-Logistic/notebook.ipynb练习用起始 notebook预置数据加载代码2-Regression/4-Logistic/solution/notebook.ipynb含完整运行输出的参考解答2-Regression/4-Logistic/solution/R/lesson_4.htmlR 语言版讲义解答2-Regression/4-Logistic/assignment.md课后作业与评分标准2-Regression/data/US-pumpkins.csv南瓜市场原始数据集1756 行 × 26 列2-Regression/4-Logistic/images/本课全部配图linear-vs-logistic、pumpkin-classifier、multinomial-vs-ordinal、catplot、swarm、sigmoid、ROC 等【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表