Lesson 02
简单线性回归:从一条直线开始理解学习
本章用最简单的线性模型建立"训练 = 最小化误差"的核心直觉:一条直线如何拟合数据、代价函数衡量什么、OLS 如何求出最优参数。
本章细分学习地图
线性回归是理解"模型从数据中学习"的最佳起点。每个模块解决一个递进问题:用什么函数预测、怎么衡量预测好坏、怎么找到最优参数、怎么用代码实现。
| 模块 | 拆细学习单元 | 完成后应产出 | 掌握标准 |
|---|---|---|---|
| 假设函数 | y = wx + b 的含义、斜率与截距的直觉。 | 手写一个预测函数。 | 能说清 w 变大或 b 变大对直线的影响。 |
| 代价函数 | 残差、MSE 的定义与含义。 | 手算一组数据的 MSE。 | 能解释为什么要平方、为什么要求均值。 |
| 最小二乘法 | OLS 公式推导、几何含义(残差平方和最小)。 | 理解参数闭式解。 | 能说清 OLS 在做什么、什么时候可以直接用。 |
| sklearn 实战 | LinearRegression 训练、预测、属性解读。 | 完整可运行代码。 | 能读懂 coef_、intercept_ 并画出拟合线。 |
| 评估指标 | R²、MAE、RMSE 的区别和适用场景。 | 指标对比表。 | 能根据业务需求选对指标。 |
学习目标
线性回归流程
本章完成度
已完成 0/4
线性回归的重点不是"画一条线",而是理解"训练 = 找到让代价函数最小的参数"。这个思路贯穿后续所有模型。
假设函数
简单线性回归假设目标 y 和特征 x 之间存在线性关系。模型的任务是学出最优的斜率 w 和截距 b。
斜率 w
x 每增加 1 个单位,ŷ 增加 w 个单位。w 为正表示正相关,为负表示负相关,绝对值越大影响越强。
截距 b
当 x = 0 时 ŷ 的值。截距决定直线的上下平移位置,不影响斜率方向。
import numpy as np
def predict(x, w, b):
"""简单线性回归的假设函数"""
return w * x + b
# 示例:斜率 2,截距 1
x = np.array([1, 2, 3, 4, 5])
y_pred = predict(x, w=2, b=1)
print("预测值:", y_pred) # [3, 5, 7, 9, 11]
代价函数:衡量拟合好坏
代价函数度量预测值 ŷ 与真实值 y 之间的差距。线性回归最常用均方误差(MSE):对每个样本计算残差平方,然后求均值。
平方让正负残差不会互相抵消,同时会放大较大的误差。如果你更在乎大误差,MSE 是合适的选择;如果想让指标对离群点更稳健,可以考虑 MAE。
import numpy as np
def mse(y_true, y_pred):
"""手动计算均方误差"""
residuals = y_true - y_pred
return np.mean(residuals ** 2)
y_true = np.array([3, 5, 7, 9, 11])
y_pred = np.array([2.8, 5.1, 6.8, 9.3, 10.7])
print("MSE:", mse(y_true, y_pred)) # 约 0.054
| 概念 | 含义 | 注意事项 |
|---|---|---|
| 残差 residual | yi − ŷi,单个样本的预测误差。 | 可正可负,平方后消除方向。 |
| MSE | 所有残差平方的均值。 | 单位是目标变量的平方,不够直观。 |
| RMSE | MSE 取平方根,与目标同单位。 | 更适合直观理解误差大小。 |
最小二乘法(OLS)
普通最小二乘法(Ordinary Least Squares)通过数学求导,直接给出让 MSE 最小的 w 和 b 的闭式解,无需迭代。
OLS 找到的直线,使得所有数据点到直线的垂直距离的平方和最小。这就是"最小二乘"名字的由来。
import numpy as np
def ols_fit(x, y):
"""手动实现 OLS 求解"""
x_mean, y_mean = x.mean(), y.mean()
w = np.sum((x - x_mean) * (y - y_mean)) / np.sum((x - x_mean) ** 2)
b = y_mean - w * x_mean
return w, b
x = np.array([1, 2, 3, 4, 5], dtype=float)
y = np.array([2.1, 4.0, 5.8, 8.1, 9.9])
w, b = ols_fit(x, y)
print(f"斜率 w={w:.3f}, 截距 b={b:.3f}") # w≈1.960, b≈0.060
| OLS 的优势 | OLS 的局限 |
|---|---|
| 有闭式解,计算快,无需调学习率。 | 特征数很多时,矩阵求逆的内存和时间开销大。 |
| 结果确定唯一,不受初始化影响。 | 对离群点敏感(因为平方放大了大残差)。 |
sklearn 的 LinearRegression 默认即 OLS。 | 不含正则化,容易在高维稀疏数据上过拟合。 |
sklearn 实战
用 LinearRegression 完成一个完整的回归流程:加载数据、拆分、训练、预测、评估与参数解读。
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import root_mean_squared_error, mean_absolute_error, r2_score
import numpy as np
# 1. 生成带噪声的一维回归数据
X, y = make_regression(n_samples=100, n_features=1, noise=15, random_state=42)
# 2. 拆分训练/测试集(回归任务不使用 stratify)
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. 查看学到的参数
print(f"斜率 coef_: {model.coef_[0]:.3f}")
print(f"截距 intercept_: {model.intercept_:.3f}")
# 5. 预测与评估
y_pred = model.predict(X_test)
print(f"R²: {r2_score(y_test, y_pred):.4f}")
print(f"MAE: {mean_absolute_error(y_test, y_pred):.2f}")
print(f"RMSE: {root_mean_squared_error(y_test, y_pred):.2f}")
coef_[0] 对应第一个特征的斜率 w;intercept_ 对应截距 b。多元回归时 coef_ 是一个数组,每个元素对应一个特征的权重。
回归评估指标
不同指标反映不同维度的拟合质量。选指标前先问:业务更在乎大误差还是平均水平?是否需要无量纲的相对指标?
| 指标 | 公式直觉 | 适用场景 |
|---|---|---|
| R² | 模型比"预测均值"好多少。1 为完美,0 为不比均值强。 | 对比不同模型时的相对指标。 |
| MAE | 残差绝对值的均值,与目标同单位。 | 想要稳健指标,不希望离群点主导评估。 |
| RMSE | MSE 的平方根,与目标同单位。 | 想重点惩罚大误差。 |
scikit-learn ≥ 1.4 提供 root_mean_squared_error。旧版本用 mean_squared_error(..., squared=False) 已弃用,请使用新 API。
练习题
第 1 题:给定 4 个数据点 (1,2), (2,4), (3,5), (4,4),手算 MSE(假设 ŷ = x + 1)。
参考思路:ŷ 分别为 2, 3, 4, 5。残差为 0, 1, 1, -1。残差平方为 0, 1, 1, 1。MSE = (0+1+1+1)/4 = 0.75。
第 2 题:R² = 0 意味着什么?R² 能否为负?
参考思路:R² = 0 表示模型的预测能力等同于"永远预测均值";R² 可以为负,说明模型甚至比预测均值还差,通常意味着模型或数据有严重问题。
第 3 题:使用 make_regression 生成 200 个样本、3 个特征的数据,完成训练并打印每个特征的 coef_,解释哪个特征影响最大。
参考思路:
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
X, y = make_regression(n_samples=200, n_features=3, noise=10, random_state=42)
model = LinearRegression().fit(X, y)
for i, c in enumerate(model.coef_):
print(f"特征 {i}: coef = {c:.3f}")
# coef_ 绝对值最大的特征对预测影响最大
检查点
离开本章前,请确认:
- 能写出 ŷ = wx + b 并解释 w、b 的含义。
- 能解释 MSE 代价函数的公式、为什么用平方、以及最小化它的目标。
- 能说清 OLS 的作用——直接算出让 MSE 最小的 w 和 b。
- 能用
LinearRegression完成训练并解读coef_和intercept_。 - 能区分 R²、MAE、RMSE,并知道
root_mean_squared_error是当前推荐 API。