CART剪枝算法详解

CART剪枝算法

CART剪枝算法从“完全生长“的决策树的底端剪去一些子树,使决策树变小(模型变简单),从而能够对未知数据有更准确的预测。CART剪枝算法由两步组成:首先从生成算法产生的决策树T0底端开始不断剪枝,直到T0的根节点,形成一个子树序列{T0,T1 ,…, Tn};然后通过交叉验证法在独立的验证数据集上对子树序列进行测试,从中选择最优子树。

1. 剪枝,得到子树序列

子树的损失函数:
            C α ( T ) = C ( T ) + α ∣ T ∣ {C_\alpha }(T) = C\left( T \right) + \alpha \left| T \right| Cα(T)=C(T)+αT
  T为任意子树,C(T)为对训练数据的预测误差,可以是基尼指数,|T|为子树T的叶子节点个数,α>= 0为参数,Cα(T)为参数是α时的子树T的整体损失,|T|衡量树的复杂度,α权衡训练数据的拟合程度与树的复杂度。
为了使得损失函数减小,有两种办法:
1> 降低第一部分的不确定次数,但我们知道这是不可能的了,因为降低不确定次数的办法是再找寻一个特征,或者找寻特征的最优切分点。这在生成决策时就已经决定了,无法改变。 (换句话说就是使得子树T的预测误差下降,这可能就要重新选择特征)
2> 进行剪枝操作,这是可以的。剪枝最明显地变化就是叶结点个数变少。假设是一个三叉树,那么一次剪枝它的叶结点数减少2个。变化量为2α,有了这变化量,我们就可以用来求解最优决策子树了。

       在α参数给定时,假设只有一个子结点发生剪枝,那么该子结点上的叶结点都将全部归并到该结点,由此我们计算此结点的不确定次数。倘若不确定次数增大的量超过2α,那么剪枝失败,算法将尝试其他子结点。因为新得的子树损失函数反而增大。  这从侧面又反映了什么样的事实?  该子结点的分类规则大大降低了不确定次数,并不存在噪声,所以没必要进行剪枝。所以在剪枝过程中,找寻的就是那些噪声点,被过度规则的那些子结点,把这些合并了,万事大吉,自然而然决策树的准确率将上升。

       那么问题来了,α是未知的,从函数和以上的分析中我们可以看出α的值对剪枝结果有很大的影响,我们如何找到这个合适的α来使拟合程度与复杂度之间达到最好的平衡呢,最好的办法就是,我们将α从0取到正无穷,对于每一个固定的α,我们都可以找到使得Cα(T)最小的最优子树T(α) 。当α 很小的时候,T0是最优子树,当α很大的时候,单独一个根节点Tn是最优的子树。(Breiman等人证明:可以用递归的方法对树进行剪枝,将a从小增大,a0

我们通过无限个α去求有最优的子树序列式很困难的,是一个NP完全问题,那怎么办呢?

       这里有一个前提,对固定的α,一定存在使损失函数Cα(T)最小的子树,将其表示为Tα。Tα在损失函数最小的意义下是最优的,这样的最优的子树是唯一的。其实所要表达的意思就是Tα和α是一一对应的。
我们通过无限个α去求最优的子树序列是很困难的,但是根据剪枝的核心思想我们知道,无论多么复杂的决策树,生成的最优子树序列都是有限的,这里记作{T0,T1 ,…, Tn},那么我们只需要寻找每一个最优子树对应的α不就可以了嘛。

       如上分析,我们现在的思路就是要得出最优子树序列,这子树序列又如何生成呢?(怎么感觉说着说着又说回来了呢,我们的最终结果不就是要得到这些最优子树序列吗?为什么还要记录相应的α值呢?这个本人也不胜理解)我们先说说求子树序列的事情。

       我们先假设我们找到了当前的最优子树,且必然发生剪枝(一定要注意这句话,这是我们接下来所有推导的前提)。具体地,从整体树T0开始剪枝,我们每次剪枝剪的都是某个内部节点的子节点,也就是将某个内部节点的所有子节点回退到这个内部节点里,并将这个内部节点作为叶子节点。因此在计算整体的损失函数时,这个内部节点以外的值都没变,只有这个内部节点的局部损失函数改变了,因此我们本需要计算全局的损失函数,但现在只需要计算内部节点剪枝前和剪枝后的损失函数。

对任意内部节点t,
剪枝前的状态:有|Tt| 个叶子节点,预测误差是C(Tt)
剪枝后的状态:只有本身一个叶子节点,预测误差是C(t)
剪枝前以t结点为根结点的子树的损失函数是:
C α ( T t ) = C ( T t ) + α ∣ T t ∣ {C_\alpha }({T_{\rm{t}}}) = C\left( {{T_t}} \right) + \alpha \left| {{T_t}} \right| Cα(Tt)=C(Tt)+αTt剪枝以后以t为单结点树的损失函数是: C α ( t ) = C ( t ) + α {C_\alpha }(t) = C\left( t \right) + \alpha Cα(t)=C(t)+α
当alpha=0及alpha充分小,有不等式 C α ( T t ) < C α ( t ) {C_\alpha }({T_t}) < {C_\alpha }(t) Cα(Tt)<Cα(t)
当alpha增大时,在某一alpha有
C α ( T t ) = C α ( t ) ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ( 1 ) {C_\alpha }({T_t}) = {C_\alpha }(t)·······(1) Cα(Tt)=Cα(t)1
当alpha再增大时,以上不等式(1)反向。在(1)式的情况下, α 1 = C ( t ) − C ( T t ) ∣ T t ∣ − 1 {\alpha _1} = \frac{{C(t) - C({T_t})}}{{\left| {{T_t}} \right| - 1}} α1=Tt1C(t)C(Tt)我们之前假设在得到最优子树时必然发生了剪枝,那么什么时候必然发生剪枝?当我们取得损失函数中的α>=α1时,必然对Tt进行剪枝,因为此时剪枝后损失函数的值要比剪枝前小。

       那是不是剪掉当前的t结点就可以得到最优子树了呢,当然不是,不同的结点会计算出不同的α1,我们就以此α1作为损失函数的α值(解释一下,当α=α1时,该节点剪枝前后的损失函数的值是一样的,但是剪枝后结点少,也必然要剪枝,此时该结点处的损失函数值也是最小的),这时会算出不同的损失函数值来,当然是取损失函数值最小的结点来剪枝。这里我们将结点t作为变量,计算得到的α记为α(t),则有如下公式: min ⁡ t C ( t ) + α ( t )         ( 2 ) \mathop {\min }\limits_t C(t) + \alpha (t)    (2) tminC(t)+α(t)    2但是在李航的《统计学习方法》中却用以下公式来衡量应该剪枝的结点: g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1     ( 3 ) g(t) = \frac{{C(t) - C({T_t})}}{{\left| {{T_t}} \right| - 1}}  (3) g(t)=Tt1C(t)C(Tt)  3       有一篇博文是这样解释的:整体损失函数 = 内部节点t的损失函数 + 其他节点的损失函数和 我们在计算2式的时候只是让等号右边的第一项达到了最小,可是局部结点的损失函数最小并不能代表整体的损失函数最小,所以并不能以2式来剪枝。但本人认为这种说法经不起推敲,如果我们对2式了解透彻的话应该知道,在α确定的情况下,整体的损失函数的计算相当于是对局部结点损失函数的累加,在某个结点剪枝而其他结点不改变的情况下,2式等号右边的第二项并没有变化,因此这并不能说明问题。但我们可以这样说,针对单个结点的剪枝我们可以用2式来衡量,可多个结点的剪枝用这种局部结点的计算公式是行不通的。

       而α就不一样了,在上面已经说过了,剪枝得到的子树序列对应着区间[ai,ai+1),i =0,1,…,n的最优子树序列{T0, T1, … , Tn},我们在不同的α(g(t))下剪枝可以得到一一对应的有限个最优子树。在李航的《统计学习方法》中,将g(t)解释为剪枝后整体的损失函数减少额程度,如果不看之前的推导,只看公式3,我们是可以理解的,其实这跟信息增益的概念差不多,但加入了结点个数这个变量来权衡模型复杂度的影响。在T0中剪去g(t)最小的Tt,将得到的子树作为T1,同时将最小的g(t)设为α1。T1为区间[α1, α2)的最优子树。
那为什么是最小的g(t)呢?(以下是别的博文上的解释,说的很好,我就直接拿过来用了,自己就不再赘述了)
CART剪枝算法详解_第1张图片
       以图中两个点为例,结点1和结点2,g(t)2大于g(t)1, 假设在所有结点中g(t)1最小,g(t)2最大,两种选择方法:当选择最大值g(t)2,即结点2进行剪枝,但此时结点1的不修剪的误差大于修剪之后的误差,即如果不修剪的话,误差变大,依次类推,对其它所有的结点的g(t)都是如此,从而造成整体的累计误差更大。反之,如果选择最小值g(t)1,即结点1进行剪枝,则其余结点不剪的误差要小于剪后的误差,不修剪为好,且整体的误差最小。从而以最小g(t)剪枝获得的子树是该alpha值下的最优子树!

       通过以上的说明,我们现在应该可以理解,将α从小增大,产生一系列的区间,剪去 g(t)属于[αi, αi+1)的对应的结点,就会得到该区间上的最优子树,如此剪下去,直到得到根结点。在这一过程中,不断增加α的值,产生新的区间。

2. 从剪枝得到的子树序列中通过交叉验证选取最优子树Tα。

       具体地,利用独立的验证数据集,测试子树序列T0, T1, … , Tn中各棵子树的平方误差或基尼指数。平方误差或基尼指数最小的决策树被认为是最优的决策树。在子树序列中,每棵子树T0, T1, … , Tn都对应于一个参数α0, α1, … ,αn。所以,当最优子树Tk确定时,对应的αk也确定了,即得到最优决策树Tα。

最后附上CART剪枝算法:
输入:CART算法生成的决策树T0
输出:最优决策树Tα
(1)设k=0,T=T0
(2)设α=+∞
(3)自下而上地对各个内部结点t计算C(Tt),|Tt|以及
g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1 g(t) = \frac{{C(t) - C({T_t})}}{{\left| {{T_t}} \right| - 1}} g(t)=Tt1C(t)C(Tt) α = m i n ( α , α ( t ) ) α=min(α,α(t)) α=min(α,α(t))这里,Tt表示t为根结点的子树,C(Tt)是对训练数据的预测误差,|Tt|是Tt的叶结点个数。
(4)对α(t)=α的内部结点t进行剪枝,并对叶结点t以多数表决法决定其类,得到树T。
(5)设k=k+1,αk=α,Tk=T。
(6)如果Tk不是由根结点及两个叶结点构成的树,则回到步骤3;否则令Tk=Tn。
(7)采用交叉验证法在子树序列T0,T1,…,Tn中选取最优子树Tα
最后,我还是不明白这一点,为什么我们还要记录最终的α值,不是只要得到最优子树就可以了吗?

参考文献:

  1. Demon的黑与白 https://blog.csdn.net/u014688145/article/details/53326910
  2. MrTriste https://blog.csdn.net/wjc1182511338/article/details/76793164
  3. 李航. 统计学习方法[M]. 北京:清华大学出版社,2012

你可能感兴趣的:(机器学习)