35·监督学习-回归进阶

偏差-方差权衡

theorymodel-selection

第35课:偏差-方差权衡

学习目标

  • 理解偏差(Bias)和方差(Variance)在模型评估中的含义
  • 区分高偏差与高方差问题的典型表现
  • 掌握通过误差分析诊断模型问题的方法
  • 学会在模型复杂度与泛化能力之间找到平衡点

核心概念

什么是偏差和方差?

想象你在练习射箭:

偏差(Bias):系统误差,就像你的瞄准器歪了,即使技术再好,箭总是偏向同一边。在机器学习中,偏差描述了模型捕获数据中真实模式的能力。高偏差意味着模型过于简单,无法捕捉数据的基本关系(欠拟合)。

方差(Variance):随机误差,就像每次射箭都手抖,结果很分散。在机器学习中,方差描述了模型对训练数据微小变化的敏感程度。高方差意味着模型过于复杂,过度学习了训练数据的噪声(过拟合)。

偏差-方差权衡的核心思想是:提高模型复杂度通常会降低偏差但增加方差,反之亦然。我们的目标是找到一个平衡点,使总误差最小。

误差分解

对于回归问题,期望预测误差可以分解为:

总误差 = 偏差² + 方差 + 不可避免的噪声

代码示例

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error
from sklearn.pipeline import make_pipeline

# 1. 生成带噪声的数据集
np.random.seed(42)
X = np.sort(5 * np.random.rand(100, 1), axis=0)
y = np.sin(X).ravel() + np.random.normal(0, 0.2, 100)  # 真实模式 + 噪声

# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 3. 创建不同复杂度的模型
degrees = [1, 4, 15]  # 低中高复杂度
models = []

plt.figure(figsize=(12, 4))

for i, degree in enumerate(degrees):
    # 创建多项式回归模型
    model = make_pipeline(PolynomialFeatures(degree), LinearRegression())
    model.fit(X_train, y_train)
    models.append(model)
    
    # 预测
    y_train_pred = model.predict(X_train)
    y_test_pred = model.predict(X_test)
    
    # 计算误差
    train_error = mean_squared_error(y_train, y_train_pred)
    test_error = mean_squared_error(y_test, y_test_pred)
    
    # 可视化
    plt.subplot(1, 3, i + 1)
    X_plot = np.linspace(0, 5, 100).reshape(-1, 1)
    y_plot = model.predict(X_plot)
    
    plt.scatter(X_train, y_train, color='blue', s=10, label='训练数据')
    plt.scatter(X_test, y_test, color='green', s=10, label='测试数据')
    plt.plot(X_plot, y_plot, color='red', linewidth=2, label=f'模型 (度={degree})')
    plt.plot(X_plot, np.sin(X_plot), color='black', linestyle='--', alpha=0.5, label='真实函数')
    
    plt.title(f'多项式度={degree}\n训练MSE: {train_error:.3f}, 测试MSE: {test_error:.3f}')
    plt.xlabel('X')
    plt.ylabel('y')
    plt.legend()
    plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# 4. 模拟偏差-方差权衡的直观展示
print("=" * 60)
print("模型复杂度分析:")
print("=" * 60)

# 使用多个随机数据集模拟方差
n_datasets = 50
train_errors = {d: [] for d in degrees}
test_errors = {d: [] for d in degrees}

for _ in range(n_datasets):
    # 生成新数据集
    X_new = np.sort(5 * np.random.rand(100, 1), axis=0)
    y_new = np.sin(X_new).ravel() + np.random.normal(0, 0.2, 100)
    X_train_new, X_test_new, y_train_new, y_test_new = train_test_split(
        X_new, y_new, test_size=0.3, random_state=42
    )
    
    for degree in degrees:
        model = make_pipeline(PolynomialFeatures(degree), LinearRegression())
        model.fit(X_train_new, y_train_new)
        
        train_errors[degree].append(mean_squared_error(y_train_new, model.predict(X_train_new)))
        test_errors[degree].append(mean_squared_error(y_test_new, model.predict(X_test_new)))

print("\n不同复杂度模型的平均误差 (50次随机数据集):")
print(f"{'模型复杂度':<15} {'平均训练误差':<15} {'平均测试误差':<15} {'诊断':<10}")
print("-" * 55)

for degree in degrees:
    avg_train = np.mean(train_errors[degree])
    avg_test = np.mean(test_errors[degree])
    
    if avg_train > 0.5 and avg_test > 0.5:
        diagnosis = "高偏差"
    elif avg_train < 0.1 and avg_test > 0.5:
        diagnosis = "高方差"
    else:
        diagnosis = "平衡"
    
    print(f"多项式度={degree:<10} {avg_train:<15.3f} {avg_test:<15.3f} {diagnosis:<10}")

实践练习

练习1:基础概念选择题

以下哪种情况最可能是高偏差问题?

  1. 训练误差很低,测试误差很高
  2. 训练误差和测试误差都很高
  3. 训练误差中等,测试误差略高
  4. 模型在训练集上表现很好,但在新数据上表现一般

答案:2. 训练误差和测试误差都很高

练习2:代码修改实验

基于上面的代码示例,尝试以下修改:

  1. 将线性回归改为岭回归(Ridge Regression),alpha参数分别设为0.01, 1, 100
  2. 观察不同正则化强度下训练误差和测试误差的变化
  3. 思考:正则化如何影响偏差和方差?

预期结果

  • alpha=0.01:接近普通线性回归
  • alpha=1:适度的正则化,可能改善测试误差
  • alpha=100:强正则化,高偏差,训练误差和测试误差都较高

练习3:诊断与优化

给定以下模型误差数据,判断问题类型并提出解决方案:

模型训练MSE测试MSE
A0.021.85
B0.450.48
C0.800.82

要求

  1. 诊断每个模型的问题(高偏差/高方差/平衡)
  2. 为每个模型提出具体的优化策略
  3. 预测优化后的误差变化方向

常见错误

错误1:只看训练误差

现象:认为训练误差最低的模型就是最好的模型 正确做法:始终比较训练误差和测试误差的差距,关注泛化性能

错误2:混淆诊断结果

现象:看到高测试误差就认为是高方差问题 正确做法

  • 高偏差:训练误差和测试误差都高,且差距不大
  • 高方差:训练误差低但测试误差高,差距很大

错误3:过度调整模型复杂度

现象:看到高方差就无限增加正则化,或看到高偏差就增加模型复杂度 正确做法:逐步调整,使用交叉验证寻找最优平衡点

错误4:忽略数据质量

现象:只关注模型而忽略数据噪声和特征工程 正确做法:先确保数据质量,再调整模型复杂度

小结

关键要点

  1. 偏差反映模型系统误差,方差反映模型稳定性
  2. 偏差-方差权衡是机器学习的核心挑战:简单模型高偏差,复杂模型高方差
  3. 诊断方法:通过训练误差和测试误差的组合判断问题类型
    • 高偏差:两误差都高,差距小
    • 高方差:训练误差低,测试误差高
  4. 解决策略
    • 高偏差:增加模型复杂度、增加特征、减少正则化
    • 高方差:减少模型复杂度、增加数据、增加正则化

下一课预告

在下一课《学习曲线与模型诊断》中,我们将学习如何通过学习曲线更系统地分析偏差和方差问题,以及如何用这些工具指导模型选择和优化。我们将把今天学到的概念转化为具体的诊断工具,让模型改进过程更加有章可循。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「学习曲线与模型诊断」 以巩固所学知识。