共计 1590 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点
决策树是机器学习中最基础且可解释性强的算法之一,在金融风控、医疗诊断等业务场景中有广泛应用。CART(Classification and Regression Trees)作为决策树的经典实现,虽然原理直观,但在实际应用中仍存在几个关键痛点:

- 连续值处理:如何高效找到最佳分割点?
- 过拟合问题:何时剪枝?预剪枝还是后剪枝?
- 计算效率:大规模数据下的特征选择优化
算法解析
Gini 系数计算
Gini 系数衡量数据不纯度,定义为:
$$Gini(D) = 1 – \sum_{k=1}^K p_k^2$$
其中 $p_k$ 是第 $k$ 类样本的比例。对于二分类问题,当 $p=0.5$ 时 Gini 系数最大(0.5)。
与 ID3/C4.5 的差异
- 分裂标准:CART 使用 Gini 系数,ID3 用信息增益,C4.5 用增益率
- 树结构:CART 强制生成二叉树,其他算法可多分叉
- 用途:CART 同时支持分类和回归
二叉树构建流程
- 遍历所有特征及其可能分割点
- 计算分裂后的 Gini 系数减少量
- 选择增益最大的特征和分割点
- 递归生成子节点直到停止条件
剪枝策略
- 预剪枝:通过 max_depth/min_samples_leaf 等参数提前终止
- 后剪枝:生成完整树后自底向上合并节点
代码实现
节点分裂核心代码
def find_best_split(X, y):
best_gini = float('inf')
best_feature, best_value = None, None
for feature in range(X.shape[1]): # 遍历所有特征
unique_values = np.unique(X[:, feature])
for value in unique_values: # 遍历所有可能分割值
left_indices = X[:, feature] <= value
gini = weighted_gini(y[left_indices], y[~left_indices])
if gini < best_gini:
best_gini = gini
best_feature = feature
best_value = value
return best_feature, best_value
可视化决策边界
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
plt.figure(figsize=(12,8))
plot_tree(model, filled=True, feature_names=feature_names)
plt.show()
实战例题
乳腺癌数据集示例
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
# 数据加载
data = load_breast_cancer()
X, y = data.data, data.target
# 模型训练
clf = DecisionTreeClassifier(max_depth=3, criterion='gini')
clf.fit(X, y)
# 评估
print(f"Test accuracy: {clf.score(X_test, y_test):.2f}")
关键输出解读
- 节点中的
value显示类别分布 gini显示当前节点的不纯度- 颜色深浅反映节点纯度
生产建议
超参数调优
- max_depth:通常 3 - 8 层足够
- min_samples_split:建议≥10 避免过拟合
- class_weight:处理类别不平衡
进阶技巧
- 与随机森林集成提升效果
- 用 GridSearchCV 自动调参
- 导出规则用于业务系统
思考题
- 如何修改代码使其支持回归任务?
- 当特征量很大时,如何优化 find_best_split 的计算效率?
希望这篇实战指南能帮助你掌握 CART 决策树的精髓!在实际项目中,建议先从简单配置开始,逐步增加复杂度观察效果变化。
正文完
