SL Scikit-Learn Learn机器学习教程

Lesson 02

简单线性回归:从一条直线开始理解学习

本章用最简单的线性模型建立"训练 = 最小化误差"的核心直觉:一条直线如何拟合数据、代价函数衡量什么、OLS 如何求出最优参数。

  • 预计时长40 分钟
  • 难度入门
  • 前置章节第 01 章

本章细分学习地图

线性回归是理解"模型从数据中学习"的最佳起点。每个模块解决一个递进问题:用什么函数预测、怎么衡量预测好坏、怎么找到最优参数、怎么用代码实现。

模块拆细学习单元完成后应产出掌握标准
假设函数y = wx + b 的含义、斜率与截距的直觉。手写一个预测函数。能说清 w 变大或 b 变大对直线的影响。
代价函数残差、MSE 的定义与含义。手算一组数据的 MSE。能解释为什么要平方、为什么要求均值。
最小二乘法OLS 公式推导、几何含义(残差平方和最小)。理解参数闭式解。能说清 OLS 在做什么、什么时候可以直接用。
sklearn 实战LinearRegression 训练、预测、属性解读。完整可运行代码。能读懂 coef_intercept_ 并画出拟合线。
评估指标R²、MAE、RMSE 的区别和适用场景。指标对比表。能根据业务需求选对指标。

学习目标

线性回归流程

1假设函数 y=wx+b
2代价函数 MSE
3OLS 求最优 w, b
4预测与评估

本章完成度

已完成 0/4

本章核心判断

线性回归的重点不是"画一条线",而是理解"训练 = 找到让代价函数最小的参数"。这个思路贯穿后续所有模型。

假设函数

简单线性回归假设目标 y 和特征 x 之间存在线性关系。模型的任务是学出最优的斜率 w 和截距 b。

ŷ = w · x + b 假设函数:ŷ 是预测值,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):对每个样本计算残差平方,然后求均值。

J(w, b) = (1/n) · Σi=1n (yi − ŷiMSE 代价函数:n 为样本数,yi − ŷi 为第 i 个残差
为什么用平方

平方让正负残差不会互相抵消,同时会放大较大的误差。如果你更在乎大误差,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
概念含义注意事项
残差 residualyi − ŷi,单个样本的预测误差。可正可负,平方后消除方向。
MSE所有残差平方的均值。单位是目标变量的平方,不够直观。
RMSEMSE 取平方根,与目标同单位。更适合直观理解误差大小。

最小二乘法(OLS)

普通最小二乘法(Ordinary Least Squares)通过数学求导,直接给出让 MSE 最小的 w 和 b 的闭式解,无需迭代。

w = Σ(xi − x̄)(yi − ȳ) / Σ(xi − x̄)² OLS 斜率公式:x̄, ȳ 分别为特征和目标的均值
b = ȳ − w · x̄ OLS 截距公式:由均值和斜率直接计算
几何含义

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_ 和 intercept_ 的含义

coef_[0] 对应第一个特征的斜率 w;intercept_ 对应截距 b。多元回归时 coef_ 是一个数组,每个元素对应一个特征的权重。

回归评估指标

不同指标反映不同维度的拟合质量。选指标前先问:业务更在乎大误差还是平均水平?是否需要无量纲的相对指标?

指标公式直觉适用场景
模型比"预测均值"好多少。1 为完美,0 为不比均值强。对比不同模型时的相对指标。
MAE残差绝对值的均值,与目标同单位。想要稳健指标,不希望离群点主导评估。
RMSEMSE 的平方根,与目标同单位。想重点惩罚大误差。
R² = 1 − Σ(yi − ŷi)² / Σ(yi − ȳ)² R² 决定系数:分子是模型残差平方和,分母是总变异
RMSE 的 API 注意

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。