CART算法

分类与回归树(CART)是应用广泛的算法,同样由特征选择、树的生成及剪枝组成,可以用于解决分类和回归问题。

ID3算法、C4.5算法分别使用了信息增益、信息增益比来选择特征,他们都使用了包含大量的对数运算的熵模型来计算样本纯度。而CART算法使用基尼系数来代替信息增益(比),基尼系数代表了模型的不纯度,基尼系数越小,则不纯度越低,特征越好。这和信息增益(比)是相反的。

CART决策树的生成过程是递归构建二叉树的过程。对于分类树,使用基尼指数最小化准则;对回归树,使用平方误差最小化准则。

CART回归树生成

构建回归树有两个问题:

(1) 如何得到预测结果?

(2) 如何对输入空间进行划分?

一颗回归树是输入空间的一个划分,以及在划分单元的输出值。假设输入空间已经划分为M个:R1,R2,...,RMR_1, R_2, ..., R_M,并且在每个单元RmR_m有一个固定的输出值cmc_m,于是回归树模型可表示为:
f(x)=m=1McmI(xRm) f(x) = \sum_{m=1}^{M} c_m I(x \in R_m)
可以用平方误差xiRm(yif(xi))2\sum_{x_i \in R_m} (y_i - f(x_i))^2来表示回归树的预测误差,用平方误差最小的准则求解每个单元的最优输出值。

对于第一个问题,单元RmR_m上的cmc_m的最优值c^m\hat c_mRmR_m上所有输入实例xix_i对应的输出yiy_i的均值,即:
c^m=ave(yi  xiRm) \hat{c}_m = ave(y_i \ | \ x_i \in R_m)
那么如何对输入空间进行划分?可以采用启发式的方法,选择样本x的第j个特征x(j)x^{(j)}和它的均值s作为切分变量和切分点。定义两个区域:
R1(j,s)={x  x(j)s} R2(j,s)={x  x(j)>s} R_1(j, s) = \{x \ | \ x^{(j)} \leqslant s\}\\ \ R_2(j, s) = \{x \ | \ x^{(j)} > s\}
然后寻找最优切分变量 j 和最优切分点 s,具体地就是遍历所有特征的所有切分点,求解:
minj,s [minc1xiR1(j,s)(yic1)2+minc2xiR2(j,s)(yic2)2] \min_{j, s} \ [ \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]
其中,c1c_1为R1数据集的样本输出均值,c2c_2为R2数据集的样本输出均值:
c^1=ave(yi  xiR1(j,s)), c^2=ave(yi  xiR2(j,s)) \hat{c}_1 = ave( y_i \ | \ x_i \in R_1(j, s)), \ \hat{c}_2 = ave( y_i \ | \ x_i \in R_2(j, s))
遍历所有输入变量,找到最优的切分变量 j,构成一个对(j,s)。依次将输入空间划分为两个区域。对每个区域重复上述划分过程,直到满足停止条件位置,这样的回归树通常称为最小二乘回归树,算法叙述如下:

输入:训练数据集DD

输出:回归树f(x)f(x)

步骤:

  1. 遍历变量jj,对固定的切分变 量jj 扫描切分点ss,得到满足下面关系的(j,s)(j,s)
    minj,s[minc1xiR1(j,s)(yic1)2+minc2xiR2(j,s)(yic2)2] \min\limits_{j,s}\left[\min\limits_{c_1}\sum\limits_{x_i\in R_1(j,s)}(y_i-c_1)^2+\min\limits_{c_2}\sum\limits_{x_i\in R_2(j,s)}(y_i-c_2)^2\right]

  2. 用选定的(j,s)(j,s), 划分区域并决定相应的输出值
    R1(j,s)={xx(j)s},R2(j,s)={xx(j)>s}c^m=1NxiRm(j,s)yj,xRm,m=1,2 R_1(j,s)=\{x|x^{(j)}\leq s\}, R_2(j,s)=\{x|x^{(j)}> s\} \\ \hat{c}_m= \frac{1}{N}\sum\limits_{x_i\in R_m(j,s)} y_j, x\in R_m, m=1,2

  3. 对两个子区域调用(1)(2)步骤, 直至满足停止条件

  4. 将输入空间划分为MM个区域R1,R2,,RMR_1, R_2,\dots,R_M,生成决策树:
    f(x)=m=1Mc^mI(xRm) f(x)=\sum_{m=1}^M\hat{c}_mI(x\in R_m)

CART分类树的生成

分类树使用基尼指数选择最优特征,同时决定该特征的最优二值切分点。

假设有K个类,样本点属于k类的概率为pkp_k,则概率分布的基尼指数定义为:
Gini(p)=k=1Kpk(1pk)=1k=1Kpk2 Gini(p) = \sum_{k=1}^{K}p_k (1 - p_k) = 1 - \sum_{k=1}^{K} {p_k}^2
对于二分类问题:
Gini(p)=2p(1p) Gini(p) = 2p(1-p)
对于给定样本集合D,其基尼指数为:
Gini(D)=1k=1K(CkD)2 Gini(D) = 1 - \sum_{k=1}^{K} (\frac{|C_k|}{|D|})^2
如果D按照特征A是否取某个值a,分割为子集D1,D2D_1, D_2两个部分,即D1={(x,y)D  A(x)=a},D2=DD1D_1 = \{(x, y) \in D \ | \ A(x) = a\}, D_2 = D - D_1,则在特征A的条件下,集合D的基尼指数为:
Gini(D,A)=D1DGini(D1)+D2DGini(D2) Gini(D, A) = \frac{|D_1|}{|D|} Gini(D_1) + \frac{|D_2|}{|D|} Gini(D_2)
Gini值越大,样本集合的不确定性也越大(与熵类似),因此每次选择Gini小的特征来划分。

连续值处理:

CART分类树对连续值的处理思路和C4.5是相同的,都是将连续的特征离散化。

具体来说,假设有m个样本,都包含连续特征A,特征A的取值从小到大排序后用:a1,a2,...,am{a_1,a_2,...,a_m}表示,则CART算法取相邻两样本值的平均数,一共取得m-1个划分点,其中第i个划分点TiT_i表示为:Ti=ai+ai+12T_i = \frac{a_i+a_{i+1}}{2}。对于这m-1个点,分别计算以该点作为二元分类点时的基尼系数。选择基尼系数最小的点作为该连续特征的二元离散分类点。比如取到的基尼系数最小的点为ata_t,则小于ata_{t}的值为类别1,大于ata_{t}的值为类别2,这样我们就做到了连续特征的离散化。要注意的是,与ID3或者C4.5处理离散属性不同的是,如果当前节点为连续属性,则该属性后面还可以参与子节点的产生选择过程。

离散值处理:

如果某个特征A被选取建立决策树节点,如果它有A1,A2,A3三种类别,我们会在决策树上一下建立一个三叉的节点。这样导致决策树是多叉树。但是CART分类树使用的方法不同,他采用的是不停的二分,还是这个例子,CART分类树会考虑把A分成{A1}和{A2,A3},{A2}和{A1,A3} {A3}和{A1,A2}三种情况,找到基尼系数最小的组合,比如{A2}和{A1,A3},然后建立二叉树节点,一个节点是A2对应的样本,另一个节点是{A1,A3}对应的节点。同时,由于这次没有把特征A的取值完全分开,后面我们还有机会在子节点继续选择到特征A来划分A1和A3。这和ID3或者C4.5不同,在ID3或者C4.5的一棵子树中,离散特征只会参与一次节点的建立。

结合上面的知识,总结得到算法流程如下:

输入:训练数据集D,基尼系数的阈值,样本个数阈值。

输出:决策树T。

根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树:

  1. 设结点的训练数据集为D,计算现有特征对该数据集的基尼指数。此时,对每一个特征A,对其可能取的每个值a,根据样本点对A=a的测试为“是"或“否”,将D分割成D1D_1D2D_2两部分,计算A=aA=a时的基尼指数。

  2. 在所有可能的特征A以及它们所有可能的切分点a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。

  3. 对两个子结点递归地调用(1),,(2),直至满足停止条件。

  4. 生成CART决策树。

算法停止计算的条件是结点中的样本个数小于预定阈值,或样本集的基尼指数小于预定阈值(样本基本属于同-类),或者没有更多特征。

对于生成的决策树做预测的时候,假如测试集里的样本A落到了某个叶子节点,而节点里有多个训练样本,则对于A的类别预测采用的是这个叶子节点里概率最大的类别。

举个同样的例子:

分类与回归树(CART)相关知识

分别用A1,A2,A3,A4A_1,A_2,A_3,A_4表示年龄、有工作、有房子、贷款情况4个特征,则有:
Gini(D,A1=1)=515(2×25×(125))+1015(2×710×(1710))=0.44Gini(D,A1=2)=0.48Gini(D,A1=3)=0.44 \begin{aligned} & Gini(D,A_1=1)=\frac{5}{15}(2 \times \frac{2}{5} \times (1-\frac{2}{5})) + \frac{10}{15}(2 \times \frac{7}{10} \times (1-\frac{7}{10})) = 0.44 \\ & Gini(D,A_1=2)=0.48\\ & Gini(D,A_1=3)=0.44 \end{aligned}
由于Gini(D,A1=1)Gini(D,A_1=1)Gini(D,A1=3)Gini(D,A_1=3)最小且相等,所以A1,A3A_1, A_3都可以作为最优切分点。同理可以得到A2,A3A_2,A_3的基尼指数:
Gini(D,A2=1)=0.32Gini(D,A3=1)=0.27 Gini(D,A_2=1) = 0.32 \\ Gini(D,A_3=1) = 0.27
由于A2,A3A_2,A_3只有一个切分点,所以基尼指数最小的即为对应特征的最优切分点。

A4A_4的基尼指数:
Gini(D,A4=1)=0.36Gini(D,A4=2)=0.47Gini(D,A4=3)=0.32 Gini(D,A_4=1) = 0.36 \\ Gini(D,A_4=2) = 0.47\\ Gini(D,A_4=3) = 0.32
Gini(D,A4=3)Gini(D,A_4=3)最小,所以A4=3A_4=3A4A_4的最优切分点。

A1,A2,A3,A4A_1,A_2,A_3,A_4的特征中,Gini(D,A3=1)=0.27Gini(D,A_3=1)=0.27最小,所以选择A3A_3为最优特征,A3=1A_3=1为最优切分点,于是生成了两个子节点。左子节点是叶节点,右子节点则需要继续在A1,A2,A4A_1,A_2,A_4中选择最优切分点,如此往复,知道所以节点都是叶节点。

CART 剪枝

CART回归树和CART分类树的剪枝策略除了在度量损失的时候一个使用均方差,一个使用基尼系数,算法基本完全一样,这里我们一起来讲。

CART剪枝算法分为两步:

  1. 首先从CART生成算法产生的原始决策树T0T_0的底端开始,不断剪枝,直到T0T_0的根节点,从而获得一个子树序列{T0,T1,...,TnT_0,T_1,...,T_n};

  2. 通过交叉验证子树序列中的每个子树进行测试,从中选择最优子树作为最终的剪枝结果;

先看第一步,要明白如何构建{T0,T1,...,TnT_0,T_1,...,T_n}。T0T_0好理解,就是未经剪枝的决策树,T1T_1怎么来的?

T1T_1T0T_0的子树,意味着子树T1T_1的损失函数至少要≤剪枝前T0T_0的损失函数(剪枝前后损失函数不变,但剪枝后复杂度降低,亦可以剪枝)。CART树T剪枝时,子树T的损失函数如下:
Cα(T)=C(T)+αT C_{\alpha}(T) = C(T) + \alpha |T|
其中,C(T)C(T)为训练数据的预测误差,对回归而言可以是平方误差和,对分类而言可以是sum(gini×sum(每个叶子节点的gini 值\times叶子节点样本数目)

当α=0时,损失函数等于预测误差,相当于不进行剪枝,对应的最优子树即决策树本身;α越大,则惩罚越大,会得到更加简单的树,即剪枝幅度更大;

由于树的叶子个数是离散值,所以给定α后,必定存在某个子树TαT_\alpha使得损失函数Cα(T)C_{\alpha}(T)取得最小值。于是只要确定序列{α0,α1,...,αnα_0,α_1,...,α_n}就能确定对应的最佳子树序列{T0,T1,...,TnT_0,T_1,...,T_n}。因此,目标为找到合适的α序列的构造。

我们将α序构造为递增的序列,则子树序列T是满树到根节点树的递减树序列。首先令α0=0α_0=0,决策树本身为T0T_0,在T0T_0上进行第一次剪枝(构造α1α_1),由于剪枝后的损失函数要≤剪枝前,因此,如果想在内部节点t处剪枝(即只保留节点t,左右子树删除),只需要将问题聚焦于节点t以及t节点对应的子树TtT_t上。

若在节点t处需要剪枝,则剪枝后的t变为了叶节点,对应的损失函数为:
Cα(t)=C(t)+α×1(1) C_\alpha(t) = C(t) + \alpha \times 1 \tag 1
若不进行剪枝,则t及其子树TtT_t的损失函数为:
Cα(Tt)=C(Tt)+αTt(2) C_\alpha(T_t) = C(T_t) + \alpha | T_t | \tag 2
由于剪枝是为了降低损失函数或者简化树模型,于是有:
Cα(Tt)Cα(t) C_\alpha(T_t) \le C_\alpha(t)
将式子(1)、(2)代入得到:
C(t)+αC(Tt)+αTt(2) C(t) + \alpha \le C(T_t) + \alpha | T_t | \tag 2
解得:
αC(t)C(Tt)Tt1 \alpha \ge \frac{C(t) - C(T_t)}{|T_t| - 1}
即当α[0,C(t)C(Tt)Tt1)\alpha \in [0, \frac{C(t) - C(T_t)}{|T_t| - 1})时,不满足剪枝条件,若要满足剪枝条件,至少有αmin=C(t)C(Tt)Tt1\alpha_{min} = \frac{C(t) - C(T_t)}{|T_t| - 1},此时虽然损失函数没有减少,但是可以简化决策树,达到了剪枝的条件。我们记:
g(t)=αmin=C(t)C(Tt)Tt1 g(t) =\alpha_{min} = \frac{C(t) - C(T_t)}{|T_t| - 1}
对于一颗要剪枝的树,自下而上地对内部每个内部节点 t 计算g(t)g(t),然后减去g(t)g(t)取值最小的TtT_t,将得到的子树作为T1T_1。为什么取最小的g(t)g(t),是因为要保证α\alpha序列是递增的,每次取最小的αmin\alpha_{min}可以保证不遗漏任何可以剪枝的情况。每次得到αmin\alpha_{min}的同时,TtT_t也随之得到了,于是可以同时得到序列{α0,α1,...,αnα_0,α_1,...,α_n}和{T0,T1,...,TnT_0,T_1,...,T_n}。

接下来进行第二步,在获得了可以剪枝的最优子树序列{T0,T1,...,TnT_0,T_1,...,T_n}之后,再将每棵树进行交叉验证,交叉验证结果最好的那颗子树便是最终的剪枝结果。

CART剪枝算法流程如下:

输入: CART算法生成的决策树T0T_0

输出: 最优决策树TαT_α

(1) 设k=0,T=T0k=0, T=T_0

(2) 设α=+α= +∞。.

(3) 自下而上地对各内部结点 t 计算C(Tt),TtC(T_t), |T_t|以及
g(t)=C(t)C(Tt)Tt1α=min(α,g(t)) g(t) = \frac{C(t) - C(T_t)}{|T_t| - 1} \\ α = min(α, g(t))

这里,TtT_t表示以t为根结点的子树,C(Tt)C(T_t)是对训练数据的预测误差,Tt|T_t|TtT_t的叶结点个数。

(4) 对g(t)=αg(t)=\alpha的内部结点t进行剪枝,并对叶结点t以多数表决法决定其类,得到树T。

(5) 设k=k+1,αk=α,Tk=Tk=k+1, \alpha_k=\alpha, T_k= T

(6) 如果TkT_k不是由根结点及两个叶结点构成的树,则回到步骤(2); 否则令Tk=TnT_k= T_n

(7) 采用交叉验证法在子树序列{T0,T1,...,TnT_0,T_1,...,T_n}中选取最优子树TαT_{\alpha}

参考文章:

《统计学习方法 第二版》

决策树算法原理(上)

决策树算法原理(下)

cart树怎么进行剪枝?[椒盐砒霜叶小沐]

相关文章:

  • 2021-12-08
  • 2021-06-12
  • 2021-07-10
  • 2021-10-12
  • 2021-10-05
  • 2021-09-29
  • 2022-12-23
  • 2021-07-15
猜你喜欢
  • 2021-10-08
  • 2021-04-12
  • 2022-01-23
  • 2022-12-23
  • 2022-01-29
相关资源
相似解决方案