线性回归详解与实战——用体重和年龄预测血压收缩值
一、前言
线性回归是机器学习中最基础的回归算法,也是入门机器学习必须掌握的第一个回归模型。它的思想简单直观:找到一条直线(或超平面),让所有数据点尽可能靠近这条线。
本文将从原理介绍、API 参数详解、代码实战三个层面,带你完整掌握线性回归。
二、线性回归介绍
2.1 什么是线性回归?
线性回归是一种通过线性组合特征变量来预测目标变量的方法。简单来说,就是找到特征与目标之间的线性关系。
一元线性回归(一个特征):
y = w x + b y = wx + b y=wx+b
多元线性回归(多个特征):
y = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + b y = w_1 x_1 + w_2 x_2 + \cdots + w_n x_n + b y=w1x1+w2x2+⋯+wnxn+b
其中:
- y y y 是目标变量(要预测的值)
- x 1 , x 2 , ⋯ , x n x_1, x_2, \cdots, x_n x1,x2,⋯,xn 是特征变量
- w 1 , w 2 , ⋯ , w n w_1, w_2, \cdots, w_n w1,w2,⋯,wn 是回归系数(权重)
- b b b 是截距(偏置项)
2.2 线性回归的应用场景
线性回归广泛应用于:
| 领域 | 应用场景 |
|---|---|
| 医疗 | 根据体重、年龄预测血压 |
| 经济 | 根据利率、GDP预测房价 |
| 教育 | 根据学习时间、出勤率预测成绩 |
| 销售 | 根据广告投入预测销售额 |
| 农业 | 根据降雨量、施肥量预测产量 |
2.3 损失函数:最小二乘法
线性回归的目标是找到最优的 w w w 和 b b b,使得预测值与实际值之间的误差最小。使用**均方误差(MSE)**作为损失函数:
L o s s = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 Loss = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 Loss=n1i=1∑n(yi−y^i)2
其中 y ^ i \hat{y}_i y^i 是预测值, y i y_i yi 是实际值。通过最小二乘法求解最优参数。
2.4 模型评估指标
| 指标 | 说明 |
|---|---|
| R²(决定系数) | 模型解释了目标变量变异的百分比,范围 0~1,越接近1越好 |
| 相关系数 r | 特征与目标之间的线性相关程度,范围 -1~1 |
R² 的解读:
- R² = 1:完美预测
- R² > 0.8:模型拟合良好
- R² < 0.5:模型拟合较差
三、线性回归 API 介绍
3.1 sklearn 中的 LinearRegression
from sklearn.linear_model import LinearRegression
class sklearn.linear_model.LinearRegression(
fit_intercept=True,
normalize=False,
copy_X=True,
n_jobs=None
)
3.2 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fit_intercept | bool | True | 是否计算截距项。如果为 False,则直线过原点(截距为0) |
normalize | bool | False | 是否对数据进行归一化。如果 fit_intercept=False,则此参数被忽略 |
copy_X | bool | True | 是否对 X 进行复制。如果选 False,则直接对原数据进行覆盖(即经过中心化、标准化后,是否把新数据覆盖到原数据上) |
n_jobs | int | None | 计算时设置的任务个数。如果选择 -1 则代表使用所有的 CPU。对于目标个数 >1(n_targets > 1)且足够大规模的问题有加速作用 |
3.3 属性(返回值)
| 属性 | 说明 |
|---|---|
coef_ | 回归系数。对于单目标问题返回一维数组 (n_features,);多目标问题返回二维数组 (n_targets, n_features) |
intercept_ | 线性模型中的截距项(独立项) |
3.4 常用方法
| 方法 | 说明 |
|---|---|
fit(X, y) | 对训练集 X, y 进行训练,拟合模型 |
predict(X) | 使用训练得到的模型对输入 X 进行预测(X 可以是测试集,也可以是需要预测的新数据) |
score(X, y) | 预测效果评分,返回 R² 决定系数 |
3.5 API 使用模板
from sklearn.linear_model import LinearRegression
# 1. 创建模型
model = LinearRegression()
# 2. 训练模型
model.fit(X_train, y_train)
# 3. 查看回归系数和截距
print("回归系数:", model.coef_)
print("截距:", model.intercept_)
# 4. 预测
predictions = model.predict(X_test)
# 5. 评估
score = model.score(X_test, y_test)
print("R²:", score)
四、代码实战:预测血压收缩值
4.1 场景描述
我们有一组医疗数据,包含 13 个样本的体重、年龄和血压收缩值。目标是通过体重和年龄来预测血压收缩值。
4.2 数据概览
数据预览:
| 体重(kg) | 年龄(岁) | 血压收缩(mmHg) |
|---|---|---|
| 76.0 | 50 | 120 |
| 91.5 | 20 | 141 |
| 85.5 | 20 | 124 |
| 82.5 | 30 | 126 |
| 79.0 | 30 | 117 |
| 80.5 | 50 | 125 |
| 74.5 | 60 | 123 |
| 79.0 | 50 | 125 |
| 85.0 | 40 | 132 |
| 76.5 | 55 | 123 |
| 82.0 | 40 | 132 |
| 95.0 | 40 | 155 |
| 92.5 | 20 | 147 |
数据统计描述:
| 统计量 | 体重 | 年龄 | 血压收缩 |
|---|---|---|---|
| 样本数 | 13 | 13 | 13 |
| 均值 | 83.04 | 38.85 | 130.00 |
| 标准差 | 6.58 | 13.87 | 11.22 |
| 最小值 | 74.50 | 20.00 | 117.00 |
| 最大值 | 95.00 | 60.00 | 155.00 |
4.3 完整代码
import pandas as pd
from sklearn.linear_model import LinearRegression
# 第一步:导入数据
data = pd.read_csv("多元线性回归.csv", encoding="gbk", engine='python')
# 打印相关系数矩阵
corr = data[["体重", "年龄", "血压收缩"]].corr()
print(corr)
# 第二步:估计模型参数,建立回归模型
lr_model = LinearRegression()
x = data[["体重", "年龄"]]
y = data["血压收缩"]
lr_model.fit(x, y) # 训练模型
# 第三步:对回归模型进行检验
score = lr_model.score(x, y)
print(score)
print(lr_model.predict(x))
4.4 代码逐行解析
第一步:导入数据
import pandas as pd
from sklearn.linear_model import LinearRegression
data = pd.read_csv("多元线性回归.csv", encoding="gbk", engine='python')
pandas用于数据读取和处理LinearRegression是 sklearn 中的线性回归类encoding="gbk"因为 CSV 文件是 GBK 编码(含中文列名)engine='python'使用 Python 引擎解析(支持非标准 CSV 格式)
第二步:查看相关系数矩阵
corr = data[["体重", "年龄", "血压收缩"]].corr()
print(corr)
运行结果:
体重 年龄 血压收缩
体重 1.000000 -0.700283 0.906402
年龄 -0.700283 1.000000 -0.382773
血压收缩 0.906402 -0.382773 1.000000
解读:
- 体重与血压收缩的相关系数为 0.906,高度正相关,说明体重越大血压越高
- 年龄与血压收缩的相关系数为 -0.383,弱负相关(可能与样本量小有关)
- 体重与年龄的相关系数为 -0.700,存在一定共线性
第三步:建立回归模型
lr_model = LinearRegression()
x = data[["体重", "年龄"]] # 特征变量(二维 DataFrame)
y = data["血压收缩"] # 目标变量(一维 Series)
lr_model.fit(x, y) # 训练模型
x必须是二维结构(DataFrame),即使是单特征也需要data[["列名"]]y是一维结构(Series)fit()方法执行最小二乘法计算回归系数
第四步:模型检验与预测
score = lr_model.score(x, y)
print(score) # R² 决定系数
print(lr_model.predict(x)) # 对训练数据进行预测
4.5 运行结果
模型结果:
===== 模型结果 =====
R²决定系数: 0.9461
回归系数 (体重): 2.1366
回归系数 (年龄): 0.4002
截距 (intercept_): -62.9634
回归方程: 血压收缩 = 2.1366 × 体重 + 0.4002 × 年龄 + (-62.9634)
回归方程解读:
- 体重每增加 1kg,血压收缩值上升约 2.14 mmHg
- 年龄每增加 1岁,血压收缩值上升约 0.40 mmHg
- R² = 0.9461,说明模型解释了 94.61% 的血压变异,拟合效果优秀
预测结果对比:
| 样本 | 实际血压收缩值 | 预测值 | 误差 |
|---|---|---|---|
| 1 | 120 | 119.43 | 0.57 |
| 2 | 141 | 140.54 | 0.46 |
| 3 | 124 | 127.72 | 3.72 |
| 4 | 126 | 125.31 | 0.69 |
| 5 | 117 | 117.83 | 0.83 |
| 6 | 125 | 129.04 | 4.04 |
| 7 | 123 | 120.22 | 2.78 |
| 8 | 125 | 125.84 | 0.84 |
| 9 | 132 | 134.65 | 2.65 |
| 10 | 123 | 122.50 | 0.50 |
| 11 | 132 | 128.24 | 3.76 |
| 12 | 155 | 156.02 | 1.02 |
| 13 | 147 | 142.67 | 4.33 |
预测新数据:
体重80kg, 年龄35岁 -> 预测血压收缩: 121.97
体重70kg, 年龄25岁 -> 预测血压收缩: 96.60
4.6 数据可视化

图表解读:
- 左图:体重与血压收缩高度正相关(r=0.906),散点紧密围绕回归线
- 中图:年龄与血压收缩呈弱负相关(r=-0.383),散点分散
- 右图:实际值与预测值高度吻合(R²=0.9461),点几乎落在对角线上
五、线性回归完整流程总结
收集数据 → 探索性分析(相关系数) → 建立模型(fit) → 模型评估(score) → 预测(predict)
| 步骤 | 代码 | 说明 |
|---|---|---|
| 1. 导入数据 | pd.read_csv() | 读取 CSV 文件 |
| 2. 相关分析 | .corr() | 查看特征与目标的相关性 |
| 3. 创建模型 | LinearRegression() | 初始化线性回归模型 |
| 4. 训练模型 | .fit(x, y) | 最小二乘法拟合参数 |
| 5. 模型评估 | .score(x, y) | 返回 R² 决定系数 |
| 6. 预测 | .predict(x_new) | 对新数据进行预测 |
六、线性回归优缺点
优点
- 思想简单,易于理解和实现
- 计算速度快,训练效率高
- 可解释性强,回归系数直接反映特征重要性
- 是许多复杂算法的基础(如岭回归、Lasso回归、神经网络)
缺点
- 假设线性关系:只能拟合线性关系,非线性关系需要多项式扩展
- 对异常值敏感:离群点会大幅影响回归线
- 多重共线性问题:特征之间高度相关时,回归系数不稳定
- 特征独立性假设:假设特征之间相互独立
七、注意事项
7.1 特征矩阵 X 的维度
# ✅ 正确:x 是二维 DataFrame
x = data[["体重", "年龄"]] # 形状 (13, 2)
# ❌ 错误:x 是一维 Series
x = data["体重"] # 形状 (13,)
7.2 编码问题
中文 CSV 文件需要注意编码:
# GBK 编码(Windows 中文环境常见)
data = pd.read_csv("文件.csv", encoding="gbk", engine='python')
# UTF-8 编码
data = pd.read_csv("文件.csv", encoding="utf-8")
7.3 R² 的解读
- R² 是模型在训练集上的拟合程度,不代表泛化能力
- 应将数据分为训练集和测试集来评估泛化性能
- R² 可以为负值(当模型比均值预测还差时)
参考资料:
- scikit-learn 官方文档:LinearRegression
- 《机器学习》—— 周志华

711

被折叠的 条评论
为什么被折叠?



