过拟合与欠拟合是机器学习模型训练中常见的两个问题。欠拟合指模型过于简单,无法有效学习训练数据中的规律,表现为训练集和测试集误差都较高。过拟合则指模型过于复杂,将训练数据中的噪声也当作规律学习,导致训练集表现极好但测试集表现差。核心概念包括欠拟合、过拟合及Bias-Variance权衡。读者将学会如何诊断模型是否欠拟合或过拟合,并掌握五种解决方案:收集更多数据、降低模型复杂度、应用正则化(如L1和L2)、使用Dropout(神经网络中随机使部分神经元失效)以及早停(监控验证集损失)。通过这些方法,读者能够有效提升模型在新数据上的表现,达到更好的泛化效果。
过拟合与欠拟合
训练模型的最高境界是:在新数据上也表现好。两个最常见的"翻车现场"是过拟合和欠拟合。
两个核心概念
欠拟合(Underfitting)
模型太简单,连训练数据里的规律都没学明白。
比喻:用一条直线去拟合明显是抛物线的数据。
表现:
- 训练集表现差
- 测试集表现也差
- 训练误差和测试误差都高,且接近
过拟合(Overfitting)
模型太复杂,把训练数据里的噪声也当成规律学进去了。
比喻:用 18 次多项式去拟合 10 个数据点——曲线完美穿过每个点,但完全无法泛化。
表现:
- 训练集表现极好(几乎 100%)
- 测试集表现差
- 训练误差低,测试误差高,两者差距大
一张图看懂
误差
↑
│ 测试误差 (过拟合时反而升高)
│ ╱
│ ╱
│ ╱ ← 训练误差 (一直下降)
│ ╱
│ ╱
│╱________________________→
0 模型复杂度 →
↑ ↑
欠拟合 过拟合
"甜蜜点" ← 选这个
5 种解决方案
1. 收集更多数据
最有效但成本最高。数据多到一定程度,简单的模型也不会欠拟合。
2. 降低模型复杂度
- 用线性而不是高次多项式
- 减少神经网络的层数/神经元数
- 减少决策树的深度
# sklearn 里直接调
DecisionTreeClassifier(max_depth=5) # 限制树的深度
3. 正则化(Regularization)
在损失函数里加上对模型复杂度的惩罚。最常见的是 L1 和 L2:
L_new = L_old + lambda * sum(|w_i|) (L1)
L_new = L_old + lambda * sum(w_i^2) (L2)
其中 lambda 是正则化强度,越大越防止过拟合。
from sklearn.linear_model import Ridge
model = Ridge(alpha=1.0) # L2 正则化
4. Dropout(神经网络专属)
训练时随机让一部分神经元"罢工",强迫网络学到更鲁棒的特征。
model = Sequential([
Dense(128, activation='relu'),
Dropout(0.5), # 50% 神经元随机失活
Dense(10, activation='softmax')
])
5. 早停(Early Stopping)
训练时监控验证集损失,验证集损失不再下降时立即停止。
from keras.callbacks import EarlyStopping
early_stop = EarlyStopping(patience=5, restore_best_weights=True)
model.fit(X_train, y_train, validation_split=0.2, callbacks=[early_stop])
一个诊断小测试
训练完模型后,如果出现:
| 训练误差 | 测试误差 | 诊断 | 怎么办 |
|---|---|---|---|
| 高 | 高 | 欠拟合 | 加特征 / 用更复杂模型 |
| 低 | 高 | 过拟合 | 加数据 / 正则化 / 降复杂度 |
| 低 | 低(接近) | 刚刚好 | 庆祝一下 |
小结
- 欠拟合 = 模型太简单,学不到规律
- 过拟合 = 模型太复杂,把噪声当规律
- 解决方案:数据 / 降复杂度 / 正则化 / Dropout / 早停
- 训练误差 vs 测试误差 是诊断的金标准
练习思考
- 为什么 L1 正则化会让一些权重变成 0,而 L2 不会?
- 在神经网络里,Dropout 为什么能防止过拟合?训练和推理时的行为有什么不同?
- 想一个真实场景,用上面那张诊断表分析一个模型的"病"并给出药方。
章末小测验
检验你对《过拟合与欠拟合》的掌握程度。
1
训练误差 0.01,测试误差 0.45,这是典型的?
2
下列哪种方法不能缓解过拟合?
3
L2 正则化为什么能防止过拟合?
学完这章, 你可能想看
讨论区(0)
加载评论中...