摘要:线性回归是机器学习最基础也最重要的算法。它用一条直线(或高维平面)拟合数据,通过最小化预测值与真实值之间的误差来"学习"。虽然简单,但它是理解所有更复杂算法(从逻辑回归到深度学习)的起点。这篇文章讲清楚线性回归的原理、求解方法、评估指标和正则化。


一、什么是线性回归?

回归问题

机器学习中,回归(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 最常用的回归损失函数,放大较大误差
最小二乘法 一步求出最优参数的解析解法
梯度下降 逐步逼近最优解的迭代解法
模型解释了多大比例的数据方差
正则化 通过惩罚大权重防止过拟合

核心三句话

  1. 线性回归是最简单的"学习"方式——从数据中找到特征和目标之间的线性关系
  2. 它的思想贯穿整个 ML/DL——损失函数、梯度下降、正则化都是从这里开始的
  3. 不要因为它简单就低估它——在大量实际问题中,线性回归是一个强 baseline,甚至是最好的选择

下一篇文章:当目标不再是连续值,而是"是/否"——逻辑回归

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐