ML-For-Beginners 回归实战指南:用 Scikit-learn 对 Linnerud 数据集做单变量回归并绘图
本篇技术指南围绕 ML-For-Beginners 课程「回归(Regression)」模块第 1 课的工具类作业 assignment.md 展开:以 Scikit-learn 内置的 Linnerud 数据集为对象,完整演示如何创建回归模型并绘制"腰围 vs 仰卧起坐次数"等特征与生理指标之间的关系图。读完后,你可以独立复现课程作业的全部技术步骤,掌握数据集加载、训练/测试集划分、线性回归拟合、预测与可视化的标准工作流,并能将该流程推广到数据集中的所有特征-目标组合。
作业原文与考核标准
在动手之前,先完整理解作业要求。该作业位于 2-Regression/1-Tools/assignment.md,标题为 "Regression with Scikit-learn",原文要求如下:
查看 Scikit-learn 中的 Linnerud 数据集。该数据集包含多个 target(目标变量):'It consists of three exercise (data) and three physiological (target) variables collected from twenty middle-aged men in a fitness club'(它由 20 名健身俱乐部中年男性的 3 个运动类数据变量和 3 个生理类目标变量组成)。
用你自己的语言,描述如何创建一个回归模型,绘制腰围(waistline)与完成的仰卧起坐数量(situps)之间的关系。对该数据集中的其他数据点做同样的事情。
作业的评分标准(Rubric)原文为:
| Criteria | Exemplary(优秀) | Adequate(合格) | Needs Improvement(待改进) |
|---|---|---|---|
| Submit a descriptive paragraph(提交一段描述) | Well-written paragraph is submitted(提交了撰写良好的段落) | A few sentences are submitted(只提交了几句话) | No description is supplied(未提供描述) |
由此可见,作业考核的核心产出是一段你自己撰写的描述性文字,说明如何为每一组"运动量-生理指标"关系建立回归模型并绘图。下面从数据、代码两个层面,把这段话"写出来、跑出来"。
课程背景:本作业在回归模块中的位置
该作业是 2-Regression/1-Tools/README.md 所授"工具与上手"一课的课后练习。这一课的目标是:
- 配置本地机器学习开发环境(Python、虚拟环境、Visual Studio Code);
- 使用 Jupyter Notebook(
.ipynb文件)进行交互式建模; - 安装并上手 Scikit-learn;
- 通过动手练习完成第一个线性回归实验(课程以内置 diabetes 数据集为例,完成了 BMI 与疾病进展指标的回归绘图)。
课程提供的练习骨架是 2-Regression/1-Tools/notebook.ipynb(空白笔记本),参考答案见 solution/notebook.ipynb。本作业则把同样的工作流迁移到另一个更小的内置数据集 Linnerud 上——样本更少、目标变量有多个,因此对"多目标回归"的表述要求更高。
上图是课程主实验(diabetes 数据集,BMI 对疾病进展)的运行结果截图,出自 README 中 "your first Scikit-learn notebook" 练习:黑色散点为测试集数据,蓝色粗线为 LinearRegression 模型对测试集输入的预测值连线。Linnerud 作业的绘图逻辑与此完全一致,只是数据换成 20 名受试者的运动与生理指标。
Linnerud 数据集:结构与 Scikit-learn 加载方式
Scikit-learn 提供 sklearn.datasets.load_linnerud() 加载该数据集。根据作业引用与 Scikit-learn 官方文档的说明,其结构为:
- 样本量:20 个样本(20 名健身俱乐部的中年男性);
- 特征(data,3 列):3 个运动类变量——仰卧起坐次数(situps)、纵跳/跳跃(jumps)、折返跑(quests);
- 目标(target,3 列):3 个生理类变量——腰围(waist,英寸)、脉搏(pulses,次/分钟)、胆固醇(cholesterol,mg/dl)。
加载代码:
import matplotlib.pyplot as plt
from sklearn import datasets, linear_model, model_selection
linnerud = datasets.load_linnerud()
X = linnerud.data # 形状 (20, 3):situps, quests, jumps
y = linnerud.target # 形状 (20, 3):waist, pulses, cholesterol
print(X.shape) # (20, 3)
print(y.shape) # (20, 3)
与课程主实验中 load_diabetes(return_X_y=True) 返回二维数值矩阵不同,Linnerud 的 target 本身就是一组并列的 3 个回归目标。这正是作业要求"描述如何对每一个数据点组合建模"的原因:你需要为 3 个运动特征 × 3 个生理目标组成的多组关系,分别建立单变量回归模型。
核心实操:绘制"腰围 vs 仰卧起坐"的回归关系
下面按照课程 solution 笔记本 中演示的标准五步(加载 → 拆分 → 拟合 → 预测 → 绘图)实现作业要求的主图。
1. 选出腰围与仰卧起坐两列
腰围是 target 的第 0 列,仰卧起坐是 data 的第 0 列。注意 Scikit-learn 的回归器要求输入 X 为二维数组,因此需要用 reshape(-1, 1) 把一维向量还原为列向量(课程 README 中对 diabetes 数据集选取第 3 列时使用了同样的技巧:X = X[:, 2] 加 X.reshape((-1,1))):
X_situps = linnerud.data[:, 0].reshape(-1, 1) # (20, 1)
y_waist = linnerud.target[:, 0] # (20,)
2. 划分训练集与测试集
沿用课程中的 model_selection.train_test_split(参考 solution 笔记本中的调用 train_test_split(X, y, test_size=0.33)):
X_train, X_test, y_train, y_test = model_selection.train_test_split(
X_situps, y_waist, test_size=0.33)
从源码用法看,test_size=0.33 表示约三分之一样本划入测试集。Linnerud 只有 20 个样本,划出 33% 后测试集约 7 个样本、训练集约 13 个样本——样本极少,这直接决定了该模型只能用于教学演示层面的关系观察,而非严谨的统计推断(这一点建议在作业描述中如实写出)。
3. 拟合线性回归模型
model = linear_model.LinearRegression()
model.fit(X_train, y_train)
model.fit() 是 Scikit-learn(以及 TensorFlow 等库)通用的训练入口;solution 笔记本中执行该调用后返回的估计器表示即为 LinearRegression()。
4. 对测试集做预测
y_pred = model.predict(X_test)
5. 散点 + 预测线绘图
完全复用课程 diabetes 实验的绘图模式:
plt.scatter(X_test, y_test, color='black')
plt.plot(X_test, y_pred, color='blue', linewidth=3)
plt.xlabel('Sit-ups (number)')
plt.ylabel('Waist (inches)')
plt.title('Linnerud: Waist vs. Sit-ups')
plt.show()
黑色散点是测试集真实数据,蓝色直线是模型对同一批 X 的预测值连成的拟合线。作业要求你用自己的语言解释这张图:例如"直线穿过了散点云,给定一个新样本的仰卧起坐次数,把它的横坐标代入这条直线,就能读出模型预测的腰围数值"。
推广到其余数据点:覆盖全部 3 × 3 组合
作业的后半句是"对该数据集中的其他数据点做同样的事情",即还要覆盖 quests、jumps 与 pulses、cholesterol 等组合。可以用双重循环把上述流程推广到全部组合:
feature_names = ['situps', 'quests', 'jumps']
target_names = ['waist', 'pulses', 'cholesterol']
for fi, fname in enumerate(feature_names):
for ti, tname in enumerate(target_names):
X_f = linnerud.data[:, fi].reshape(-1, 1)
y_t = linnerud.target[:, ti]
X_train, X_test, y_train, y_test = model_selection.train_test_split(
X_f, y_t, test_size=0.33)
model = linear_model.LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
plt.figure()
plt.scatter(X_test, y_test, color='black')
plt.plot(X_test, y_pred, color='blue', linewidth=3)
plt.xlabel(fname)
plt.ylabel(tname)
plt.title(f'Linnerud: {tname} vs. {fname}')
plt.show()
对每一组,作业描述段落中应说明三件事:
- 选列方式:
data[:, i]取第 i 个运动特征、target[:, j]取第 j 个生理目标,并用reshape(-1, 1)保证二维输入; - 建模流程:
train_test_split(test_size=0.33)→LinearRegression().fit(X_train, y_train)→predict(X_test)→plt.scatter+plt.plot; - 结果解读:直线斜率方向(正相关/负相关)反映该运动量与生理指标的直观关系,但 20 个样本、约 7 个测试点意味着拟合线对单点波动敏感,结论只宜作定性观察。
如果你愿意多走一步,LinearRegression 拟合后还可以读取 model.coef_ 与 model.intercept_ 属性,把每组关系的斜率与截距写进描述段落,让"用自己的语言描述"有具体数字支撑(注意:不要在作业中虚构未运行的数值,以实际运行为准)。
环境要求与运行前提
- 需要 Python 3+,并已安装 Scikit-learn、matplotlib(课程 README 建议在虚拟环境中安装,M1 Mac 有专门的安装说明指引);
- 作业在本课程文件夹的 notebook.ipynb 中完成,用 Visual Studio Code 打开后 Jupyter 内核会自动启动,代码块点"播放"图标即可执行,
md图标可添加 markdown 说明; - 课程同时提供 R 语言的对照版本,见 solution/R/lesson_1.html,可作为跨语言对照阅读。
自检清单:提交作业前的核对
- 是否用一句话说明了 Linnerud 数据集的来源与结构(20 名中年男性、3 运动特征、3 生理目标);
- 是否完整给出"选列 → 拆分(
test_size=0.33)→fit→predict→ 散点+直线绘图"的代码流程,并至少展示了 waist vs situps 一张图; - 是否用循环或分步说明覆盖了其余特征-目标组合,而不是只画了一张图;
- 描述段落是否达到 Rubric 中 "Exemplary" 档(一段撰写良好的完整描述,而非零散几句话),并如实注明小样本下的解释边界;
- 对照课程 diabetes 实验 与 solution 笔记本 确认
fit、predict、train_test_split的调用方式与课程一致。
完成以上步骤,即同时满足了作业的两层要求:可运行的回归建模代码,以及一段能讲清"如何为 Linnerud 数据集每一组关系创建回归模型并绘图"的描述性文字。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
