CART 算法
CART生成
CART假设决策树是二叉树,内部结点特征的取值为“是”和“否”,左分支是取值为“是”的分支,右分支是取值为“否”的分支。这样的决策树等价于递归地二分每个特征,将输入空间即特征空间划分为有限个单元,并在这些单元上确定预测的概率分布,也就是在输入给定的条件下输出的条件概率分布。
CART算法由以下两步组成:
- 决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;
- 决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时损失函数最小作为剪枝的标准。
CART决策树的生成就是递归地构建二叉决策树的过程。CART决策树既可以用于分类也可以用于回归。本文我们仅讨论用于分类的CART。对分类树而言,CART用Gini系数最小化准则来进行特征选择,生成二叉树。 CART生成算法如下:
输入:训练数据集DD
输出:CART决策树。
根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树:
- 设结点的训练数据集为DD,计算现有特征对该数据集的Gini系数。此时,对每一个特征AA,对其可能取的每个值aa,根据样本点对A=aA=a的测试为“是”或 “否”将DD分割成D1D1和D2D2两部分,计算A=aA=a时的Gini系数。
- 在所有可能的特征AA以及它们所有可能的切分点aa中,选择Gini系数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。
- 对两个子结点递归地调用步骤l~2,直至满足停止条件。
- 生成CART决策树。
算法停止计算的条件是结点中的样本个数小于预定阈值,或样本集的Gini系数小于预定阈值(样本基本属于同一类),或者没有更多特征。注意:适当的选用阈值能够防止过拟合
一个具体的例子
下面来看一个具体的例子。我们使用《数据挖掘十大算法之决策树详解(1)》中图4-6所示的数据集来作为示例,为了便于后面的叙述,我们将其再列出如下:
首先对数据集非类标号属性{是否有房,婚姻状况,年收入}分别计算它们的Gini系数增益,取Gini系数增益值最大的属性作为决策树的根节点属性。根节点的Gini系数
当根据是否有房来进行划分时,Gini系数增益计算过程为
若按婚姻状况属性来划分,属性婚姻状况有三个可能的取值{married,single,divorced},分别计算划分后的
- {married} | {single,divorced}
- {single} | {married,divorced}
- {divorced} | {single,married}
的Gini系数增益。
当分组为{married} | {single,divorced}时,SlSl表示婚姻状况取值为married的分组,SrSr表示婚姻状况取值为single或者divorced的分组
当分组为{single} | {married,divorced}时,
当分组为{divorced} | {single,married}时,
对比计算结果,根据婚姻状况属性来划分根节点时取Gini系数增益最大的分组作为划分结果,也就是{married} | {single,divorced}。
最后考虑年收入属性,我们发现它是一个连续的数值类型。我们在前面的文章里已经专门介绍过如何应对这种类型的数据划分了。对此还不是很清楚的朋友可以参考之前的文章,这里不再赘述。
对于年收入属性为数值型属性,首先需要对数据按升序排序,然后从小到大依次用相邻值的中间值作为分隔将样本划分为两组。例如当面对年收入为60和70这两个值时,我们算得其中间值为65。倘若以中间值65作为分割点。SlSl作为年收入小于65的样本,SrSr表示年收入大于等于65的样本,于是则得Gini系数增益为
其他值的计算同理可得,我们不再逐一给出计算过程,仅列出结果如下(最终我们取其中使得增益最大化的那个二分准则来作为构建二叉树的准则):
注意,这与我们之前在《数据挖掘十大算法之决策树详解(1)》中得到的结果是一致的。最大化增益等价于最小化子女结点的不纯性度量(Gini系数)的加权平均值,之前的表里我们列出的是Gini系数的加权平均值,现在的表里给出的是Gini系数增益。现在我们希望最大化Gini系数的增益。根据计算知道,三个属性划分根节点的增益最大的有两个:年收入属性和婚姻状况,他们的增益都为0.12。此时,选取首先出现的属性作为第一次划分。
接下来,采用同样的方法,分别计算剩下属性,其中根节点的Gini系数为(此时是否拖欠贷款的各有3个records)
与前面的计算过程类似,对于是否有房属性,可得
对于年收入属性则有:
最后我们构建的CART如下图所示:
现在我们来再次理解cart的剪枝
CART剪枝核心思想
从最宏观的角度去考虑的话,就是利用生成
。抽象一下,从【无限的实数】中找寻【有限个数的
】,这问题当然不好解决了!思路其实已经出来了,CART剪枝算法的核心思想就是说,一个复杂的决策树,不管多复杂,都能生成有限个数的子树,我们记作
,那么我们只要找寻到对应于每一个子树的
不就可以了嘛!没错,抽象一下,从【有限个数的
】中找寻对应的【
】,万事解决。
咱们先来看看决策树损失函数的定义:
做一些数学变换得:
所以说,衡量损失函数大小的真正贡献在于每个叶结点,叶结点不确定次数的累加并加个常数就是我们决策树整体的损失函数。
为了得到树T的所有子序列,我们需要从底自上,每次只进行一次剪枝操作,那么进行剪枝操作后,该子序列应该是当前参数的最优子树。且应该是根据所剪的那个结点来计算参数
。
为什么要这么做?接下来的思路是什么?因为我们刚才说了,是通过最优子树来求解参数,因此,我们先【假设】我们找到了当前的最优子树,且必然发生剪枝。【注意加黑的这句话!】具体地,需要归并的子结点为t,以t为单结点损失函数就可以表示为:(该子结点t已经成为我们的叶结点咯!在接下来给出的公式中,请思考哪些是已知参数,哪些是未知参数。)
这公式是最初的决策树损失函数变化而来的!它是其中一个子结点【吞并】它的子树,所得到【叶结点后】的损失函数。还需要强调下,因为在最初理解这个C(t)含义时,自己也被搞混了。该公式已经是剪枝完毕后的表达式了,也就是说原先的子结点已经变成了当前的叶结点。接下来会给剪枝前的表达式!表示在该叶结点中的不确定次数。
那么【剪枝前】是什么情况呢?剪枝前是以t为根结点的子树的损失函数是:
也就是说,剪枝前该子结点的损失函数如上。具体的含义之前都有解释过,就不再叙述了。接下来我们要明确哪些是已知参数,因为决策树已经生成了,所以每个结点的不确定次数都是知道的,即,
和
是已知的。未知参数是
如何求解?还记得加粗的假设嘛?
假设1:必然发生剪枝!
从中我们便能求得,为什么?我们来观察下,上述两个式子。
当或者充分小,明显地,不确定次数:
决策树叶结点越多,不确定性越低,不解释。
当增大时,总有那么一个点,能够使得:
当继续增大时,
不等式反向,所以我们只要取时,当且仅当
时,剪枝必然发生。
必须满足上述条件,否则前提假设将失去意义。所以说,我们通过假设剪枝必然发生就能找到对应的
。可对于任何一个子结点t都可以嘛?别忘了第二个假设。
假设2:剪枝发生后,当前决策树是我们的最优子树
最优子树?现在t变成了一个变量,因为我们并不知道到底剪枝哪个子结点后决策树是最优的。不急,再来看看,公式:
剪枝已经发生,此时,对应于每一个子结点t会生成不同的我们记作
,由此得:
剪枝的决策树什么时候最优?对于当前参数而言,能够找到这样的t,使得
然而在这里为了能够求得的一个序列,貌似直接最小化了
找的即找到了子结点t,即完成了剪枝,即找到了最优子树
。有了上述的步骤,为了得到决策树
的所有子序列,直接递归下去,直到根节点即可。在这一过程中,不断地增加
的值,产生新的区间。
总结:1)cart算法先根据gini基数对data set 进行分裂,直到满足停止条件:gini 阈值,或者数据特征属性,或data set 的number,生成决策树T
2)cart的剪枝:关键点:损失函数C(Tn)=n+a,n为不确定数的数量,a是指它的调节参数
3)讲T进行递归剪枝,不断的计算剪枝后的损失函数,损失函数与C(Tn)的比为a的子树为最优树。