ML-For-Beginners 回归作业实战:用 Scikit-learn 构建并评估线性回归与多项式回归模型
2026/9/12 2:30:49 网站建设 项目流程

ML-For-Beginners 回归作业实战:用 Scikit-learn 构建并评估线性回归与多项式回归模型

【免费下载链接】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 章「回归」第 3 课作业(translations/es/2-Regression/3-Linear/assignment.md,英文原文见 2-Regression/3-Linear/assignment.md)展开:作业要求基于课程学到的线性回归(Linear Regression)多项式回归(Polynomial Regression),自行寻找数据集(或使用 Scikit-learn 内置数据集)构建一个新模型,并在 notebook 中解释技术选型理由、演示模型精度。读完本文,你将掌握完整的作业完成路径:从数据清理、相关性分析,到用 Scikit-learn 训练模型、用 RMSE 与决定系数评估精度,直至对照评分标准自查提交。

作业要求解读

课程作业(Assignment "Create a Regression Model")的核心指令如下:

本课向你展示了如何使用线性回归和多项式回归构建模型。运用所学知识,找一个数据集,或使用 Scikit-learn 内置数据集,构建一个新模型。在你的 notebook 中解释你为什么选择该技术,并演示你模型的精度。如果模型不够精确,请解释原因。

英文原文(2-Regression/3-Linear/assignment.md):

In this lesson you were shown how to build a model using both Linear and Polynomial Regression. Using this knowledge, find a dataset or use one of Scikit-learn's built-in sets to build a fresh model. Explain in your notebook why you chose the technique you did, and demonstrate your model's accuracy. If it is not accurate, explain why.

拆解成可执行的任务清单:

  1. 数据来源二选一:自选公开数据集,或直接使用sklearn.datasets内置数据集(如diabetes等经典回归集)。
  2. 模型构建:运用线性回归与(可选)多项式回归至少一种技术完成训练。
  3. 技术选型论证:在 notebook 中用文字解释「为什么选线性/多项式」,这是作业的评分重点之一。
  4. 精度演示:用测试集评估并展示量化指标。
  5. 失败归因:若精度不理想,必须分析原因(例如数据本身非线性、缺失值、特征不足、相关性过低等)。

评分标准与达标路径

作业自带 Rubric 评分表:

标准优秀(Exemplary)合格(Adequate)需改进(Needs Improvement)
总体要求提交一个完整、文档记录良好的解决方案 notebook解决方案不完整解决方案存在错误或缺陷
CriteriaExemplaryAdequateNeeds Improvement
presents a complete notebook with a well-documented solutionthe solution is incompletethe solution is flawed or buggy

要拿到「优秀」档,notebook 必须同时具备:完整性(含数据探索、训练、评估全流程)与文档化(每个步骤有文字说明,尤其是技术选型理由)。建议在 notebook 中至少包含四个明确小节:数据准备 → 相关性分析 → 模型训练 → 精度评估与结论。

技术背景:为什么先看相关性

课程 2-Regression/3-Linear/README.md 强调,线性回归的目标是拟合一条直线,达到两个目的:展示变量关系对新数据点做预测。其数学基础是最小二乘法(Least-Squares Regression)——对每个数据点测量实际值与回归线之间的垂直距离(残差),将其平方后求和,再寻找使该总和最小的那条"最佳拟合线":

  • 量级优先于方向:平方使 -5 与 +5 的误差同权处理,全部转正;
  • 惩罚离群点:平方赋予大误差更大权重,迫使直线更贴近远离主体的点。

拟合直线可表示为Y = a + bX,其中X是解释变量,Y是因变量,b是斜率,a是截距(即X = 0Y的值)。对应本课南瓜数据问题「按月预测每蒲式耳南瓜价格」,X为价格、Y为销售月份。

相关系数(Correlation Coefficient)是判断线性回归是否可行的第一道关口:散点呈整齐直线排布则相关性高,杂乱分布则相关性低。好的线性回归模型应当具有接近 1(而非 0)的相关系数。作业中选择数据集时,建议先对目标特征做corr()检查——若相关系数接近 0,直接解释"数据缺乏线性关系,因此线性回归不适用",这本身就是合格的失败归因。

数据准备:以南瓜数据集为例

课程使用美国南瓜批发数据集 2-Regression/data/US-pumpkins.csv。完整的数据清洗代码在课程 notebook 2-Regression/3-Linear/notebook.ipynb 中,参考答案见 solution/notebook.ipynb。核心步骤:

  1. 只保留以蒲式耳计价的记录(Package列包含bushel);
  2. 保留关键列(Package、Variety、City Name、Month、Low Price、High Price、Date);
  3. 价格取高低价均值:price = (Low Price + High Price) / 2
  4. 按包装规格折算为每蒲式耳价格:1 1/9蒲式耳纸箱除以 1.1,1/2蒲式耳乘以 2;
  5. 计算DayOfYear(自年初的天数):
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)

清洗后得到类似new_pumpkins的结构(字段:MonthDayOfYearVarietyCityPackageLow PriceHigh PricePrice)。作业中若使用 Scikit-learn 内置数据集(如load_diabetes()),则可跳过这步,但仍建议在 notebook 中先describe()、检查缺失值。

相关性分析:作业的第一步论证

课程在 README.md 中演示了相关性检查(结果与 solution notebook 实测一致):

print(new_pumpkins['Month'].corr(new_pumpkins['Price'])) # ≈ -0.15 print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price'])) # ≈ -0.17

相关性很小,但按品种着色绘制散点后可以发现价格存在多个簇——品种对价格的影响比日期更大。只关注PIE TYPE品种时,DayOfYearPrice的相关系数为-0.27(见 solution/notebook.ipynb),此时训练预测模型才有意义。

对作业的启示:如果自选数据集的相关系数同样很低,就可以在 notebook 中记录这一发现,并据此论证为什么可能需要多项式回归或更多特征,这正是「解释技术选型」的素材。

另外,线性回归对缺失值敏感,训练前必须清理空值:

pie_pumpkins.dropna(inplace=True)

另一种做法是用列均值填充空值。

实现一:简单线性回归

训练模型使用Scikit-learn,核心代码(与课程和 solution notebook 一致):

from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1, 1) y = pie_pumpkins['Price'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) lin_reg = LinearRegression() lin_reg.fit(X_train, y_train)

要点说明:

  • reshape(-1, 1):LinearRegression 要求二维输入,每一行对应一个特征向量;单特征场景需要 N×1 形状的数组。
  • train_test_split(..., test_size=0.2, random_state=0):20% 数据留作测试集,random_state=0保证可复现(作业建议固定随机种子,这也是"文档化"的一部分)。
  • 拟合后通过.coef_读取系数(本案例约-0.017,即价格每天约降 2 美分),通过.intercept_读取截距(约21,即年初价格)。
  • 用测试集预测并计算RMSE(均方根误差)
import numpy as np pred = lin_reg.predict(X_test) rmse = np.sqrt(mean_squared_error(y_test, pred)) print(f'RMSE: {rmse:3.3} ({rmse/np.mean(pred)*100:3.3}%)')
  • 决定系数(coefficient of determination,即 R²)用score获取:
score = lin_reg.score(X_train, y_train) print('Model determination: ', score)

R² 为 0 表示模型退化为"最差线性预测器"(直接输出均值);为 1 表示完美预测。本案例 R² ≈ 0.06~0.07,非常低——这就是作业要求的"如果不精确,请解释原因"的典型场景:仅凭日期一个特征无法解释价格波动。

实现二:多项式回归

当变量间关系并非直线(例如价格在一年内呈抛物线波动、存在最低点)时,可引入多项式回归。Scikit-learn 提供了Pipeline APIsklearn.pipeline.make_pipeline)把数据处理步骤串联成 estimator 链:

from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression()) pipeline.fit(X_train, y_train)

PolynomialFeatures(2)表示加入输入数据的全部二次多项式项:单特征时是DayOfYear²;若有两个输入变量 X、Y,则会生成 X²、XY、Y²。如需更高阶曲线可增大阶数(如 3),但需注意过拟合风险。Pipeline 的用法与LinearRegression完全一致,可fitpredictscore

pred = pipeline.predict(X_test) rmse = np.sqrt(mean_squared_error(y_test, pred)) print(f'RMSE: {rmse:3.3} ({rmse/np.mean(pred)*100:3.3}%)') score = pipeline.score(X_train, y_train) print('Model determination: ', score)

绘制平滑拟合曲线时,应使用np.linspace生成均匀的输入值序列(直接在乱序测试集上连线会得到锯齿线):

X_range = np.linspace(X_test.min(), X_test.max(), 100).reshape(-1, 1) y_range = pipeline.predict(X_range) plt.scatter(X_test, y_test) plt.plot(X_range, y_range)

课程实测:单特征多项式回归的 RMSE 与 R² 相比线性回归仅有微弱提升(RMSE 2.73 vs 2.77,R² 0.08 vs 0.07),说明仅靠日期特征不够,必须引入更多特征。这个"试了多项式但提升有限"的结论本身就是作业里极佳的论证材料。

实现三:引入分类特征(One-Hot 编码)

Variety等列是非数值的分类特征(categorical)。线性回归无法直接使用文本值,需要编码,有两种思路:

  • 简单数值编码:给品种编号后用编号作为数值输入。这对线性回归并不合适——回归会按编号的实际数值乘以系数加进结果,而编号与价格的映射通常非线性。
  • One-Hot 编码:把Variety拆成多个 0/1 列,每列对应一个品种。这样线性回归会为每个品种学习一个独立的"附加价格"系数。

使用 Pandas 的get_dummies即可:

pd.get_dummies(new_pumpkins['Variety'])
X = pd.get_dummies(new_pumpkins['Variety']) y = new_pumpkins['Price']

课程进一步演示了把分类特征与数值特征拼接成完整特征矩阵:

X = pd.get_dummies(new_pumpkins['Variety']) \ .join(new_pumpkins['Month']) \ .join(pd.get_dummies(new_pumpkins['City'])) \ .join(pd.get_dummies(new_pumpkins['Package'])) y = new_pumpkins['Price']

加入CityPackage后,RMSE 降至 2.84(10.5%),R² 提升到 0.94。这是作业中"提升模型精度"的最有效手段,也是应当写进 notebook 的关键步骤。

综合对照:五类模型的结果对比

课程在 README.md 汇总了本课构建的所有模型(数值与 solution notebook 实测一致):

模型RMSE决定系数(R²)
DayOfYear线性2.77(17.2%)0.07
DayOfYear多项式2.73(17.0%)0.08
Variety线性5.24(19.7%)0.77
全部特征线性2.84(10.5%)0.94
全部特征多项式2.23(8.25%)0.97

完整版"全部特征 + 多项式"代码(可直接复用于作业):

# 准备训练数据 X = pd.get_dummies(new_pumpkins['Variety']) \ .join(new_pumpkins['Month']) \ .join(pd.get_dummies(new_pumpkins['City'])) \ .join(pd.get_dummies(new_pumpkins['Package'])) y = new_pumpkins['Price'] # 划分训练/测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # 构建并训练 Pipeline pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression()) pipeline.fit(X_train, y_train) # 预测 pred = pipeline.predict(X_test) # 评估 rmse = mean_squared_error(y_test, pred, squared=False) print(f'RMSE: {rmse:3.3} ({rmse/pred.mean()*100:3.3}%)') score = pipeline.score(X_train, y_train) print('Model determination: ', score)

最终模型的 R² 接近 0.97、RMSE ≈ 2.23(约 8% 预测误差),是本课能达到的最佳结果。作业中建议至少完成一个「简单线性回归 → 多项式/更多特征 → 评估对比」的完整闭环,并记录每一步的 RMSE 与 R²,与上面的基准值形成对照。

作业自查清单

对照 Rubric「优秀」档逐项自查:

  1. notebook 完整:包含数据加载(自选数据或sklearn.datasets内置集)、数据探索、训练、评估全过程;每个代码单元有 Markdown 文字说明。
  2. 技术选型有理由:明确写出"为什么用线性/多项式回归"——例如"相关性分析显示corr ≈ -0.27,存在一定线性关系,故先尝试简单线性回归";若 R² 低,说明"单特征线性关系弱,改用多项式/引入更多特征"。
  3. 精度演示:输出 RMSE(含百分比)与 R² 两个指标,并附测试集散点与回归线的可视化图(线性结果可参考 2-Regression/3-Linear/images/linear-results.png,多项式结果可参考 2-Regression/3-Linear/images/poly-results.png)。
  4. 失败归因:若模型不精确,分析原因(相关性过低、特征不足、数据缺失、非线性关系、过拟合等)并写在 notebook 结论区。

延伸学习:课程 README.md 还建议在学完本课后进一步了解 Stepwise、Ridge、Lasso 与 Elasticnet 等回归技术;本课的 R 语言版本见 solution/R/lesson_3-R.ipynb,可作对比参考。完成本作业后,你将在回归章节的最后一部分接触逻辑回归(Logistic Regression),用于类别预测。

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

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

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

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

立即咨询