CART决策树后剪枝实战:从过拟合陷阱到模型优化

1次阅读
没有评论

共计 1341 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

为什么需要后剪枝?

刚接触决策树时,我总发现训练集准确率接近 100%,但测试集表现糟糕——这就是典型的过拟合。后剪枝(Post-Pruning)就像给树做 ” 整形手术 ”,通过修剪不必要的分支来提高泛化能力。与预剪枝(Pre-Pruning)不同,后剪枝允许树先充分生长,再反向修剪,避免了预剪枝可能导致的欠拟合问题。

CART 决策树后剪枝实战:从过拟合陷阱到模型优化

核心数学原理

决策树分裂时使用基尼系数(Gini Index)衡量不纯度:

Gini(t) = 1 - Σ[p(i|t)^2]

后剪枝通过代价复杂度(Cost-Complexity Pruning)平衡误差与复杂度:

Rα(T) = R(T) + α|T|

其中:
– R(T)是误分类率
– |T| 是叶节点数
– α 是调节参数(越大剪枝越激进)

过拟合可视化诊断

用 sklearn 生成一个深度为 10 的未剪枝树:

from sklearn.tree import plot_tree
import matplotlib.pyplot as plt

plt.figure(figsize=(20,10))
plot_tree(clf_unpruned, filled=True, feature_names=X.columns)
plt.show()

你会发现树结构复杂,存在大量只覆盖单个样本的节点——这些就是需要修剪的 ” 过拟合分支 ”。

代价复杂度剪枝四步法

1. 计算 CCP 路径

path = clf.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas = path.ccp_alphas

2. 交叉验证选择 α

from sklearn.model_selection import cross_val_score

alpha_scores = []
for alpha in ccp_alphas:
    temp_clf = DecisionTreeClassifier(ccp_alpha=alpha)
    scores = cross_val_score(temp_clf, X_train, y_train, cv=5)
    alpha_scores.append(np.mean(scores))

3. 选择最佳 α 值

optimal_alpha = ccp_alphas[np.argmax(alpha_scores)]

4. 训练最终模型

clf_pruned = DecisionTreeClassifier(ccp_alpha=optimal_alpha)
clf_pruned.fit(X_train, y_train)

避坑实践指南

  1. 数据泄露陷阱:绝对不要用测试集选择 α!必须严格区分训练 / 验证 / 测试集
  2. 特征缩放影响:决策树虽不要求归一化,但高基数特征会获得不合理的高重要性
  3. 随机性控制 :设置random_state 保证实验可复现,尤其是在交叉验证时

效果对比实验

指标 未剪枝树 剪枝后树
训练集 F1 0.99 0.93
测试集 F1 0.82 0.88
预测时延(ms) 3.2 1.7

从我的信用卡欺诈检测项目看,剪枝后模型:
– 测试集 F1 提升 6%
– 推理速度加快 47%
– 模型体积缩小 80%

最佳实践建议

  1. 先用 max_depth=3 快速建立基线模型
  2. 逐步放松限制让树生长
  3. 最后用后剪枝优化
  4. 商业场景建议 α≤0.02(保持可解释性)

完整代码已上传 Github(含 Jupyter 可视化示例),欢迎 Star 交流!

正文完
 0
评论(没有评论)