第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:基础概念选择题
以下哪种情况最可能是高偏差问题?
- 训练误差很低,测试误差很高
- 训练误差和测试误差都很高
- 训练误差中等,测试误差略高
- 模型在训练集上表现很好,但在新数据上表现一般
答案:2. 训练误差和测试误差都很高
练习2:代码修改实验
基于上面的代码示例,尝试以下修改:
- 将线性回归改为岭回归(Ridge Regression),alpha参数分别设为0.01, 1, 100
- 观察不同正则化强度下训练误差和测试误差的变化
- 思考:正则化如何影响偏差和方差?
预期结果:
- alpha=0.01:接近普通线性回归
- alpha=1:适度的正则化,可能改善测试误差
- alpha=100:强正则化,高偏差,训练误差和测试误差都较高
练习3:诊断与优化
给定以下模型误差数据,判断问题类型并提出解决方案:
| 模型 | 训练MSE | 测试MSE |
|---|---|---|
| A | 0.02 | 1.85 |
| B | 0.45 | 0.48 |
| C | 0.80 | 0.82 |
要求:
- 诊断每个模型的问题(高偏差/高方差/平衡)
- 为每个模型提出具体的优化策略
- 预测优化后的误差变化方向
常见错误
错误1:只看训练误差
现象:认为训练误差最低的模型就是最好的模型 正确做法:始终比较训练误差和测试误差的差距,关注泛化性能
错误2:混淆诊断结果
现象:看到高测试误差就认为是高方差问题 正确做法:
- 高偏差:训练误差和测试误差都高,且差距不大
- 高方差:训练误差低但测试误差高,差距很大
错误3:过度调整模型复杂度
现象:看到高方差就无限增加正则化,或看到高偏差就增加模型复杂度 正确做法:逐步调整,使用交叉验证寻找最优平衡点
错误4:忽略数据质量
现象:只关注模型而忽略数据噪声和特征工程 正确做法:先确保数据质量,再调整模型复杂度
小结
关键要点
- 偏差反映模型系统误差,方差反映模型稳定性
- 偏差-方差权衡是机器学习的核心挑战:简单模型高偏差,复杂模型高方差
- 诊断方法:通过训练误差和测试误差的组合判断问题类型
- 高偏差:两误差都高,差距小
- 高方差:训练误差低,测试误差高
- 解决策略:
- 高偏差:增加模型复杂度、增加特征、减少正则化
- 高方差:减少模型复杂度、增加数据、增加正则化
下一课预告
在下一课《学习曲线与模型诊断》中,我们将学习如何通过学习曲线更系统地分析偏差和方差问题,以及如何用这些工具指导模型选择和优化。我们将把今天学到的概念转化为具体的诊断工具,让模型改进过程更加有章可循。
练习编辑器
rust
Loading...