线性回归
目标读者: 机器学习初学者 核心内容: 线性模型、损失函数、梯度下降、正则化 前置知识: 机器学习基础概念、线性代数、微积分
1. 核心思想
目标:找到一条直线(或超平面),最好地拟合数据点。
向量形式:
其中:
- :输入特征矩阵
- :权重向量
- :预测值
2. 损失函数:均方误差 (MSE)
目标:最小化预测值与真实值之间的平方差
为什么用平方?
- 数学上易于求导
- 惩罚大误差
- 与高斯噪声假设下的最大似然估计等价
3. 求解方法
3.1 正规方程(解析解)
直接令梯度为零,求解闭式解:
得到:
| 优点 | 缺点 |
|---|---|
| 一步到位,无需迭代 | 复杂度,特征多时慢 |
| 直接得到最优解 | 需要矩阵可逆 |
代码示例:
import numpy as np
# 正规方程求解
w = np.linalg.inv(X.T @ X) @ X.T @ y3.2 梯度下降(迭代优化)
思想:沿着梯度的反方向,逐步逼近最优解
MSE 的梯度:
三种梯度下降变体:
| 变体 | 每次用多少数据 | 特点 |
|---|---|---|
| 批量 (BGD) | 全部数据 | 稳定但慢 |
| 随机 (SGD) | 1 个样本 | 快但震荡 |
| 小批量 | mini-batch | 折中,最常用 |
代码示例:
def gradient_descent(X, y, learning_rate=0.01, epochs=1000):
m, n = X.shape
w = np.zeros(n)
for _ in range(epochs):
gradient = -2/m * X.T @ (y - X @ w)
w = w - learning_rate * gradient
return w3.3 学习率的影响
学习率太大 学习率合适 学习率太小
× ↘ .
/ \ ↘ .
/ \ ↘ .
/ \ 震荡发散 ↘ 快速收敛 ...... 收敛太慢
选择学习率的经验:
- 从 0.01 或 0.001 开始
- 观察 loss 曲线,根据震荡/收敛速度调整
- 使用学习率衰减策略
4. 正则化:防止过拟合
4.1 为什么需要正则化?
当特征数量接近或超过样本数量时,模型容易过拟合。正则化通过限制权重大小来降低模型复杂度。
4.2 L2 正则化(Ridge 回归)
闭式解:
特点:
- 权重变小,但不会变成 0
- 对多重共线性有很好的处理效果
- 越大,正则化越强
4.3 L1 正则化(Lasso 回归)
特点:
- 产生稀疏解:部分权重会变成 0
- 自动进行特征选择
- 没有闭式解,需要迭代优化
4.4 弹性网 (ElasticNet)
结合 L1 和 L2 的优点:
4.5 正则化对比
| 方法 | 惩罚项 | 解的特点 | 适用场景 |
|---|---|---|---|
| Ridge | 权重缩小 | 所有特征都有用 | |
| Lasso | 稀疏(部分为0) | 只有部分特征重要 | |
| ElasticNet | L1 + L2 | 兼顾 | 特征多且相关性高 |
5. 几何直观
5.1 损失函数的等高线
w2
│
│ ╭───╮
│ ╭╯ ╰╮
│ ╭╯ ✕ ╰╮ ← 最优解
│ ╰╮ ╭╯
│ ╰╮ ╭╯
│ ╰───╯
└────────────→ w1
- 椭圆是损失函数的等高线
- 梯度下降沿着垂直于等高线的方向移动
- 最优解在椭圆中心
5.2 正则化的几何解释
Ridge (L2) Lasso (L1)
w2 w2
│ ╭──╮ │ /\
│ ╱ ╲ │/ \
├● ╲ ← 约束区域 ├● ← 更容易在角上
│ ╲ ╱ │\ /
│ ╰──╯ │ \/
└─────→ w1 └─────→ w1
- L2 约束是圆形,解不容易落在坐标轴上
- L1 约束是菱形,解更容易落在角上(即某些 )
6. Scikit-learn 实践
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# 准备数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 普通线性回归
lr = LinearRegression()
lr.fit(X_train, y_train)
# Ridge 回归
ridge = Ridge(alpha=1.0) # alpha 就是 λ
ridge.fit(X_train, y_train)
# Lasso 回归
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
# 评估
for name, model in [("LR", lr), ("Ridge", ridge), ("Lasso", lasso)]:
y_pred = model.predict(X_test)
print(f"{name}: MSE={mean_squared_error(y_test, y_pred):.4f}, R²={r2_score(y_test, y_pred):.4f}")小结
| 概念 | 要点 |
|---|---|
| 线性模型 | |
| MSE 损失 | 最小化预测与真实值的平方差 |
| 正规方程 | 闭式解, 复杂度 |
| 梯度下降 | 迭代优化,适合大规模数据 |
| L2 正则化 | 权重缩小,不稀疏 |
| L1 正则化 | 稀疏解,自动特征选择 |
| 学习率 | 太大震荡,太小收敛慢 |
参考资料
- 吴恩达机器学习 - 线性回归
- StatQuest - Linear Regression
- 《统计学习方法》第 1 章
- 《机器学习》周志华 - 第 3 章