介绍决策树的生成过程及算法。
关于决策树的结点的特征选择依据:决策树中结点的特征选择方法
一、ID3、C4.5决策树生成算法
关键点:ID3依据结点上信息增益进行特征选择,C4.5依据结点上的信息增益比进行特征选择
算法:
输入:训练数据集D,特征集A,阈值
输出:ID3、C4.5算法决策树 T
步骤:
(先检验两种极端情况)
1.检查D中所有数据标签是否为同一类,是同一类,T直接为单节点树,并将此类标记为该结点的类标记并返回T。
2.若,则T为单结点树,并将D中实例数最大的类作为该结点的标记,返回T。
3.否则,按照特征选择方法中的信息增益(信息增益比)方法计算A中各特征的信息增益(信息增益比),选择信息增益(比)最大的特征,并检测其增益(比)是否大于阈值。
4.对大于阈值的信息增益(比)特征,对其每一个可能的值将数据集D进行分割为若干非空子集并构建子结点。
5.重复分割步骤,分割特征不包括之前已经分割过的特征,当分割后的信息增益(比)不大于阈值时,将此结点下的实例数最多的类作为此结点的标记,构成一个叶结点。
二、ID3、C4.5决策树剪枝算法
直接生成的决策树结构可能过于复杂(和阈值的大小也有关系),此时可能出现过拟合的现象,解决这个问题的方法是对决策树进行剪枝,对决策树进行简化。
决策树的剪枝往往通过极小化决策树整体的损失函数或代价函数来实现。
引入模型的复杂度惩罚项(类似于线性回归的正则化项),损失函数可以定义为:
加号前半部分代表模型对训练数据的预测误差,即模型与训练数据的拟合程度H(T)为结点上的经验熵,经验熵为(因此剪枝是利用正则化的极大似然估计进行模型选择),|T|表示模型复杂度,参数大小控制希望树结构复杂程度。参数较大,树相对简单,参数较小,树相对复杂。
剪枝步骤:1.先将生成的决策树上的每个结点进行计算经验熵
2.递归地从树的叶节点向上回缩,回缩到父结点之前与之后的整体树分别为和,其对应的损失函数值为:和,如果前者比后者小,则进行剪枝,将父结点变为新的叶节点。
3.返回2,直至不能继续为止,得到损失函数最小的子树。
三、CART决策树的生成算法
关键点:CART决策树可以是分类树也可以是回归树,并且CART树是二叉树,内部结点特征取值为是或否。CART回归树特征选择时使用的是平方误差最小化,CART分类决策树特征选择时使用的是Gini指数最小化,关于Gini指数也在上面那篇博客中。
回归树的生成:
输入:训练数据集D
输出:回归树
步骤:1.找寻最优切分变量j和扫描切分点s,找出(s,j)对使得下式最小: 对于c是分为两个子节点分别对应的所有子数据的标签平均值,R1、R2分别对应两结点上的数据集。
2.用选定的(j,s)对划分区域并决定相应的输出值:
3.继续对两个子区域调用步骤1、2,直至满足停止条件。
4.最终将输入空间划分为多个子空间,生成决策树。
分类树的生成:
输入:训练数据集D,停止计算的条件
输出:CART分类树
步骤:1.计算全部数据集的Gini指数:。此时,对每一个特征A,对其每个可能的取值a,根据样本点对A=a的测试是“是”或 “否”将D分为和两部分,并计算此时的基尼指数。
2.在所有可能的特征A以及所有可能的切分点a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点,并将数据集进行分配。
3.对两个子结点递归地调用1、2,直至满足停止条件。
4.生成CART决策树。
四、CART决策树的剪枝
在初始决策树任意内部结点t,以t为单结点树的损失函数是 ,以t为根节点的子树的损失函数是: ,前面的损失函数代表的是把t下面的子树均裁剪并把这个结点取出来当做只有一个结点的树的损失函数,后面的损失函数代表的是在此结点没剪枝时,把这个结点当做根节点的一个树的损失函数。输入:CART算法生成的决策树T
输出:最优决策树
步骤:1.设k=0,
2.自下而上地对各内部结点t计算以及(g(t)代表的是一个临界的值,是当时的值,此时剪枝和不剪枝的损失函数大小相同)和。
3.对的内部结点t进行剪枝,并对叶节点t以多数表决决定其类,得到树T.
4.设
5.如果不是由根节点及两个叶节点构成的树,则回到步骤2,否则
6.采用交叉验证法在子树序列中选择最优子树。
注:在剪枝过程中,实质上是不断地增大值,产生新的区间。
对整体过程更为直观的理解,注意上面的几个关键地方:
1.对树的更新是创建一个新的子树,并不是对更新了的子树赋值给树带回到步骤2,而回到步骤2的还是完整的没有任何剪枝树。
2.因为是逐渐增大,所以开始为0时,不会剪枝,因为过小,树的结构复杂也对损失函数造成不了什么影响,随着的增大,会到达某一个临界点,这个临界点就是所有内部结点算出的g(t)中的最小的g(t),我们称为g(t0),此时剪枝不剪枝损失相同,但为了结构更加简单(奥卡姆剃刀原理),进行剪枝。
然后剪枝完了,得到一颗子树,并保存下来。之后恢复完整没剪枝的树回到步骤2里面,并且因为是自下而上的,所以对上面刚刚剪枝的临界值即g(t0)的基础上增大,第二次剪枝的时候就彻底不考虑g(t0)了,因为之前第一次剪枝的是所有里面最小的,所以后面的肯定比第一次的临界大,因此满足了书中的不断增加值。
然后再找一个g(t0)大的g(t1),并且g(t1)比除了g(t0)的g(t)都小,于是这就是第二个剪枝的临界点,找到g(t1)对应的结点,并在此进行剪枝,又得到一棵子树,然后再找比g(t0) g(t1)大但比其他g(t)小的g(t2),重复之前的过程,直到增大到恰好等于只剩初始完整树的根节点加俩叶节点时的g(tn),停止,并返回这个树,增大也就结束了,也得到了一系列树。