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<a1<…<an<+无穷,产生一系列的区间[ai,ai+1),i =0,1,…,n;剪枝得到的子树序列对应着区间[ai,ai+1),i =0,1,…,n的最优子树序列{T0, T1, … , Tn},序列中的子树是嵌套的。嵌套应该很好理解,向上剪枝的过程,树越变越小嘛)

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

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

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

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

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

那是不是剪掉当前的t结点就可以得到最优子树了呢,当然不是,不同的结点会计算出不同的α1,我们就以此α1作为损失函数的α值(解释一下,当α=α1时,该节点剪枝前后的损失函数的值是一样的,但是剪枝后结点少,也必然要剪枝,此时该结点处的损失函数值也是最小的),这时会算出不同的损失函数值来,当然是取损失函数值最小的结点来剪枝。这里我们将结点t作为变量,计算得到的α记为α(t),则有如下公式:min⁡tC(t)+α(t)(2)\mathop {\min }\limits_t C(t) + \alpha (t)    (2)tmin​C(t)+α(t)    (2)但是在李航的《统计学习方法》中却用以下公式来衡量应该剪枝的结点:g(t)=C(t)−C(Tt)∣Tt∣−1(3)g(t) = \frac{{C(t) - C({T_t})}}{{\left| {{T_t}} \right| - 1}}  (3)g(t)=∣Tt​∣−1C(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)呢?(以下是别的博文上的解释,说的很好,我就直接拿过来用了,自己就不再赘述了)

       以图中两个点为例,结点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(Tt)∣Tt∣−1g(t) = \frac{{C(t) - C({T_t})}}{{\left| {{T_t}} \right| - 1}}g(t)=∣Tt​∣−1C(t)−C(Tt​)​ α=min(α,α(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

CART剪枝算法详解相关推荐

  1. python alpha beta 剪枝_一看就懂的 Alpha-Beta 剪枝算法详解

    Alpha-Beta剪枝用于裁剪搜索树中没有意义的不需要搜索的树枝,以提高运算速度. 假设α为下界,β为上界,对于α ≤ N ≤ β: 若 α ≤ β  则N有解. 若 α > β 则N无解. ...

  2. 一看就懂的Alpha-Beta剪枝算法详解

    原贴:http://blog.csdn.net/tangchenyi/article/details/22925957 Alpha-Beta剪枝算法(Alpha Beta Pruning) [说明] ...

  3. 经典算法详解--CART分类决策树、回归树和模型树

    Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Reg ...

  4. 回溯算法详解之全排列、N皇后问题

    回溯算法详解 回溯算法框架.解决一个回溯问题,实际上就是一个决策树的遍历过程.你只需要思考 3 个问题: 1.路径:也就是已经做出的选择. 2.选择列表:也就是你当前可以做的选择. 3.结束条件:也就 ...

  5. c4.5算法 程序语言,决策树之C4.5算法详解-Go语言中文社区

    决策树之C4.5算法详解 主要内容 C4.5算法简介 分裂属性的选择--信息增益率 连续型属性的离散化处理 剪枝--PEP(Pessimistic Error Pruning)剪枝法 缺失属性值的处理 ...

  6. Apriori算法详解之【一、相关概念和核心步骤】

    感谢红兰整理的PPT,简单易懂,现在将其中精彩之处整理,与大家分享. 一.Apriori算法简介:  Apriori算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测 ...

  7. JDA人脸检测算法详解

    JDA人脸检测算法详解: 第一步: JDA算法原理详解: 作者建立了一个叫post classifier的分类器,方法如下: 1.样本准备:首先作者调用OpenCV的Viola-Jones分类器,将r ...

  8. Apriori算法详解与实现

    Apriori算法详解与实现 一.摘要 二.绪论 三.算法介绍 1.项目 2.项集 3.项集的支持度 4.关联规则 5.关联规则的置信度 6.频繁k项集 7.算法流程 四.代码实现 五.引用 一.摘要 ...

  9. Matlab人脸检测算法详解

    这是一个Matlab人脸检测算法详解 前言 人脸检测结果 算法详解 源代码解析 所调用函数解析 bwlabel(BW,n) regionprops rectangle 总结 前言 目前主流的人脸检测与 ...

  10. 图论-最短路Dijkstra算法详解超详 有图解

    整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...

最新文章

  1. oracle 关联出现重复数据,ORACLE 分页查询出现重复记录的解决办法
  2. Linux 搭建Sphinx 全文检索引擎
  3. sniffer 工具
  4. 微信小程序image组件中aspectFill和widthfix模式应用详解
  5. 3Dshader之膨胀与收缩
  6. day_log 12月份的
  7. java 冒泡_Java中的冒泡排序
  8. java最新2019面试题
  9. prince和学生们侃侃而谈系列03
  10. 《Python基础教程(第3版)》笔记:第8章异常
  11. 蓝牙无法连接手机解决大全(转)
  12. 小程序正则验证 身份证号、统一社会信用代码
  13. 2018年的总结和2019年的期望
  14. 【电子技术】如何抑制共模、差模噪声?
  15. 可能是历史上最伟大的一次 Git 代码提交
  16. jquery表单ajax json数据,jquery序列化form表单使用ajax提交后处理返回的json数据
  17. MVC之Identity身份验证
  18. 使用vlookup嵌套INDIRECT函数实现跨表数据引用
  19. Allegro 17.4完整教学内容+视频
  20. iOS - AVPlayer播放视频,获取视频尺寸(宽高)

热门文章

  1. tcl语言读取文件一行_TCL语言笔记:TCL中的列表操作
  2. MCSA / Windows Server 2016 PowerShell DSC
  3. 【高速PCB电路设计】2.高速电路DDR原理图概述
  4. 学习笔记(5):Google开发专家带你学 AI:入门到实战(Keras/Tensorflow)(附源码)-深度学习“四件套”:数据、模型、损失函数与优化器...
  5. TextCNN(文本分类)
  6. 创建线程的三种方法c语言,创建线程 - Python教程 - C语言网
  7. 计算机程序设计流程图循环,流程图循环画法_流程图用什么办公软件
  8. 软考中级软件设计师该怎么备考
  9. android笔画输入法的字库,献给爱好笔画输入的机友们 速度才是王道之大众码新笔画输入法...
  10. 【PR】PR剪辑视频编辑软件视频去字幕