线性回归:从零理解“预测“
摘要:线性回归是机器学习最基础也最重要的算法。它用一条直线(或高维平面)拟合数据,通过最小化预测值与真实值之间的误差来"学习"。虽然简单,但它是理解所有更复杂算法(从逻辑回归到深度学习)的起点。这篇文章讲清楚线性回归的原理、求解方法、评估指标和正则化。
一、什么是线性回归?
回归问题
机器学习中,回归(Regression) 是指预测连续值的任务。
| 问题类型 | 输出 | 例子 |
|---|---|---|
| 回归 | 连续值 | 预测房价(50 万、120 万...) |
| 分类 | 离散类别 | 判断是否买房(是/否) |
线性回归就是回归问题中最基础的方法。
一个生活场景
假设你要出租一套房子,想知道应该定多少租金。你收集了附近已出租房子的数据:
面积 (m²) → 月租金 (元)
50 3000
70 4200
90 5100
110 6000
... ...
肉眼一看,面积越大租金越高,大致是一条直线关系。
线性回归要做的就是:找到一条最"合适"的直线,让它能根据面积预测租金。
租金 ↑
│ ●
6000│ ●
5000│ ●
4000│ ●
3000│ ●
└──────────────────→ 面积
50 70 90 110
直线方程:租金 = w × 面积 + b
二、数学形式
一元线性回归
当只有一个特征时,线性回归就是一条直线:
y = w × x + b
其中:
y = 预测值(租金)
x = 特征(面积)
w = 权重/斜率(面积每增加 1m²,租金增加多少)
b = 偏置/截距(面积为 0 时的基础租金)
多元线性回归
当有多个特征时,线性回归变成高维空间中的一个"超平面":
y = w₁x₁ + w₂x₂ + ... + wₙxₙ + b
例如预测房价:
房价 = w₁×面积 + w₂×卧室数 + w₃×楼层 + w₄×房龄 + b
用向量表示更简洁:
y = w · x + b
或写成更紧凑的形式(把 b 并入 w):
y = w^T x
线性回归的"线性"到底指什么?
线性指的不是输入特征之间的关系,而是参数 w 和输出 y 之间的关系。
✅ y = w₁x₁ + w₂x₂² + b ← 虽然 x₂² 是二次的,但对参数 w 是线性的 → 线性回归
❌ y = w₁x₁ + e^(w₂x₂) ← 对参数 w₂ 不是线性的 → 非线性回归
这意味着我们可以用 x^2、sin(x) 等变换后的特征做线性回归——这就是多项式回归的本质。
三、求解:如何找到"最合适"的直线?
损失函数:定义什么是"好"
要找到最好的 w 和 b,首先需要定义"好"的标准。最常用的标准是均方误差(MSE):
MSE = (1/N) × Σ(y_true_i - y_pred_i)²
N = 样本数量
y_true_i = 第 i 个样本的真实值
y_pred_i = 第 i 个样本的预测值
为什么用平方而不是绝对值?
| 误差度量 | 公式 | 特点 |
|---|---|---|
| MSE(均方误差) | Σ(y - ŷ)² | 放大大误差,数学性质好(可导) |
| MAE(平均绝对误差) | Σ|y - ŷ| | 对大误差不那么敏感,鲁棒性更强 |
MSE 对"大误差"的惩罚远大于 MAE——一个偏离 10 个单位的点,在 MSE 中贡献 100 的误差,在 MAE 中只贡献 10。
求解方法 1:最小二乘法(解析解)
对于线性回归,MSE 损失函数是凸函数——意味着有一个全局最优解,可以用公式直接计算:
w = (X^T X)^{-1} X^T y
这就是"最小二乘法"(Ordinary Least Squares, OLS)
优点:一步到位,不需要迭代
缺点:当特征数量很大(>10万)或 X^T X 不可逆时无法使用
求解方法 2:梯度下降(迭代解)
当特征太多或数据量太大时,用梯度下降逐步逼近最优解:
# 伪代码:梯度下降求解线性回归
w = [0, 0, ..., 0] # 初始化
learning_rate = 0.01
for step in range(1000):
# 预测
y_pred = X @ w
# 计算梯度(MSE 对 w 的导数)
gradient = (2/N) × X^T × (y_pred - y_true)
# 更新参数
w = w - learning_rate × gradient
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 最小二乘法 | 一步求解,精确 | 计算复杂度 O(n³) | 特征数 < 1万 |
| 梯度下降 | 可扩展到大数据 | 需要调学习率 | 特征数 > 1万或数据量极大 |
四、评估指标
训练好模型后,如何知道它"好"还是"不好"?
R²(决定系数)
最常用的回归评估指标。范围 (-∞, 1],越接近 1 越好。
R² = 1 - Σ(y_true - y_pred)² / Σ(y_true - ȳ)²
解读:
R² = 0.85 → 模型解释了 85% 的数据方差
R² = 0 → 模型和直接用平均值预测一样好
R² < 0 → 模型比瞎猜还差
其他指标
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
y_true = [3.0, 5.0, 2.5, 7.0]
y_pred = [2.8, 5.1, 2.2, 7.3]
mse = mean_squared_error(y_true, y_pred) # 均方误差
mae = mean_absolute_error(y_true, y_pred) # 平均绝对误差
r2 = r2_score(y_true, y_pred) # 决定系数
print(f"MSE = {mse:.3f}") # 0.045
print(f"MAE = {mae:.3f}") # 0.175
print(f"R² = {r2:.3f}") # 0.973
五、过拟合与正则化
线性回归也会过拟合?
当特征很多时(比如用 x, x², x³, ..., x^{20} 做多项式回归),线性回归可以拟合非常复杂的曲线——但很容易过拟合。
欠拟合(太简单) 正常拟合 过拟合(太复杂)
│ │ │
│ ● │ ● │ ●
│ ● │ ● ● │ ● ● ●
│● ● │ ● ● ●│● ● ● ● ●
│ ● │● ● ●│ ● ●
└───── └───── └─────
模型太简单 刚刚好 模型记住了每个点
误差大 泛化好 新数据表现差
岭回归(Ridge Regression):L2 正则化
在损失函数中加入权重平方和的惩罚,迫使模型使用小权重:
L = MSE + λ × Σ(w_i²)
λ 是正则化强度(超参数):
λ = 0 → 普通线性回归(可能过拟合)
λ = 0.1 → 轻微正则化
λ = 10 → 强正则化(可能欠拟合)
为什么小权重更好?小权重意味着模型对特征的微小变化不敏感——输出的预测更平滑、更稳定。
Lasso 回归:L1 正则化
用权重绝对值之和替换平方和:
L = MSE + λ × Σ|w_i|
L1 正则化的特殊效果:
→ 不重要的特征的权重会被精确压缩到 0
→ 相当于自动做"特征选择"
正则化方法对比
| 方法 | 惩罚项 | 效果 | 适用场景 |
|---|---|---|---|
| 普通线性回归 | 无 | 无特征选择 | 特征少、数据充足 |
| 岭回归(Ridge) | L2: Σw² | 所有特征权重变小但不为零 | 特征相关性强 |
| Lasso | L1: Σ|w| | 不相关特征权重变为 0 | 特征很多,需要特征选择 |
| ElasticNet | L1 + L2 混合 | 兼顾两者 | 特征多且相关 |
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np
# 生成示例数据
np.random.seed(42)
X = np.random.randn(200, 10)
y = X[:, 0] * 2 + X[:, 1] * 1.5 + np.random.randn(200) * 0.3
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 标准化(对正则化方法很重要)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 普通线性回归
lr = LinearRegression()
lr.fit(X_train_scaled, y_train)
print(f"LinearRegression R²: {lr.score(X_test_scaled, y_test):.3f}")
# 岭回归
ridge = Ridge(alpha=1.0) # alpha = λ
ridge.fit(X_train_scaled, y_train)
print(f"Ridge R²: {ridge.score(X_test_scaled, y_test):.3f}")
# Lasso(会压缩部分特征权重到 0)
lasso = Lasso(alpha=0.1)
lasso.fit(X_train_scaled, y_train)
print(f"Lasso R²: {lasso.score(X_test_scaled, y_test):.3f}")
print(f"Lasso 非零权重数: {np.sum(lasso.coef_ != 0)} / 10")
六、sklearn 完整代码示例
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
# ===== 1. 生成示例数据 =====
np.random.seed(42)
X = np.random.rand(100, 1) * 10 # 面积:0-10
y = 2.5 * X.squeeze() + 5 + np.random.randn(100) * 1.5 # 租金 = 2.5×面积 + 5 + 噪声
# ===== 2. 划分数据集 =====
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# ===== 3. 训练模型 =====
model = LinearRegression()
model.fit(X_train, y_train)
# ===== 4. 查看参数 =====
w = model.coef_[0]
b = model.intercept_
print(f"学习到的关系: y = {w:.3f}x + {b:.3f}")
# 应该接近: y = 2.500x + 5.000(与真实生成关系一致)
# ===== 5. 预测与评估 =====
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"MSE = {mse:.3f}")
print(f"R² = {r2:.3f}")
# ===== 6. 可视化 =====
plt.figure(figsize=(8, 5))
plt.scatter(X_train, y_train, alpha=0.5, label='训练数据')
plt.scatter(X_test, y_test, alpha=0.5, label='测试数据', c='orange')
plt.plot(X_test, y_pred, 'r-', linewidth=2, label='预测线')
plt.xlabel('面积')
plt.ylabel('租金')
plt.legend()
plt.title(f'线性回归: y = {w:.2f}x + {b:.2f}, R² = {r2:.3f}')
plt.grid(True, alpha=0.3)
plt.show()
输出示例:
学习到的关系: y = 2.487x + 5.132
MSE = 2.113
R² = 0.948
七、线性回归与深度学习的联系
线性回归是理解深度学习的基础,两者之间存在直接的联系:
# 线性回归
y = w₁x₁ + w₂x₂ + ... + b
# 神经网络的一个神经元(不带激活函数)
y = σ(w₁x₁ + w₂x₂ + ... + b)
↑ 激活函数(如 ReLU)
# 没有激活函数时,一个神经元 = 线性回归
# 多个神经元组合 → 非线性 → 深度学习
| 概念 | 线性回归 | 深度学习中的对应 |
|---|---|---|
| 权重 w | 特征的重要性 | 神经网络中的连接权重 |
| 偏置 b | 截距 | 偏置项 |
| MSE 损失 | 回归损失 | 回归任务的常见损失 |
| 梯度下降 | 训练方法之一 | 深度学习的默认训练方法 |
| 正则化 | Ridge/Lasso | Weight Decay |
八、线性回归的假设与局限
四个基本假设
1. 线性关系:特征和目标之间存在线性关系
→ 检查方法:画残差图(残差应随机分布)
2. 误差独立:样本之间的误差互不相关
→ 时间序列数据中常违反(今天的误差和昨天的误差有关)
3. 同方差性:误差的方差在不同预测值下相同
→ 如果方差变化,说明模型在某些区域表现差
4. 无多重共线性:特征之间不高度相关
→ 如"房间数"和"面积"高度相关,会导致权重估计不稳定
什么时候该用线性回归?
| ✅ 适合 | ❌ 不适合 |
|---|---|
| 特征和目标关系近似线性 | 强非线性关系 |
| 需要可解释性("面积每增加 1m² 租金涨 50 元") | 特征之间有复杂交互 |
| 作为 baseline(所有复杂模型的起点) | 高维稀疏数据(文本、图像) |
| 数据量较小 | 极度复杂的模式 |
九、总结
| 概念 | 一句话 |
|---|---|
| 线性回归 | 用一条直线(或高维平面)拟合数据 |
| MSE | 最常用的回归损失函数,放大较大误差 |
| 最小二乘法 | 一步求出最优参数的解析解法 |
| 梯度下降 | 逐步逼近最优解的迭代解法 |
| R² | 模型解释了多大比例的数据方差 |
| 正则化 | 通过惩罚大权重防止过拟合 |
核心三句话:
- 线性回归是最简单的"学习"方式——从数据中找到特征和目标之间的线性关系
- 它的思想贯穿整个 ML/DL——损失函数、梯度下降、正则化都是从这里开始的
- 不要因为它简单就低估它——在大量实际问题中,线性回归是一个强 baseline,甚至是最好的选择
下一篇文章:当目标不再是连续值,而是"是/否"——逻辑回归。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)