ML-For-Beginners 实战指南:用完整南瓜数据集重练逻辑回归,从数据清洗到 ROC 曲线评估
2026/9/10 13:49:51 网站建设 项目流程

ML-For-Beginners 实战指南:用完整南瓜数据集重练逻辑回归,从数据清洗到 ROC 曲线评估

【免费下载链接】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 课(2-Regression/4-Logistic/README.md)中,我们曾用南瓜数据的子集训练了一个预测南瓜颜色(Orange/White)的二分类模型。而本课作业(translations/de/2-Regression/4-Logistic/assignment.md)提出了更高的要求:回到原始数据集,尝试使用全部数据(清洗并标准化后)重新构建逻辑回归模型。读完本文,你将掌握完整的实战链路——从原始 CSV 的加载清洗、特征与标签编码、数据可视化,到逻辑回归建模、混淆矩阵与 ROC/AUC 评估,并了解如何对照评分标准自检模型质量。

任务解读:为什么作业要求"全量数据"

课程中的演示代码只选取了['City Name','Package','Variety', 'Origin','Item Size', 'Color']六个字段,并在dropna之后丢弃了大量含缺失值的行——这正是作业所说的"子集"。而作业要求"go back to the original data and try to use all of it, cleaned and standardized"(assignment.md),意味着你需要:

  • 回到完整原始数据文件 2-Regression/data/US-pumpkins.csv;
  • 对全部可用字段进行清洗与标准化(而不是只保留六列);
  • 用清洗后的完整数据重新训练逻辑回归模型。

逻辑回归的一个关键特性是:数据越多,结果越准确("Logistic regression will give more accurate results if you use more data")。课程数据仅约 1000 行,属于小样本,因此全量数据的利用对提升模型表现有直接意义。

数据准备:加载原始数据与清洗

起步于课程配套的 starter notebook。首先加载原始数据:

import pandas as pd import numpy as np full_pumpkins = pd.read_csv('../data/US-pumpkins.csv') full_pumpkins.head()

从 notebook.ipynb 的输出可以看到,原始数据包含 26 列,包括City NamePackageVarietyGradeDateLow PriceHigh Price以及大量含 NaN 的字段(如Sub VarietyQualityStorage等)。清洗的第一步是处理缺失值:

columns_to_select = ['City Name','Package','Variety', 'Origin','Item Size', 'Color'] pumpkins = full_pumpkins.loc[:, columns_to_select] pumpkins.dropna(inplace=True)

在"全量数据"方案中,你可以放宽列选择的范围,但需要注意:逻辑回归要求数值输入,而原数据中DatePrice等字段还需要额外的解析与标准化处理。核心思想是:用更多行、更多特征训练,但前提是每个特征都被正确编码为数值

特征与标签编码:Ordinal、One-Hot 与 ColumnTransformer

机器无法直接理解字符串,因此编码是数据预处理的关键一步("Good encoding leads to building a good model")。课程区分了两类编码器(README.md):

  1. OrdinalEncoder(顺序编码)——适用于存在逻辑顺序的类别变量,如Item Size。数据中该列包含sml, med, med-lge, lge, xlge, jbo, exjbo七种尺寸,按从小到大映射为 0~6:
from sklearn.preprocessing import OrdinalEncoder item_size_categories = [['sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo']] ordinal_features = ['Item Size'] ordinal_encoder = OrdinalEncoder(categories=item_size_categories)
  1. OneHotEncoder(独热编码)——适用于无顺序关系的名义变量(nominal),如City NamePackageVarietyOrigin。每个类别被展开为一个 0/1 二进制列:
from sklearn.preprocessing import OneHotEncoder categorical_features = ['City Name', 'Package', 'Variety', 'Origin'] categorical_encoder = OneHotEncoder(sparse_output=False)
  1. ColumnTransformer(列转换器)——将多个编码器组合成一步,并指定各自作用的列。在 solution/notebook.ipynb 中可以看到,编码后的 DataFrame 变为 48 列(1 个顺序特征 + 47 个独热列),列名形如cat__City Name_BALTIMORE
from sklearn.compose import ColumnTransformer ct = ColumnTransformer(transformers=[ ('ord', ordinal_encoder, ordinal_features), ('cat', categorical_encoder, categorical_features) ]) ct.set_output(transform='pandas') encoded_features = ct.fit_transform(pumpkins)
  1. 标签编码——使用LabelEncoder将标签Color映射为 0/1(ORANGE→0,WHITE→1),然后合并为最终训练集:
from sklearn.preprocessing import LabelEncoder label_encoder = LabelEncoder() encoded_label = label_encoder.fit_transform(pumpkins['Color']) encoded_pumpkins = encoded_features.assign(Color=encoded_label)

数据可视化:洞察特征与标签的关系

编码之后,建议先用 Seaborn 可视化数据分布,判断特征与标签的关系。课程给出了三种典型图:

分类计数图(catplot count)——观察各Variety下橙色/白色南瓜的数量分布:

import seaborn as sns palette = { 'ORANGE': 'orange', 'WHITE': 'wheat', } sns.catplot( data=pumpkins, y="Variety", hue="Color", kind="count", palette=palette, )

箱线图(box)——用编码后的Item Size作为 x 轴,按品种分行,观察颜色与尺寸的关系:

pumpkins['Item Size'] = encoded_pumpkins['ord__Item Size'] g = sns.catplot( data=pumpkins, x="Item Size", y="Color", row='Variety', kind="box", orient="h", sharex=False, margin_titles=True, height=1.8, aspect=4, palette=palette, ) g.set(xlabel="Item Size", ylabel="").set(xlim=(0,6)) g.set_titles(row_template="{row_name}")

Swarm 图——展示二分类标签(0/1)与尺寸的分布关系。注意:当数据点过多时 Seaborn 会发出警告,官方建议忽略该警告以保证可读性(缩小 marker 会破坏可读性):

palette = { 0: 'orange', 1: 'wheat' } sns.swarmplot(x="Color", y="ord__Item Size", data=encoded_pumpkins, palette=palette)

构建逻辑回归模型:训练与预测

模型构建在 Scikit-learn 中非常直接(README.md):

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_size=0.2, random_state=0)
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))

课程中基于子集数据的基线成绩为:accuracy 0.92、macro avg f1 0.85、F1-score 0.746(solution/notebook.ipynb)。你的作业目标就是在此基础上利用全量数据获得更优或至少持平的成绩——这直接对应评分标准中的"well-performing model"。

模型评估:混淆矩阵、Precision/Recall 与 ROC 曲线

混淆矩阵

通过confusion_matrix可以直观理解模型在二分类上的错误类型:

from sklearn.metrics import confusion_matrix confusion_matrix(y_test, predictions)

课程中的输出为array([[162, 4], [11, 22]])。在 Scikit-learn 中,行(axis 0)是真实标签,列(axis 1)是预测标签

预测 0预测 1
真实 0TNFP
真实 1FNTP

对"白色/非白色"分类而言:TN=162(预测非白且实际非白)、FP=4(预测白但实际非白)、FN=11(预测非白但实际白)、TP=22(预测白且实际白)。理想情况下 TP 与 TN 应尽量大、FP 与 FN 尽量小。

Precision、Recall 与 F1 的数学定义

课程明确给出了各指标与混淆矩阵的换算关系(README.md):

  • Precision(精确率)= TP / (TP + FP),即预测为正类的样本中真正为正类的比例。本例:22 / (22 + 4) = 0.846
  • Recall(召回率)= TP / (TP + FN),即实际正类中被正确找出的比例。本例:22 / (22 + 11) = 0.667
  • F1-score= (2 × precision × recall) / (precision + recall),精确率与召回率的加权平均,最优为 1
  • Support:每个标签的真实出现次数
  • Accuracy= (TP + TN) / (TP + TN + FP + FN),预测正确的总比例
  • Macro Avg:各标签指标的未加权平均(不考略类别不平衡)
  • Weighted Avg:按各标签 support 加权后的平均(考略类别不平衡)

思考题:如果业务上希望尽量减少假阴性(漏判白色南瓜),应当重点观察哪个指标?答案是 Recall。

ROC 曲线与 AUC

最后用 ROC 曲线可视化分类器的输出质量——它描绘了真正例率(TPR,Y 轴)与假正例率(FPR,X 轴)的权衡,曲线越快速攀升并越过对角线越好:

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()

auc = roc_auc_score(y_test, y_scores[:,1]) print(auc)

课程基线的 AUC 为0.9749908725812341——AUC 取值范围 0~1,越接近 1 说明模型区分正负类的能力越强。这是检验全量数据模型的重要基准数字。

评分标准与提交建议

作业的评分表(assignment.md)分三档:

标准优秀(Exemplary)合格(Adequate)待改进(Needs Improvement)
交付物提交一个讲解充分、运行良好的模型的 Notebook提交一个勉强运行的模型的 Notebook提交一个表现不佳或没有模型的 Notebook

对照该标准,建议你在交付 Notebook 时包含:

  1. 清晰的步骤注释:数据加载、清洗、编码、建模、评估各环节均有文字说明;
  2. 可复现的代码:所有代码可一键从头运行(参考 solution/notebook.ipynb 的结构);
  3. 完整的评估输出classification_report、混淆矩阵、ROC 曲线与 AUC 值;
  4. 与基线对比的结论:说明全量数据相对子集数据在 accuracy、F1、AUC 上的变化,并分析可能的原因(如样本量增加带来的方差下降、新增特征引入的噪声等)。

通过本次练习,你将完整经历"全量数据 + 编码 + 逻辑回归 + 多维评估"的机器学习闭环,这为后续分类章节(如 4-Classification 课程组)打下了坚实的实践基础。

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

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

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

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

立即咨询