目录
  1. 1. 写在前面
  2. 2. 1. 决策树的基本概念
    1. 2.1. 1.1 什么是决策树
    2. 2.2. 1.2 决策树学习的三个关键问题
    3. 2.3. 1.3 决策树的几何解释
    4. 2.4. 1.4 决策树算法家族概览
  3. 3. 2. 特征选择准则
    1. 3.1. 2.1 熵(Entropy)
    2. 3.2. 2.2 条件熵(Conditional Entropy)
    3. 3.3. 2.3 信息增益(Information Gain)
    4. 3.4. 2.4 信息增益比(Information Gain Ratio)
    5. 3.5. 2.5 基尼指数(Gini Index)
    6. 3.6. 2.6 最小二乘回归树的分裂准则
  4. 4. 3. ID3 算法
    1. 4.1. 3.1 算法描述
    2. 4.2. 3.2 ID3 算法流程(伪代码)
    3. 4.3. 3.3 ID3 的数值计算案例
    4. 4.4. 3.4 ID3 的局限性
  5. 5. 4. C4.5 算法
    1. 5.1. 4.1 信息增益比替代信息增益
    2. 5.2. 4.2 连续特征处理
    3. 5.3. 4.3 缺失值处理
      1. 5.3.1. 计算方法
    4. 5.4. 4.4 剪枝策略(PEP - Pessimistic Error Pruning)
  6. 6. 5. CART(Classification and Regression Tree)
    1. 6.1. 5.1 CART 分类树
      1. 6.1.1. 5.1.1 基尼指数选择特征
      2. 6.1.2. 5.1.2 CART 分类树的生成(伪代码)
    2. 6.2. 5.2 CART 回归树
      1. 6.2.1. 5.2.1 最小二乘准则
      2. 6.2.2. 5.2.2 回归树的数值案例
    3. 6.3. 5.3 CART 的剪枝:代价复杂度剪枝(CCP)
      1. 6.3.1. 5.3.1 代价复杂度度量
      2. 6.3.2. 5.3.2 剪枝过程
      3. 6.3.3. 5.3.3 1-SE 规则
  7. 7. 6. 预剪枝与后剪枝
    1. 7.1. 6.1 预剪枝(Pre-pruning)
    2. 7.2. 6.2 后剪枝(Post-pruning)
    3. 7.3. 6.3 预剪枝 vs 后剪枝
  8. 8. 7. 从决策树到集成学习
    1. 8.1. 7.1 决策树的优势与劣势
    2. 8.2. 7.2 Bagging(Bootstrap Aggregating,装袋法)
    3. 8.3. 7.3 Boosting(提升法)
    4. 8.4. 7.4 决策树在集成中的角色总结
  9. 9. 8. 分裂准则的数学统一与对比
    1. 9.1. 8.1 不纯度度量的一般框架
    2. 9.2. 8.2 三种不纯度函数的比较(二分类)
    3. 9.3. 8.3 Gini 指数与方差的等价性(回归视角)
  10. 10. 9. CART 的缺失值处理:代理分裂
    1. 10.1. 8.1 代理分裂的核心思想
    2. 10.2. 8.2 代理分裂的搜索
    3. 10.3. 8.3 代理分裂的优势
    4. 10.4. 8.4 C4.5 vs CART 缺失值处理对比
  11. 11. 10. 多变量决策树
    1. 11.1. 9.1 多变量决策树的优势
    2. 11.2. 9.2 常见的多变量分裂方法
  12. 12. 11. 决策树的不稳定性与集成学习的统计视角
    1. 12.1. 10.1 决策树是高方差学习器
    2. 12.2. 10.2 Bagging 如何降低方差
    3. 12.3. 10.3 Bagging vs Boosting 的偏差-方差视角
  13. 13. 12. 实战:sklearn 决策树参数全解析
    1. 13.1. 12.1 sklearn.tree.DecisionTreeClassifier 的核心参数
    2. 13.2. 12.2 剪枝路径可视化
    3. 13.3. 12.3 特征重要性计算
  14. 14. 13. 面试高频问答
  15. 15. 14. 总结
【统计学习方法死磕系列】决策树

写在前面

决策树是机器学习中最直观、最具可解释性的分类与回归方法。它模拟了人类做决策的自然过程——根据一系列特征条件来逐步缩小可能性,最终得出结论。一棵训练好的决策树可以直接可视化为一棵树形结构,每个内部节点代表一个特征上的测试,每个分支代表测试结果,每个叶节点代表一个决策。

虽然单棵决策树的预测精度通常不如 SVM 或神经网络,但决策树是集成学习(Random Forest、GBDT、XGBoost)的基石——没有决策树,就没有现代最强的表格数据学习器。

本文严格按照《统计学习方法》的脉络,依次覆盖 ID3、C4.5 和 CART 三种经典决策树学习算法,并深入探讨特征选择准则、剪枝策略、连续值和缺失值处理,以及它们与集成学习的桥梁关系。


1. 决策树的基本概念

1.1 什么是决策树

定义 1(决策树):决策树是一个由节点和有向边组成的树形结构。节点分为两种类型:

  • 内部节点(Internal Node):表示一个特征或属性上的测试
  • 叶节点(Leaf Node):表示一个类别(分类树)或一个预测值(回归树)

从根节点到叶节点的一条路径对应了一条分类规则。决策树的学习本质上是从训练数据中归纳出一组 if-then 规则。

1.2 决策树学习的三个关键问题

  1. 特征选择:在每个节点,应该选择哪个特征来进行划分?用什么样的准则衡量”划分的好坏”?
  2. 决策树生成:如何根据选择的特征递归地构建决策树?何时停止生长?
  3. 决策树剪枝:如何对过于复杂的树进行简化,以防止过拟合?

这三个问题对应了决策树学习的三个步骤,每个经典算法在这三个问题上给出了不同的答案。

1.3 决策树的几何解释

从几何角度看,当特征空间是 $\mathbb{R}^d$ 时,决策树的每个内部节点在特征空间中进行一次轴平行(axis-parallel)的划分。因此决策树的决策边界是由一系列与坐标轴平行的超平面段组成的。

这是决策树的一个重要限制——它无法直接学习斜的(oblique)决策边界。但这同时也赋予了决策树良好的可解释性:每个决策规则都对应一个明确可理解的条件(如”年龄 > 30”)。

1.4 决策树算法家族概览

算法 提出者/年代 树类型 特征选择 连续值 缺失值 剪枝
ID3 Quinlan, 1986 分类 信息增益 不支持 不支持
C4.5 Quinlan, 1993 分类 信息增益比 支持 支持 PEP 剪枝
CART Breiman et al., 1984 分类+回归 Gini 指数/MSE 支持 代理分裂 CCP 剪枝
CHAID Kass, 1980 分类 $\chi^2$ 统计量 分箱 支持 合并类别
MARS Friedman, 1991 回归 自适应样条 原生连续 支持 正则化

本文重点覆盖 ID3、C4.5 和 CART,这也是面试中的核心范围。


2. 特征选择准则

2.1 熵(Entropy)

信息熵是度量随机变量不确定性的最常用指标。

定义 2(信息熵):设 $X$ 是一个取有限个值的离散随机变量,其概率分布为 $P(X = x_i) = p_i, i = 1, \ldots, n$。则 $X$ 的熵定义为:

$$H(X) = -\sum_{i=1}^{n} p_i \log_2 p_i$$

约定 $0 \log 0 = 0$。通常对数以 2 为底,此时熵的单位是 bit。

熵的性质

  1. 非负性:$H(X) \geq 0$,当且仅当 $X$ 退化为确定事件时等号成立(没有不确定性)。
  2. 最大值:当 $X$ 服从均匀分布时($p_i = 1/n$),$H(X) = \log_2 n$,达到最大。均匀分布意味着对所有结果同等不确定。
  3. 严格凹性:$H(X)$ 作为 $p$ 的函数是严格凹的(沿概率单纯形)。

:抛硬币,正面概率 $p$,反面概率 $1-p$:

$$H(p) = -p \log_2 p - (1-p) \log_2 (1-p)$$

当 $p = 0.5$ 时,$H = 1$ bit(最大);当 $p = 0$ 或 $p = 1$ 时,$H = 0$(最小)。

具体数值:

$p$ $H(p)$
0.0 0.000
0.1 0.469
0.3 0.881
0.5 1.000
0.7 0.881
0.9 0.469
1.0 0.000

2.2 条件熵(Conditional Entropy)

定义 3(条件熵):已知随机变量 $A$ 的条件下,随机变量 $Y$ 的不确定性:

$$H(Y|A) = \sum_{a} P(A=a) \cdot H(Y|A=a)$$

其中 $H(Y|A=a) = -\sum_y P(Y=y|A=a) \log_2 P(Y=y|A=a)$。

条件熵是给定 $A$ 后 $Y$ 的残留不确定性

2.3 信息增益(Information Gain)

定义 4(信息增益):特征 $A$ 对训练数据集 $D$ 的信息增益 $g(D, A)$,定义为集合 $D$ 的熵 $H(D)$ 与特征 $A$ 给定条件下 $D$ 的条件熵 $H(D|A)$ 之差:

$$g(D, A) = H(D) - H(D|A)$$

信息增益表示得知特征 $A$ 后,对数据集 $D$ 分类不确定性的减少程度。增益越大,特征对分类越有用。

ID3 算法使用信息增益作为特征选择准则,每次选择信息增益最大的特征进行分裂。

信息增益的计算过程

设训练数据集 $D$,$|D|$ 为其样本容量。设有 $K$ 个类 $C_k, k = 1,\ldots,K$,$|C_k|$ 为属于类 $C_k$ 的样本个数。

  1. 计算数据集 $D$ 的经验熵:
    $$H(D) = -\sum_{k=1}^{K} \frac{|C_k|}{|D|} \log_2 \frac{|C_k|}{|D|}$$

  2. 计算特征 $A$ 对 $D$ 的经验条件熵:
    设特征 $A$ 有 $n$ 个不同的取值 ${a_1, a_2, \ldots, a_n}$,将 $D$ 划分为 $n$ 个子集 $D_1, D_2, \ldots, D_n$,其中 $D_i = {x \in D | A(x) = a_i}$。
    $$H(D|A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} H(D_i)$$
    其中 $H(D_i) = -\sum_{k=1}^{K} \frac{|D_{ik}|}{|D_i|} \log_2 \frac{|D_{ik}|}{|D_i|}$,$D_{ik} = D_i \cap C_k$。

  3. 计算信息增益:
    $$g(D, A) = H(D) - H(D|A)$$

2.4 信息增益比(Information Gain Ratio)

信息增益有一个严重问题:偏向于选择取值较多的特征

考虑极端情况:样本 ID 作为特征,每个样本的 ID 都不同。按 ID 分裂后每个子集只有一个样本,条件熵 $H(D|A) = 0$,信息增益达到最大值 $H(D)$。但这个特征对分类毫无意义——它只是在”记忆”训练数据。

为了校正这个偏差,C4.5 使用信息增益比

定义 5(信息增益比):特征 $A$ 对训练数据集 $D$ 的信息增益比定义为:

$$g_R(D, A) = \frac{g(D, A)}{H_A(D)}$$

其中 $H_A(D) = -\sum_{i=1}^{n} \frac{|D_i|}{|D|} \log_2 \frac{|D_i|}{|D|}$ 是分裂信息(Split Information)——将 $D$ 按 $A$ 的取值分裂成 $n$ 个子集这件事本身的熵。

直觉:如果特征取值很多,$H_A(D)$ 会很大(因为数据被分得很散),信息增益比通过除以 $H_A(D)$ 来惩罚这种特征。

C4.5 使用信息增益比来选择特征,但不是简单地选增益比最大的:它先从所有候选特征中选出信息增益高于平均水平的特征,再从这些特征中选择信息增益比最大的。

2.5 基尼指数(Gini Index)

CART 分类树使用基尼指数作为特征选择准则。

定义 6(基尼指数):在分类问题中,假设有 $K$ 个类,样本属于第 $k$ 类的概率为 $p_k$,则概率分布的基尼指数定义为:

$$\text{Gini}(p) = \sum_{k=1}^{K} p_k (1-p_k) = 1 - \sum_{k=1}^{K} p_k^2$$

对于给定的样本集合 $D$,其基尼指数为:

$$\text{Gini}(D) = 1 - \sum_{k=1}^{K} \left(\frac{|C_k|}{|D|}\right)^2$$

基尼指数的概率解释:它等于从集合中随机抽取两个样本,其类别标记不一致的概率。所以基尼指数越小,数据集的纯度越高。

基尼指数 vs 熵的比较

对于二分类问题($p$ 为正类比例):

$p$ Gini: $2p(1-p)$ 半熵: $-\frac{1}{2}[p\log_2 p + (1-p)\log_2(1-p)]$
0.0 0.000 0.000
0.1 0.180 0.234
0.3 0.420 0.441
0.5 0.500 0.500
0.7 0.420 0.441
0.9 0.180 0.234
1.0 0.000 0.000

半熵和基尼指数的曲线形状非常接近。两者都在 $p=0.5$ 处达到最大值。实践中两种准则选出的分裂特征通常一致,只是 Gini 计算更快(不需要 $\log$)。

特征 $A$ 条件下的基尼指数(CART 的分裂准则):

$$\text{Gini}(D, A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} \text{Gini}(D_i)$$

CART 选择使 $\text{Gini}(D, A)$ 最小的特征进行分裂。

为什么 CART 用 Gini 而不是熵?

  1. Gini 的计算不需要对数运算,速度更快
  2. Gini 的梯度更稳定(熵在 $p \to 0$ 时梯度趋于无穷,导致数值问题)
  3. 两者在实践中效果几乎相同,Gini 的简洁性使其成为默认选择

2.6 最小二乘回归树的分裂准则

对于回归问题,CART 使用平方误差最小化。

对于输入空间 $\mathcal{X}$ 被划分为 $M$ 个区域 $R_1, R_2, \ldots, R_M$,每个区域 $R_m$ 的预测值为其内部样本的均值:

$$\hat{c}_m = \text{avg}(y_i | x_i \in R_m)$$

回归树使用以下准则来选择最优切分变量 $j$ 和切分点 $s$:

$$\min_{j,s} \left[ \min_{c_1} \sum_{x_i \in R_1(j,s)} (y_i - c_1)^2 + \min_{c_2} \sum_{x_i \in R_2(j,s)} (y_i - c_2)^2 \right]$$

其中 $R_1(j,s) = {x | x^{(j)} \leq s}$,$R_2(j,s) = {x | x^{(j)} > s}$。

当 $j$ 和 $s$ 固定时,最优的 $c_1, c_2$ 为对应区域内的样本均值。这等价于:

  • 在所有特征 $j$ 和所有可能的切分点 $s$ 上进行穷举搜索
  • 选择使分裂后两侧 MSE 之和最小的 $(j, s)$ 对

3. ID3 算法

3.1 算法描述

ID3(Iterative Dichotomiser 3)是 Quinlan 于 1986 年提出的决策树生成算法。其核心是使用信息增益进行特征选择,递归地构建决策树。

3.2 ID3 算法流程(伪代码)

Algorithm: ID3(D, feature_list)
Input: 训练数据集 D, 特征列表 A
Output: 决策树 T

1. 若 D 中所有样本属于同一类 C_k:
2. 则将 T 置为单节点树,类标记为 C_k,返回 T
3. 若 A = ∅:
4. 则将 T 置为单节点树,类标记为 D 中样本数最多的类 C_max,返回 T
5. 否则:
6. 计算 A 中每个特征的信息增益
7. 选择信息增益最大的特征 A_g
8. 以 A_g 为根节点,对其每个取值 a_i:
9. 将 D 中 A_g = a_i 的样本构成子集 D_i
10. 若 D_i = ∅:
11. 则创建叶节点,标记为 D 中样本最多的类
12. 否则:
13. 以 ID3(D_i, A \ {A_g}) 为子树
14. 返回 T

3.3 ID3 的数值计算案例

考虑经典的”打网球”数据集:

序号 天气 (Outlook) 温度 (Temp) 湿度 (Humidity) 有风 (Windy) 打球 (Play)
1 Sunny Hot High Weak No
2 Sunny Hot High Strong No
3 Overcast Hot High Weak Yes
4 Rain Mild High Weak Yes
5 Rain Cool Normal Weak Yes
6 Rain Cool Normal Strong No
7 Overcast Cool Normal Strong Yes
8 Sunny Mild High Weak No
9 Sunny Cool Normal Weak Yes
10 Rain Mild Normal Weak Yes
11 Sunny Mild Normal Strong Yes
12 Overcast Mild High Strong Yes
13 Overcast Hot Normal Weak Yes
14 Rain Mild High Strong No

14 个样本中:Yes = 9,No = 5。

Step 1:计算根节点熵

$$H(D) = -\frac{9}{14}\log_2\frac{9}{14} - \frac{5}{14}\log_2\frac{5}{14} = -0.643 \times (-0.611) - 0.357 \times (-1.485) = 0.393 + 0.530 = 0.940$$

Step 2:计算各特征的信息增益

以 Outlook 为例:

  • Outlook = Sunny:5 个样本,其中 Yes=2, No=3
    $$H(D_{\text{Sunny}}) = -\frac{2}{5}\log_2\frac{2}{5} - \frac{3}{5}\log_2\frac{3}{5} = 0.971$$

  • Outlook = Overcast:4 个样本,其中 Yes=4, No=0
    $$H(D_{\text{Overcast}}) = 0$$

  • Outlook = Rain:5 个样本,其中 Yes=3, No=2
    $$H(D_{\text{Rain}}) = -\frac{3}{5}\log_2\frac{3}{5} - \frac{2}{5}\log_2\frac{2}{5} = 0.971$$

条件熵:

$$H(D|\text{Outlook}) = \frac{5}{14} \times 0.971 + \frac{4}{14} \times 0 + \frac{5}{14} \times 0.971 = 0.694$$

信息增益:

$$g(D, \text{Outlook}) = 0.940 - 0.694 = 0.246$$

类似计算:

$$g(D, \text{Temp}) = 0.029$$
$$g(D, \text{Humidity}) = 0.151$$
$$g(D, \text{Windy}) = 0.048$$

Outlook 的信息增益最大(0.246),选为根节点

Step 3:递归构建子树

  • Outlook = Overcast 的 4 个样本全是 Yes → 叶节点,类标为 Yes
  • Outlook = Sunny 和 Rain 的子集需要继续分裂

对 Sunny 子集(5 个样本,Yes=2, No=3),计算其余特征的增益…最终选择 Humidity 作为分裂特征。

完整决策树:

Outlook
├── Sunny
│ ├── Humidity
│ │ ├── High → No
│ │ └── Normal → Yes
├── Overcast → Yes
└── Rain
├── Windy
│ ├── Weak → Yes
│ └── Strong → No

3.4 ID3 的局限性

  1. 不能处理连续特征:ID3 假定所有特征都是离散的。连续值必须先离散化。
  2. 对缺失值敏感:ID3 没有处理缺失值的机制。
  3. 偏向多值特征:信息增益天然偏好取值多的特征。
  4. 没有剪枝:容易过拟合(学习到训练数据中的噪声)。
  5. 不能处理回归:ID3 是纯分类算法。

这些局限在 C4.5 中得到了系统性的解决。


4. C4.5 算法

C4.5 是 ID3 的改进版本,由同一作者 Quinlan 于 1993 年提出。它在保留 ID3 基本框架的同时,引入了几项关键改进。

4.1 信息增益比替代信息增益

如 2.4 节所述,C4.5 使用信息增益比而非信息增益来选择特征。

继续上节的例子,计算 Outlook 的分裂信息:

$$H_{\text{Outlook}}(D) = -\frac{5}{14}\log_2\frac{5}{14} - \frac{4}{14}\log_2\frac{4}{14} - \frac{5}{14}\log_2\frac{5}{14} = 1.577$$

信息增益比:

$$g_R(D, \text{Outlook}) = \frac{0.246}{1.577} = 0.156$$

类似地:

特征 信息增益 分裂信息 信息增益比
Outlook 0.246 1.577 0.156
Humidity 0.151 1.000 0.151
Windy 0.048 0.985 0.049
Temp 0.029 1.557 0.019

Outlook 在增益比上也胜出。

4.2 连续特征处理

C4.5 通过二分法(Binary Splitting)来处理连续特征。

对于连续特征 $A$,将训练集中 $A$ 的取值按升序排列:

$$a_1 \leq a_2 \leq \cdots \leq a_n$$

在每对相邻值的中点构造候选切分点:

$$t_i = \frac{a_i + a_{i+1}}{2}, \quad i = 1, 2, \ldots, n-1$$

这样得到 $n-1$ 个候选切分点。对每个切分点,计算按”$A \leq t_i$”二分后的信息增益(或增益比),选择最优的那个。

复杂度分析:对 $n$ 个样本的连续特征,排序 $O(n \log n)$ + 扫描切分点 $O(n)$,总体 $O(n \log n)$。加上对所有 $d$ 个特征都要做这个操作,特征选择阶段总复杂度为 $O(d n \log n)$。

注意:连续特征在一次分裂后,该特征在后续分裂中仍可能被再次使用(因为二分法只在某个阈值处分裂,不等于特征被完全”消耗”了)。这是 C4.5 与 ID3 的一个重要区别。

4.3 缺失值处理

C4.5 对缺失值的处理分为两个层面:训练时如何计算信息增益,以及预测时如何处理缺失。

计算方法

设特征 $A$ 有缺失值。记:

  • $D$ 的全部样本数为 $|D|$
  • $\tilde{D}$ 为 $D$ 中在特征 $A$ 上无缺失的样本子集
  • 引入权重 $w_i$(最开始全部为 1),实际的熵计算使用加权熵

计算信息增益时,只使用无缺失样本 $\tilde{D}$,然后按比例折算:

$$g(D, A) = \frac{|\tilde{D}|}{|D|} \cdot g(\tilde{D}, A)$$

也就是按无缺失样本的比例对信息增益进行”折扣”处理。这隐含地对有大量缺失值的特征施加了惩罚。

当选择 $A$ 进行分裂后,对于 $A$ 上有缺失的样本,C4.5 将其按各分支的样本比例分配到所有子节点:

  • 子节点 $i$ 的样本权重 = $\frac{|D_i|}{|\tilde{D}|} \times$(原样本权重)

一个缺失样本最终可能以不完整的权重出现在多个子节点中。

4.4 剪枝策略(PEP - Pessimistic Error Pruning)

C4.5 使用悲观错误剪枝(PEP),在训练集上直接评估是否应该剪掉某棵子树(不需要单独的验证集)。

对于一棵子树,估计其在训练集上的错误率的上界:

$$e = \frac{E + 0.5}{N}$$

其中 $E$ 是子树在训练集上的错误分类数,$N$ 是覆盖的样本数。$+0.5$ 是连续性校正。

该子树的分错个数的标准差(二项分布):

$$\text{SE} = \sqrt{\frac{e(1-e)}{N}}$$

如果剪掉子树(用叶节点替代,类标为多数类),其误差为 $E_{\text{leaf}}$。C4.5 的剪枝条件:

$$E_{\text{leaf}} \leq E_{\text{subtree}} + \text{SE}$$

即如果叶节点的错误数不超过子树错误数加一个标准差,就把子树剪掉。

直觉:子树的复杂性可能只是”记住”了训练数据中的噪声。如果剪掉子树后错误没有显著增加(在一个标准差范围外的增加才被认为是统计显著的),那子树就是不必要的,应被剪掉。


5. CART(Classification and Regression Tree)

CART 由 Breiman、Friedman、Olshen 和 Stone 于 1984 年提出,是决策树方法的集大成者。与 ID3/C4.5 相比,CART 有以下几个显著特点:

  1. 二分递归分裂:每个内部节点只产生两个子节点(二叉树),而非 ID3/C4.5 的多叉树。
  2. 分类和回归统一:CART 既可以做分类(Gini 指数),也可以做回归(MSE)。
  3. 代价复杂度剪枝(CCP):CART 的剪枝策略有严格的交叉验证支撑。

5.1 CART 分类树

5.1.1 基尼指数选择特征

CART 分类树使用基尼指数选择最优特征和最优二值切分点。

对于特征 $A$ 和其某个取值 $a$,二分数据集为 $D_1 = {x | A = a}$ 和 $D_2 = {x | A \neq a}$(离散情况),或 $D_1 = {x | A \leq s}$ 和 $D_2 = {x | A > s}$(连续情况)。

选择使分裂后加权基尼指数最小的 $(A, a)$ 对:

$$\text{Gini}(D, A, a) = \frac{|D_1|}{|D|}\text{Gini}(D_1) + \frac{|D_2|}{|D|}\text{Gini}(D_2)$$

5.1.2 CART 分类树的生成(伪代码)

Algorithm: CART_classification(D)
Input: 训练数据集 D, 停止条件
Output: CART 决策树

1. 对于每个特征 A 的每个可能取值 a:
2. 计算以 (A, a) 二分 D 后的基尼指数
3. 选择基尼指数最小的 (A*, a*) 作为最优切分点
4. 将 D 切分为 D1 和 D2
5. 对 D1 和 D2 分别递归调用 CART_classification
6. 返回以 (A*, a*) 为根节点的二叉树

停止条件:

  1. 节点中样本个数小于预定阈值
  2. 节点基尼指数小于预定阈值(样本基本纯净)
  3. 没有更多特征可用于分裂

5.2 CART 回归树

5.2.1 最小二乘准则

CART 回归树使用平方误差最小化来选择最优切分。对每个特征 $j$ 和切分点 $s$,求解:

$$\min_{j,s} \left[ \min_{c_1} \sum_{x_i \in R_1(j,s)} (y_i - c_1)^2 + \min_{c_2} \sum_{x_i \in R_2(j,s)} (y_i - c_2)^2 \right]$$

其中 $c_1 = \frac{1}{|R_1|}\sum_{x_i \in R_1} y_i$,$c_2 = \frac{1}{|R_2|}\sum_{x_i \in R_2} y_i$(区域内的样本均值)。

5.2.2 回归树的数值案例

假设有如下数据:

$x$ 1 2 3 4 5 6
$y$ 4.5 4.7 4.9 5.2 5.3 5.1

按 $x$ 排序后,候选切分点为 $s \in {1.5, 2.5, 3.5, 4.5, 5.5}$。

以 $s = 3.5$ 为例:

  • $R_1: {1, 2, 3}$,$\bar{y}_1 = (4.5+4.7+4.9)/3 = 4.70$
  • $R_2: {4, 5, 6}$,$\bar{y}_2 = (5.2+5.3+5.1)/3 = 5.20$
  • $\text{MSE} = \sum_{R_1}(y - 4.70)^2 + \sum_{R_2}(y - 5.20)^2$
    $= (0.04 + 0 + 0.04) + (0 + 0.01 + 0.01) = 0.08 + 0.02 = 0.10$

对所有切分点计算:

$s$ $R_1$ 均值 $R_2$ 均值 MSE
1.5 4.50 5.04 0.292
2.5 4.60 5.125 0.229
3.5 4.70 5.20 0.100
4.5 4.825 5.20 0.155
5.5 4.92 5.10 0.269

$s = 3.5$ 对应 MSE 最小(0.10),选为根节点切分点。

5.3 CART 的剪枝:代价复杂度剪枝(CCP)

CART 使用代价复杂度剪枝(Cost-Complexity Pruning),也称为最弱链接剪枝(Weakest Link Pruning)。它是 CART 最精巧的部分。

5.3.1 代价复杂度度量

对于一棵决策树 $T$,定义其代价复杂度:

$$R_\alpha(T) = R(T) + \alpha |T|$$

其中:

  • $R(T)$:树 $T$ 在训练数据上的错误率(分类)或 MSE(回归),即经验风险
  • $|T|$:树 $T$ 的叶节点个数,作为模型复杂度的度量
  • $\alpha \geq 0$:复杂度惩罚参数,控制剪枝的强度

$\alpha = 0$:不惩罚复杂度 → 不剪枝(完全生长的树 $T_0$)
$\alpha \to \infty$:极度惩罚复杂度 → 退化为只有根节点的树

5.3.2 剪枝过程

  1. 生成完整树 $T_0$:不断生长直到所有叶节点的样本数小于阈值或纯度为 100%。

  2. 生成剪枝序列:对于 $\alpha$ 从 0 逐渐增大的每个阶段,我们通过”剪掉使 $R_\alpha(T)$ 减少最多的子树”来得到一系列嵌套的子树:

    $$T_0 \supset T_1 \supset T_2 \supset \cdots \supset T_K = \{\text{root}\}$$

    对于内部节点 $t$,定义其剪枝前后的代价差:

    $$g(t) = \frac{R(t) - R(T_t)}{|T_t| - 1}$$

    其中 $R(t)$ 是将该节点作为叶节点时的经验风险,$R(T_t)$ 是以 $t$ 为根的子树 $T_t$ 的经验风险。

    $g(t)$ 越小,说明剪去该子树后增加的误差越小(相对于其复杂度减少来说),越应该被剪。

    每次剪去 $g(t)$ 最小的节点,直到只剩根节点。

    为什么 $g(t)$ 的形式是这样? 考虑两种代价:

    • 剪枝后(节点 $t$ 变叶节点):$R(t) + \alpha$
    • 剪枝前(保留子树 $T_t$):$R(T_t) + \alpha|T_t|$

    当 $R(t) + \alpha \leq R(T_t) + \alpha|T_t|$ 时剪枝更优,即 $\alpha \geq \frac{R(t) - R(T_t)}{|T_t| - 1} = g(t)$。

    所以 $g(t)$ 是使剪枝变得有利的最小 $\alpha$ 值。每次递增 $\alpha$ 到下一个最小的 $g(t)$,剪去对应节点。

  3. 交叉验证选择最优 $\alpha$:使用独立的验证集(或 k 折交叉验证),从 ${T_0, T_1, \ldots, T_K}$ 中选择验证误差最小的那棵。

5.3.3 1-SE 规则

为避免选到过于复杂的树(验证集上的变化可能在统计上不显著),CART 推荐使用 1-SE 规则

在交叉验证中,先找出最小验证误差的树 $T^*$,计算其验证误差的标准误 SE。然后选择满足”验证误差 $\leq$ T*验证误差 + 1 SE”的前提下,最简单的($|T|$ 最小的)那棵树。

直觉:如果两棵树的验证误差差距在一个标准差以内,可以认为没有显著差异;此时选更简单的那棵树更好(奥卡姆剃刀)。


6. 预剪枝与后剪枝

6.1 预剪枝(Pre-pruning)

预剪枝在树生长过程中提前停止分裂。

常用停止条件

  1. 节点样本数下限:当节点中样本数少于阈值(如 50),停止分裂
  2. 节点纯度:当节点的 Gini 指数或熵低于阈值,停止分裂
  3. 信息增益下限:当最优分裂的信息增益小于阈值,停止分裂
  4. 树的深度:当树的深度达到预定上限(如 max_depth = 10),停止分裂
  5. 叶节点数上限:当叶节点总数达到预定上限

优点

  • 简单,计算开销小(不需要先长完整树再剪)
  • 适用于在线学习场景

缺点

  • 短视(Short-sighted):当前看起来”不好”的分裂可能在后续分裂后变得很好。例如 XOR 问题中,单独任何一个特征的分裂都没有信息增益,但两个特征一起就能完美分类。预剪枝会因为第一步增益为 0 而停止,错失好的模型。

6.2 后剪枝(Post-pruning)

后剪枝先生成一棵完全生长的树,然后自底向上地剪去不必要的子树。

方法对比

方法 算法 验证集 评价标准 特点
REP Reduced Error Pruning 需要 验证集错误率 简单但需要额外数据
PEP Pessimistic Error Pruning (C4.5) 不需要 训练集+连续性校正 悲观估计,可能过度剪枝
CCP Cost-Complexity Pruning (CART) 需要(CV) $R_\alpha = R + \alpha T
MEP Minimum Error Pruning 不需要 贝叶斯误差估计 对先验的设定敏感
EBP Error-Based Pruning 不需要 置信区间 C4.5 的后继使用

6.3 预剪枝 vs 后剪枝

维度 预剪枝 后剪枝
计算量 小(一次建树) 大(可能多次评估)
泛化能力 可能欠拟合 通常更好
适用场景 大数据集,需要快速训练 中小数据集,追求精度
实践 sklearn 的决策树默认策略 传统方法(CART, C4.5)
主要风险 短视,错过好的深层交互 需要好的评估策略,否则可能过拟合

在实践中,现代库(如 sklearn)通常同时使用两者:设置 max_depth/min_samples_split 做预剪枝,配合 CCP 做后剪枝(通过 ccp_alpha 参数)。


7. 从决策树到集成学习

7.1 决策树的优势与劣势

决策树作为基学习器,具有两个关键特性使它非常适合做集成:

优势

  1. 表达能力强:可以学习复杂的非线性关系
  2. 对数据预处理要求低:不需要标准化/归一化
  3. 自动处理特征交互:无需手动构造交互特征
  4. 可解释性强:天然为白盒模型

劣势

  1. 高方差:对训练数据的微小扰动很敏感(叶节点结构完全改变)
  2. 容易过拟合:深层树容易记住噪声
  3. 贪心算法:局部最优不等于全局最优
  4. 不稳定:数据的小变化可能导致完全不同的树结构

7.2 Bagging(Bootstrap Aggregating,装袋法)

核心思想:通过对训练数据进行 bootstrap 采样(有放回采样),构建多个略有不同的训练集,每个训练集上训练一棵决策树,最终通过投票(分类)或平均(回归)来降低方差。

Random Forest = Bagging + 随机特征子空间

  • 除了对样本做 bootstrap,还在每个分裂节点随机选择一个特征子集(通常 $\sqrt{d}$ 个特征 for 分类,$d/3$ for 回归)
  • 进一步去相关(decorrelate)各棵决策树,增强集成效果

7.3 Boosting(提升法)

核心思想:串行地训练一系列弱学习器(通常是浅层决策树),每个新学习器都侧重于纠正前一轮集成模型的错误。

  • AdaBoost:通过调整样本权重来关注难分类样本(指数损失)
  • GBDT:每棵树拟合前一轮的负梯度(残差)
  • XGBoost:GBDT + 正则化 + 二阶泰勒展开 + 系统优化
  • LightGBM:基于直方图的 GBDT + 单边梯度采样(GOSS)+ 互斥特征捆绑(EFB)

为什么 boosting 用浅树?

  • Boosting 的核心是 sequential bias reduction,每轮减少前轮集成模型的偏差
  • 单个基学习器不需要很强(通常 depth = 3-6),否则容易过拟合且增加计算开销
  • 这与 Bagging 的哲学相反(Bagging 用深树,通过平均减少方差)

7.4 决策树在集成中的角色总结

集成方法 树的数量 树的深度 并行/串行 主导作用
Random Forest 多(100-1000) 深(完全生长) 并行 降方差
AdaBoost 多(50-100) 极浅(stump/depth=1-3) 串行 降偏差
GBDT 多(100-500) 浅(depth=4-8) 串行 降偏差
XGBoost 多(100-500) 浅(depth=3-6) 串行 降偏差

8. 分裂准则的数学统一与对比

8.1 不纯度度量的一般框架

所有分裂准则可以统一为对节点不纯度(impurity)的度量。设节点 $t$ 包含 $N_t$ 个样本,属于 $K$ 个类别的比例分别为 $p_{t1}, p_{t2}, \ldots, p_{tK}$。

不纯度函数 $i(t)$ 需要满足:

  1. 当所有样本属于同一类时($\exists k: p_{tk} = 1$),$i(t)$ 达到最小值
  2. 当各类样本均匀分布时($\forall k: p_{tk} = 1/K$),$i(t)$ 达到最大值
  3. $i(t)$ 是关于 $(p_{t1}, \ldots, p_{tK})$ 的对称凹函数

三种常见的不纯度函数:

不纯度 公式 $K=2$ 时的形式(令 $p$ 为正类比例)
分类错误率 $1 - \max_k p_{tk}$ $1 - \max(p, 1-p)$
基尼指数 $1 - \sum_k p_{tk}^2$ $2p(1-p)$
交叉熵 $-\sum_k p_{tk} \log_2 p_{tk}$ $-p\log_2 p - (1-p)\log_2(1-p)$

分裂的增益:使用特征 $A$ 分裂节点 $t$ 为子节点 $t_1, \ldots, t_m$ 后的不纯度减少量:

$$\Delta i = i(t) - \sum_{j=1}^{m} \frac{N_{t_j}}{N_t} i(t_j)$$

选择使 $\Delta i$ 最大化的特征和分裂方式。

8.2 三种不纯度函数的比较(二分类)

以二分类为例,令 $p$ 为正类比例,我们对比三种不纯度函数:

$p$ 错误率: $1-\max(p,1!-!p)$ Gini: $2p(1!-!p)$ 熵: $-p\log p - (1!-!p)\log(1!-!p)$
0.00 0.00 0.00 0.00
0.10 0.10 0.18 0.47
0.25 0.25 0.375 0.81
0.50 0.50 0.50 1.00
0.75 0.25 0.375 0.81
0.90 0.10 0.18 0.47
1.00 0.00 0.00 0.00

关键观察

  1. 在 $p=0.5$ 附近,三者的形状非常相似(通过 Taylor 展开可以验证,Gini 和半熵在 $p=0.5$ 处二次近似完全一致)
  2. 远离 $p=0.5$ 时,错误率是分段线性的(最”平”),Gini 是二次的,熵是最”陡”的
  3. 这意味着熵对纯度变化最敏感(轻微的不纯会导致较大的熵增),Gini 居中,错误率最不敏感
  4. 实践中 Gini 和熵选出的分裂几乎总是相同;错误率对纯度不敏感,通常不单独用于决策树分裂

8.3 Gini 指数与方差的等价性(回归视角)

有趣的是,对于二分类问题(类标为 0/1),基尼指数与样本方差之间存在等价关系。

将类标视为 0/1 变量,节点 $t$ 中 $y$ 的方差为:

$$\text{Var}(y|t) = p_t(1-p_t)$$

其中 $p_t$ 是 $y=1$ 的比例。而基尼指数 $\text{Gini}(t) = 2p_t(1-p_t) = 2\text{Var}(y|t)$。

这意味着:CART 分类树的基尼指数分裂准则,等价于将类标视为连续变量后以最小化方差为目标进行分裂。这解释了为什么 CART 能用一个统一的框架(均方误差 / 方差最小化)同时处理分类和回归——分类不过是回归在 0/1 标签上的特例。

从这个角度看,CART 的回归和分类在数学上是完全统一的——唯一的区别在于叶节点的输出:回归取均值,分类取多数投票(或概率估计)。


9. CART 的缺失值处理:代理分裂

CART 对缺失值的处理使用了独特的代理分裂(Surrogate Split)机制,与 C4.5 的权重分配法不同。

8.1 代理分裂的核心思想

对于被选中分裂的特征 $A^*$(主分裂,Primary Split),如果某个样本在 $A^*$ 上有缺失值,CART 使用代理特征来判断该样本应该被分到哪个子节点。

代理分裂的定义:对于主分裂 $(A^*, s^*)$,一个在特征 $A_{\text{sur}}$ 上的分裂 $(A_{\text{sur}}, s_{\text{sur}})$ 如果将训练样本分配到左右子节点的分布与主分裂最接近,则被称为代理分裂。

8.2 代理分裂的搜索

对于给定的主分裂,CART 在其他特征中搜索代理分裂,按照与主分裂的”一致度”排序:

$$\text{agreement} = P(\text{surrogate sends } x \text{ to same child as primary})$$

具体步骤:

  1. 对所有非主分裂特征,搜索使与该特征的最优二分与主分裂分配最一致的那个切分点
  2. 按一致度降序排列代理分裂
  3. 预测时,如果样本在主分裂特征上有缺失,依次尝试第一个、第二个代理分裂,直到找到一个代理特征在该样本上有值

8.3 代理分裂的优势

  1. 利用特征相关性:代理分裂天然利用了特征之间的相关性。例如,如果”家庭收入”缺失,可以用高度相关的”教育程度”作为代理。
  2. 不需要修改样本权重:相比 C4.5 的权重分配法,代理分裂保持每个样本的完整性(一个样本只去一个子节点)。
  3. 模型更稳定:代理特征与主分裂特征的相关性赋予了模型针对缺失模式的鲁棒性。

8.4 C4.5 vs CART 缺失值处理对比

维度 C4.5 CART
训练时 只用无缺失样本计算增益,按比例折扣 正常分裂(或用代理评估)
预测时 权重分配:缺失样本按比例进入各分支 代理分裂:用代理特征判断方向
优势 简单直接 利用特征相关性,更鲁棒
劣势 可能引入偏差 需要为每个分裂搜索代理

10. 多变量决策树

传统决策树在每个节点只用一个特征做测试(轴平行划分)。这在面对倾斜的数据分布时会产生大量碎小的矩形区域。多变量决策树(Multivariate Decision Tree)在每个节点使用多个特征的线性组合来做测试:

$$f(x) = \sum_{j=1}^{d} w_j x_j \leq \theta$$

这就是一个斜决策边界(Oblique Decision Boundary)

9.1 多变量决策树的优势

传统决策树(轴平行)在处理对角分布时需要大量递归分裂来近似斜线,导致树又深又复杂,且容易过拟合。多变量决策树一两个节点就能完成斜线划分。

极端的 XOR 问题:传统决策树需要至少 3 个内部节点才能解决 XOR,而多变量决策树理论上可以一步解决(但在实践中仍然依赖于能否找到合适的线性组合)。

9.2 常见的多变量分裂方法

  1. OC1(Oblique Classifier 1):随机搜索 + 爬山法寻找最优的斜分裂超平面
  2. CART-LC(Linear Combinations):CART 作者 Breiman 提出的一个扩展,使用线性组合做分裂,通过交替优化的方式搜索系数
  3. 神经网络决策树:在每个节点训练一个小型感知机或逻辑回归来做”软”分裂

虽然多变量决策树理论上有优势,但由于分裂的搜索空间从 $O(nd)$(轴平行)爆炸到指数级,实践中很少被使用——集成方法(如 GBDT)在计算效率和预测精度上几乎总是更优。


11. 决策树的不稳定性与集成学习的统计视角

10.1 决策树是高方差学习器

从 Bias-Variance 分解的角度看,决策树(特别是深树)是典型的高方差、低偏差模型。

$$E_{\mathcal{D}}[(y - \hat{f}_{\mathcal{D}}(x))^2] = \text{Bias}^2[\hat{f}(x)] + \text{Var}[\hat{f}(x)] + \sigma^2$$

其中:

  • Bias(偏差):模型在无限多训练集上训练后,平均预测与真实值的差距。深树因为表达能力强,偏差低。
  • Variance(方差):在不同训练集上训练出的模型预测值的波动程度。深树对数据极度敏感,方差高。

如何证明决策树方差高? Bootstrap 实验:对同一分布的多个采样集各自训练一棵决策树(不剪枝),比较它们的结构和预测——你会发现树结构几乎完全不一样(不同根节点、不同分裂顺序、不同叶节点数)。

10.2 Bagging 如何降低方差

如果 $B$ 个模型是独立同分布的,每个方差为 $\sigma^2$,则它们的均值的方差为 $\sigma^2/B$。

但 Bootstrap 得到的 $B$ 个树并非独立——它们共享相同的原始分布,只是采样略有不同。设两棵树的相关性为 $\rho$,则 $B$ 棵树均值的方差约为:

$$\text{Var}(\text{ensemble}) = \rho\sigma^2 + \frac{1-\rho}{B}\sigma^2$$

当 $B \to \infty$,方差趋向 $\rho\sigma^2$。这就是为什么 Random Forest 在 Bootstrap 之外还引入了随机特征子集——目的是降低 $\rho$(使树之间更独立),从而更有效地降低方差。

10.3 Bagging vs Boosting 的偏差-方差视角

Bagging (RF) Boosting (GBDT)
基学习器 强学习器(深树,低偏差高方差) 弱学习器(浅树,高偏差低方差)
集成策略 并行平均 串行加性组合
主要降什么 降方差 降偏差
相关性的作用 $\rho$ 大效果差 → RF 用随机特征降 $\rho$ 相关性是设计的一部分(串行相关)
基学习器深度 深(10+) 浅(3-6)

这一对比揭示了为什么调参时 Random Forest 的 max_depth 通常很大或完全生长,而 GBDT 的 max_depth 通常很小——这两个算法在 Bias-Variance 谱系的两端。


12. 实战:sklearn 决策树参数全解析

12.1 sklearn.tree.DecisionTreeClassifier 的核心参数

在 sklearn 中使用决策树时,以下参数直接控制树的结构和训练行为:

参数 默认值 含义 调优建议
criterion 'gini' 分裂准则:'gini''entropy' 两者效果接近,Gini 更快
max_depth None 树的最大深度 最重要参数,通常 3-15
min_samples_split 2 内部节点再分裂所需最小样本数 增大可防过拟合,常用 10-100
min_samples_leaf 1 叶节点最少样本数 常用 5-50,比 min_samples_split 更直观
min_weight_fraction_leaf 0.0 叶节点最小加权样本比例 用于样本加权场景
max_features None 分裂时考虑的特征数 sqrt, log2 或整数;None=全部特征
max_leaf_nodes None 最大叶节点数 限制总叶节点数,与 max_depth 互斥
min_impurity_decrease 0.0 分裂所需最小不纯度减少量 等价于 CCP 的预剪枝版本
ccp_alpha 0.0 代价复杂度剪枝参数 >0 时启用 CCP 剪枝
class_weight None 类别权重 'balanced' 自动按频率反比加权

12.2 剪枝路径可视化

使用 sklearn 寻找最优 ccp_alpha 的标准流程:

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

# 先完整生长
clf = DecisionTreeClassifier(random_state=0)
path = clf.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas, impurities = path.ccp_alphas, path.impurities

# 对每个 alpha 训练一棵树,记录验证精度
clfs = []
for ccp_alpha in ccp_alphas:
clf = DecisionTreeClassifier(random_state=0, ccp_alpha=ccp_alpha)
clf.fit(X_train, y_train)
clfs.append(clf)

train_scores = [clf.score(X_train, y_train) for clf in clfs]
test_scores = [clf.score(X_test, y_test) for clf in clfs]

# 选择验证精度最高的 alpha
best_alpha = ccp_alphas[np.argmax(test_scores)]

12.3 特征重要性计算

决策树天然提供特征重要性度量。sklearn 中的计算方式:

$$\text{importance}(j) = \frac{\sum_{t: \text{split on feature } j} N_t \cdot \Delta i(t)}{\sum_{t \in \text{all internal nodes}} N_t \cdot \Delta i(t)}$$

即特征 $j$ 在所有使用它的分裂节点上的不纯度减少量(按样本数加权)的归一化值。

注意:基于不纯度减少的特征重要性对高基数的特征有偏倚(与信息增益的问题同源)。对于集成模型(如 Random Forest),可以使用 permutation importance 作为更无偏的替代度量。


13. 面试高频问答

Q1: ID3、C4.5、CART 三种决策树算法有什么区别?

A: 核心区别有四点:

  1. 特征选择准则:ID3 用信息增益(偏向多值特征),C4.5 用信息增益比(校正多值偏倚),CART 用 Gini 指数(分类)或 MSE(回归)。
  2. 树的结构:ID3 和 C4.5 生成多叉树(每个特征取值一个分支),CART 只生成二叉树(二分递归)。
  3. 功能范围:ID3 只能分类,C4.5 能分类但不原生支持回归,CART 分类和回归都能做。
  4. 剪枝策略:ID3 不剪枝,C4.5 用悲观错误剪枝(PEP,不需要验证集),CART 用代价复杂度剪枝(CCP,使用交叉验证)。
  5. 附加功能:C4.5 支持连续值和缺失值处理(CART 也支持但方法不同)。C4.5 用二分法处理连续值,CART 用遍历所有可能的二分切分点。

Q2: 为什么信息增益会偏向于选择取值较多的特征?如何校正?

A: 考虑一个极端例子:把样本 ID 作为特征。按 ID 分裂后,每个子节点只有一个样本,条件熵 $H(D|ID) = 0$,信息增益达到最大。但这个特征毫无泛化价值——它只是在”背诵”训练数据。

数学上:$g(D, A) = H(D) - H(D|A) = H(D) - \sum_i \frac{|D_i|}{|D|}H(D_i)$。当 $A$ 取值很多时,每个 $D_i$ 的规模很小(极端情况为 1),每个 $H(D_i)$ 倾向于接近 0,导致条件熵很小,信息增益很大。

C4.5 的校正方法:除以分裂信息 $H_A(D) = -\sum_i \frac{|D_i|}{|D|}\log_2\frac{|D_i|}{|D|}$,得到信息增益比。分裂信息 $H_A(D)$ 同样随特征取值变多而增大,因此起到惩罚作用。举例来说,样本 ID 的分裂信息是 $\log_2 N$(均匀分布),除以这么大的分母后,增益比就变得很小了。

Q3: CART 回归树的预测值为什么取叶节点内样本的均值?

A: 从优化角度,给定一个区域的样本 ${(x_i, y_i)}{i \in R}$,我们要找一个常数 $c$ 来拟合这些样本,最小化平方误差 $\sum{i \in R}(y_i - c)^2$。对 $c$ 求导令为 0:

$$\frac{d}{dc}\sum_{i \in R}(y_i - c)^2 = -2\sum_{i \in R}(y_i - c) = 0 \Rightarrow \sum_{i \in R} y_i = |R| \cdot c \Rightarrow c = \frac{1}{|R|}\sum_{i \in R} y_i$$

所以均值是平方误差下的最优常数拟合。类似地,如果是绝对误差(MAE),最优常数是中位数;这正是分位数回归树的基础。

Q4: 解释代价复杂度剪枝(CCP)的原理和 $\alpha$ 参数的作用。

A: CCP 的目标函数是 $R_\alpha(T) = R(T) + \alpha|T|$。其中 $R(T)$ 是训练误差(经验风险),$|T|$ 是叶节点数。

  • $\alpha = 0$:不惩罚复杂度,保持完整树 $T_0$(经验风险最小但过拟合)
  • $\alpha \to \infty$:复杂度惩罚极大,剪到只剩根节点

CCP 通过以下步骤找到最优的 $\alpha$:

  1. 从 $T_0$ 开始,对每个内部节点计算 $g(t) = \frac{R(t) - R(T_t)}{|T_t|-1}$(”剪枝的性价比”)
  2. $g(t)$ 越小,说明剪掉该子树带来的误差增加越少(相比其复杂度减少),越该剪
  3. 每次递增 $\alpha$ 到下一个最小的 $g(t)$,剪掉对应节点,得到一个剪枝序列

最终通过交叉验证从这个序列中选出最优树。1-SE 规则进一步建议选择最简单但验证误差在 1 个标准误内的树,以获得更稳定的泛化性能。

Q5: 决策树如何处理连续值特征?

A: C4.5 和 CART 都处理连续值,但方法略有不同:

  • 共同点:将连续特征值排序,在相邻值的”中点”构造候选切分点,计算每个候选点的分裂准则值(信息增益/Gini),选最优的。
  • C4.5 方式:$A \leq t$ vs $A > t$(二分)。注意同一个连续特征在后续子树中可以被再次使用(因为只切了一部分)。
  • CART 方式:同样是二分搜索 $j$(哪个特征)和 $s$(在哪个值切)。CART 的搜索更彻底:对每个特征的每个可能切分点都算 Gini/MSE。

复杂度都是 $O(n \log n)$(排序)+ $O(n)$(扫描切分点),总体对 $d$ 个特征来说是 $O(d n \log n)$。

Q6: 决策树的过拟合现象如何诊断?怎样解决?

A:

  • 诊断:决策树的深度过大(远超特征数的 log)通常就是过拟合信号。定量上看训练集准确率接近 100% 但验证/测试集准确率明显低。叶节点中样本数极少(如 1-2 个)也是一个标志。
  • 解决方案
    1. 剪枝:后剪枝(CCP/PEP)或预剪枝(限制 max_depth, min_samples_split, min_samples_leaf)
    2. 集成学习:使用 Random Forest 或 GBDT 来降低方差
    3. 限制特征:只使用最相关的特征子集
    4. 增大数据集:更多数据意味着树更难”记住”每个样本
    5. 引入噪声鲁棒性:对连续特征做分箱(binning)可以减少对噪声的敏感度

Q7: 什么时候应该用决策树而不是逻辑回归或 SVM?

A:

  1. 数据层面:数据有明显的分段结构(如条件规则 “if-then”),决策树的表达能力天然匹配
  2. 特征层面:特征中有大量分类变量或缺失值(决策树天然处理,而 LR/SVM 需要预处理);特征间的交互效应很重要(决策树自动捕获,而 LR 需要手动构造交互项)
  3. 模型要求:需要完全可解释的模型(如金融风控的监管合规场景),决策树的 if-then 规则直接可读
  4. 工程层面:特征尺度不一致且不想做标准化(决策树不受影响);需要快速 baseline(决策树训练快)
  5. 集成场景:需要用 GBDT/Random Forest 等 tree-based ensemble 时,决策树是唯一的基学习器选择

Q8: 为什么 CART 只生成二叉树?

A: 有三个主要原因:

  1. 统一处理离散和连续特征:连续特征的二分切分天然产生二叉树。将类别特征也统一为二分(如 $A = a$ vs $A \neq a$),简化了算法实现。
  2. 降低碎片化:多叉分裂将数据切分得越来越碎(每个子节点样本数太小),不利于泛化。二叉树保证了每个子节点都能保留足够多的样本,统计上更稳定。多叉分裂下,一个有 $m$ 个取值的类别特征会将数据分为 $m$ 份,样本迅速被碎片化;二叉树每步只分成两份,更渐进地”消耗”数据。
  3. 理论上没有损失:任何多叉分裂都可以表示为一串二叉树分裂的组合。例如,将数据按颜色(红/蓝/绿)三分,等价于先按”是否红色”二分,再将非红子集按”是否蓝色”二分。二叉树的表达力完全等价于多叉树,不会丢失任何决策边界。

Q9: 决策树训练时熵的对数计算以什么为底?影响是什么?

A: 信息论中,以 2 为底时熵的单位是 bit,以 $e$ 为底时单位是 nat,以 10 为底时单位是 dit(或 hartley)。底数选择影响熵的绝对数值,但不影响信息增益的相对大小——因为底数转换只是一个全局的乘法因子:$\log_2(x) = \ln(x) / \ln(2)$。由于信息增益 $g = H(D) - H(D|A)$ 是熵的线性组合,换底相当于乘一个常数,不影响不同特征间的相对排序。实践中通常以 2 为底(符合计算机科学的 bit 语义),sklearn 的熵实现使用以 $e$ 为底的自然对数(np.log),因为计算上更高效。


14. 总结

决策树是机器学习中最基础的模型之一。从 ID3 到 C4.5 再到 CART,三代算法逐步解决了信息增益偏倚、连续值处理、缺失值处理、剪枝策略和回归能力等核心问题。这是理解一切树模型和集成方法的起点。

核心知识地图

决策树学习三问
├── 特征选择(用什么分?)
│ ├── ID3:信息增益 (Information Gain)
│ ├── C4.5:信息增益比 (Gain Ratio) → 校正多值偏倚
│ └── CART:基尼指数 (Gini) 或 最小化 MSE
├── 决策树生成(怎么长树?)
│ ├── ID3/C4.5:多叉树,递归分裂
│ └── CART:二叉树,二分递归分裂
└── 决策树剪枝(怎么剪枝?)
├── C4.5:PEP (Pessimistic Error Pruning) → 不需要验证集
├── CART:CCP (Cost-Complexity Pruning) → CV 选 α
└── sklearn:预剪枝 (max_depth, min_samples_split) + CCP (ccp_alpha)

决策树的重要性不止于它作为一个独立模型的价值。以决策树为基学习器的集成方法——Random Forest、GBDT、XGBoost、LightGBM、CatBoost——统治了表格数据建模领域长达二十年,至今仍是 Kaggle 竞赛和工业 Tabular 建模的事实标准。深入理解决策树的原理(特别是特征选择、分裂机制和剪枝策略),是理解这些高级算法的必要条件。


本系列下一篇文章将深入探讨提升算法(AdaBoost/GBDT/XGBoost/LightGBM/CatBoost),揭示从弱学习器到强学习器的奥秘,敬请期待。


扩展阅读推荐

  • Breiman et al. (1984), Classification and Regression Trees — CART 的原始著作,统计学习理论基石
  • Quinlan (1993), C4.5: Programs for Machine Learning — C4.5 的完整技术文档
  • Hastie et al. (2009), The Elements of Statistical Learning, Chapters 9, 10, 15 — 决策树与集成学习的圣经级综述
文章作者: Leo·Cheung
文章链接: http://tufusi.com/2021/07/25/%E3%80%90%E7%BB%9F%E8%AE%A1%E5%AD%A6%E4%B9%A0%E6%96%B9%E6%B3%95%E6%AD%BB%E7%A3%95%E7%B3%BB%E5%88%97%E3%80%91%E5%86%B3%E7%AD%96%E6%A0%91/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ONE·PIECE
打赏
  • 微信
  • 支付宝

评论