CART决策树实战:从原理到例题解析

1次阅读
没有评论

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

image.webp

背景痛点

决策树在业务场景中广泛应用,如金融风控、医疗诊断等,因其可解释性强、对数据分布要求低而备受青睐。然而,在实际使用 CART(Classification and Regression Trees)算法时,开发者常遇到以下典型问题:

CART 决策树实战:从原理到例题解析

  • 连续值处理 :如何高效找到最佳分割点?
  • 剪枝策略选择 :预剪枝容易欠拟合,后剪枝计算成本高
  • 过拟合风险 :树深度控制与样本量不匹配导致泛化性差

算法解析

Gini 系数计算

Gini 系数衡量节点纯度,计算公式为:
$$ Gini(p) = 1 – \sum_{k=1}^{K}p_k^2 $$
其中 $p_k$ 是第 k 类样本的占比。分裂时选择使 Gini 下降最大的特征:
$$ \Delta Gini = Gini(D) – \sum_{v=1}^{V}\frac{|D^v|}{|D|}Gini(D^v) $$

与 ID3/C4.5 的差异

  • 分裂方式 :CART 强制生成二叉树,ID3/C4.5 允许多叉树
  • 特征标准 :CART 使用 Gini 系数,ID3 用信息增益,C4.5 用增益率
  • 输出类型 :CART 可同时处理分类和回归任务

剪枝策略

  1. 预剪枝 :在分裂前通过参数控制(如 max_depth)
  2. 后剪枝 :生成完整树后,用验证集自底向上剪枝

代码实现

核心分裂函数

def find_best_split(X, y):
    best_gini = float('inf')
    best_feature, best_threshold = None, None

    for feature_idx in range(X.shape[1]):
        # 对连续值特征排序
        thresholds = np.unique(X[:, feature_idx])
        for threshold in thresholds:
            left_mask = X[:, feature_idx] <= threshold
            gini = weighted_gini(y[left_mask], y[~left_mask])
            if gini < best_gini:
                best_gini = gini
                best_feature = feature_idx
                best_threshold = threshold
    return best_feature, best_threshold

可视化决策边界

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.model_selection import train_test_split

data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

模型训练与评估

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report

model = DecisionTreeClassifier(criterion='gini', max_depth=3)
model.fit(X_train, y_train)
print(classification_report(y_test, model.predict(X_test)))

生产建议

超参数调优指南

  • max_depth:通常 3 -10 层,通过交叉验证选择
  • min_samples_split:建议≥20 防止过拟合
  • class_weight:处理不平衡数据时设为 ’balanced’

进阶技巧

  1. 特征工程 :对连续特征做分箱处理
  2. 集成学习 :作为随机森林的基学习器
  3. 部署优化 :转换为 if-else 规则提升推理速度

思考题

  1. 当特征同时包含连续值和类别值时,应如何修改分裂逻辑?
  2. 如何证明后剪枝比预剪枝更能提升模型泛化能力?
正文完
 0
评论(没有评论)