1. 为什么要剪枝
剪枝主要解决决策树学习算法中的”过拟合”问题. 好比说, 小明身高180cm, 体重75kg, 我们要给小明做一件裤子. 我们只要根据小明的身高, 体重, 腰围这三个参数, 就可以做出来一件适合小明穿的裤子. 同时我们也确信, 有许多身高体重和小明相近人也适合这条裤子. 但如果我们除了考虑身高, 体重, 腰围这几个参数外, 还额外去考虑这小明喜欢什么颜色, 喜欢什么图案, 喜欢什么材质, 喜欢什么风格. 那么这样作出来的一件衣服, 依然适合小明, 但却不一定适合别人. 这就是过拟合的问题, 我们不应该把一些自身的特点都当作所有数据集都具有的一般性质. 所以, 我们可以主动去掉一些分支, 来降低过拟合的风险. 有研究表明, 在数据带有噪声时通过剪枝甚至可将决策树的泛化性能提升25%.
2.剪枝处理
剪枝分为”预剪枝(prepruning)”和”后剪枝(postpruning)”两种. 预剪枝是指在决策树构建过程中, 对每个节点在划分前先进行估计, 若不能带来决策树泛化性能提升, 就停止划分, 并将当前结点标记为叶结点. 后剪枝则是先构成一颗完整的决策树, 再考察非叶结点. 若该结点对应的子树替换为叶结点能带来决策树泛化性能提升, 则将该字数替换为叶结点.(机器学习,周志华)
我们用这个数据集来详细的说明一下剪枝方法:
![3971e63e3713c948cb043e191321e485.png](https://img-blog.csdnimg.cn/img_convert/3971e63e3713c948cb043e191321e485.png)
我们把数据集分成两个部分, 绿色为训练集, 蓝色为验证集.
2.1 预剪枝
根据我们以往学过的知识, 基于信息增益准则, 我们根据苹果的”大小”属性来对训练集进行划分. 然后, 我们要对划分前后所带来的泛化性进行评估, 来决定是否真的要进行划分.
若不进行划分, 结点1将被当作为叶结点, 并将类别标记为训练样例数最多的类别. 在当前的训练集中, 好苹果和差苹果都是5个, 所以我们选择哪个类别都可以, 这里我们假设这个结点标记为好苹果. 由于节点1也是整棵树的根节点, 也就是先默认所有的苹果都是好苹果.
![718bd880fc6701776c3e8757411f7d03.png](https://img-blog.csdnimg.cn/img_convert/718bd880fc6701776c3e8757411f7d03.png)
然后用验证集对我们这个结点进行评估. 一共7组数据, 其中分类正确的个数为3个, 编号为{11, 12, 13}, 其余4个分类错误。 所以验证集精度为3/7 * 100% = 42.9%。
然后, 再用”大小”属性尝试一次划分. 划分后, 再用训练集进行评估. 此时, 依然是7组数据, 其中的5组数据, 编号{11,12,13,15,16}被分类正确,所以验证集精度为5/7 * 100% = 71.4%. 很显然, 划分后71.4%的精度更高. 即用”大小”这个属性可以进行划分.
下面开始考虑2号节点. 基于信息增益准则, 2号节点用“颜色”尝试划分.
![9514d36e3dc016c4a93971b5f5dcf482.png](https://img-blog.csdnimg.cn/img_convert/9514d36e3dc016c4a93971b5f5dcf482.png)
划分前, 验证集共7组数据中的5组数据{11, 12, 13, 15, 16}是被划分正确的. 但划分后验证集的7组数据中, 只有4组数据被划分正确 {11, 13, 15, 16}, 正确率降低为4/7 * 100% = 57%. 于是, 此节点被禁止划分.
其余的节点也可以以此类推进行划分.
2.2 后剪枝
后剪枝先从训练集生成一颗完整的决策树, 然后在进行剪枝处理. 所以我们先要生成一颗完整的决策树. 基于信息增益准则, 生成的决策树如下.
![1e55613458007248affadd7964dcb362.png](https://img-blog.csdnimg.cn/img_convert/1e55613458007248affadd7964dcb362.png)
2.2.1 REP - 错误率降低剪枝(Reduced-Error Pruning)
这个主体思路是, 我们用验证集来验证这棵树. 对于完全决策树中的每一个非叶子节点的子树, 我们尝试着把它替换成一个叶子节点, 该叶子节点的类别我们用子树所覆盖训练样本中存在最多的那个类来代替, 这样就产生了一个简化决策树, 然后比较这两个决策树在测试数据集中的表现, 如果简化决策树在测试数据集中的错误比较少, 那么该子树就可以替换成叶子节点. 该算法以自底向上的方式遍历所有的子树, 直至没有任何子树可以替换使得测试数据集的表现得以改进时, 算法就可以终止.
直接上例子, 我们先用验证集测试一下当前决策树的精度. 将验证集的7条数据依次验证, 可知 {11, 15, 16} 是正确的, 精度3/7 * 100% = 42.9%.
然后我们自下而上的进行考察, 先看节点6. 若将其分支剪除, 即把6替换为叶节点. 替换后, 6节点包含的训练样本编号为 {5, 8} , 叶子节点的类别我们用该节点训练样本中存在最多的类别来代替. 在这里, 好苹果和坏苹果类别相等, 我们可以随便选择其中一种, 我们在这里将叶节点标记为好苹果. 在用我们的验证集去验证. 在我们验证集7组数据中, 编号 {11, 13, 15, 16}是正确的. 此时决策树验证集精度提高至4/7 * 100% = 57.1%. 精度有所提升. 所以后剪枝策略决定剪枝.
其他节点也用同样的方法进行决策, 最后得到的后剪枝决策树如下:
![1f2ba0d33f078b8141e95baecbec8706.png](https://img-blog.csdnimg.cn/img_convert/1f2ba0d33f078b8141e95baecbec8706.png)
2.2.2 PEP - 悲观剪枝 (Pessimistic Error Pruning)
通过2.2.1 REP的学习, 我们发现REP必须需要一个验证集. 为此我们在介绍另一种方法PEP, 相比REP剪枝, PEP不需要单独的测试集.
PEP剪枝算法是在C4.5决策树算法中提出的, 把一颗子树 (具有多个叶子节点) 用一个叶子节点来替代, 比起REP剪枝法, 它不需要一个单独的测试数据集.
PEP算法首先确定这个叶子的经验错误率(empirical)为(E+0.5)/N, 0.5为一个调整系数. 对于一颗拥有L个叶子的子树, 则子树的错误数和实例数都是就应该是叶子的错误数和实例数求和的结果, 则子树的错误率为e, 这个e后面会用到.
![b10afd2503ad3dc1697c2f34dc345772.png](https://img-blog.csdnimg.cn/img_convert/b10afd2503ad3dc1697c2f34dc345772.png)
然后用一个叶子节点替代子树, 该新叶子节点的类别为原来子树节点的最优叶子节点所决定. J为这个替代的叶子节点的错判个数, 但是也要加上0.5, 即J+0.5. 最终是否应该替换的标准为:
![200b3f5d76b0b305fe8ad8e2f5923638.png](https://img-blog.csdnimg.cn/img_convert/200b3f5d76b0b305fe8ad8e2f5923638.png)
(公式2)
我们用来自西北工业大学的一份PPT来举一个例子.
![f83ce9b71881cfc65141203324fc7e79.png](https://img-blog.csdnimg.cn/img_convert/f83ce9b71881cfc65141203324fc7e79.png)
我们来判断T4为根的这个子树可否被剪掉.
每个节点的数字含义为, 左边数字代表正确的个数, 右边数字代表错误的个数. 例如T8节点, 说明覆盖了5条数据, 其中3条是分类正确的, 2条是分类错误的.
根据公式1:
![b10afd2503ad3dc1697c2f34dc345772.png](https://img-blog.csdnimg.cn/img_convert/b10afd2503ad3dc1697c2f34dc345772.png)
T4有三个叶子节点, 分别是T8, T9和T7. 因此L=3.
T8包含5条数据, T9包含2条, T7包含9条. 三个节点一共包含16条数据. 因此N=16.
T8包含2条错误数据, T9包含2条错误数据, T7包含3条错误数据. 三个节点一共包含7条错误数据. 因此E=7.
根据子树的错误率 e = (7 + 0.5*3) / 16 = 0.53
这三颗子树在考虑到调整系数0.5的情况下, 错误数 = (7 + 0.5*3) = 8.5
根据二项分布的标准差公式,
![5d87877193e2aaf8d56b1f62f9f5dcaf.png](https://img-blog.csdnimg.cn/img_convert/5d87877193e2aaf8d56b1f62f9f5dcaf.png)
var(16) = = 2,把子树剪枝后, 剩下的T4在考虑到调整系数0.5的情况下, 错误数 = 7 + 0.5 = 7.5,这样根据公式2:
![200b3f5d76b0b305fe8ad8e2f5923638.png](https://img-blog.csdnimg.cn/img_convert/200b3f5d76b0b305fe8ad8e2f5923638.png)
(8.5 – 2) < 7.5, 不满足公式2. 所以不能用T4替换整个子树.
2.2.3 CCP - 代价复杂度剪枝 (Cost-Complexity Pruning)
CCP的核心思想是, 对于原始的一棵树T0, 先减去一棵子树, 变成T1. 在从T1减去一颗字数, 变成T2. 直到剩下跟结点. 然后再由T0, T1, T2… Tn 分别去测试验证数据集, 谁的误差最小就选谁.
但到底该从哪个节点去剪去子树呢? 我们用以下公式对树的每一个子树进行计算, 并剪掉g(t)最小的树.
![eb36bf3c8435ad84bd5a4edecf9494ab.png](https://img-blog.csdnimg.cn/img_convert/eb36bf3c8435ad84bd5a4edecf9494ab.png)
|NTt| 表示子树包含的叶子节点个数
R(t) 训练数据的预测误差(如基尼指数)= 节点 t 上的数据占所有数据的比例*节点 t 的误差率
R(Tt) 是子树Tt的预测误差 = 子树Tt上所有叶子节点的预测误差之和
CCP剪枝算法分为两个步骤:
1、对于完全决策树T的每个非叶结点计算g(t)值,循环剪掉具有最小g(t)值的子树,直到剩下根节点。在该步可得到一系列的剪枝树{T0,T1,T2......Tm},其中T0为原有的完全决策树,Tm为根节点,Ti+1为对Ti进行剪枝的结果;
2、从子树序列中,根据真实的误差估计选择最佳决策树。
以这幅图为例子
![d80239908f168807a6ec4fd865d77d9e.png](https://img-blog.csdnimg.cn/img_convert/d80239908f168807a6ec4fd865d77d9e.png)
第一轮, 各个结点的g(t)最终计算结果如下
![8119070a0e344427268d5c6ab888eed3.png](https://img-blog.csdnimg.cn/img_convert/8119070a0e344427268d5c6ab888eed3.png)
其中t2 与 t3 最小, 都是1/8, 遇上此类情况我们选择最小的 最少的节点t3, 剪完后, 生成的新树如下:
![b9424883d11301d2b27b0b12f43ee9da.png](https://img-blog.csdnimg.cn/img_convert/b9424883d11301d2b27b0b12f43ee9da.png)
此时注意原先的t3节点变成了叶子节点, 原先t3节点的左叶子的两个空心圆被错误的划分.到了t2节点的右叶子.
则第二轮迭代时
![b0dca4e51fad654b4a755e6b7c4aa7fd.png](https://img-blog.csdnimg.cn/img_convert/b0dca4e51fad654b4a755e6b7c4aa7fd.png)
t2最小, 所以剪掉. 最终只剩跟结点
![0c3ec723aeafdf4574269f0373ff6526.png](https://img-blog.csdnimg.cn/img_convert/0c3ec723aeafdf4574269f0373ff6526.png)
到现在, 我们一共有两颗子树, 利用独立的验证数据集,计算每个子树的平方误差或者基尼指数,选择误差最小的那个子树作为最优的剪枝后的树。
2.2.4 其他和各种剪枝方法对比
此外,还有MEP-最小错误剪枝,由于篇幅限制,这里就不做介绍了。具体读者们可以参考https://zhuanlan.zhihu.com/p/30296061或其原始论文进行了解。有论文对这四种方法进行了比较,如下所示:
![f02cf4fcfa2e9979c401af17ee60461a.png](https://img-blog.csdnimg.cn/img_convert/f02cf4fcfa2e9979c401af17ee60461a.png)
①MEP比PEP不准确,且树大。两者都不需要额外数据集,故当数据集小的时候可以用。对比公式,如果类(Label)多,则用MEP;PEP在数据集uncertain时错误多,不使用。 ②REP最简单且精度高,但需要额外数据集;CCP精度和REP差不多,但树小。 ③如果数据集多(REP&CCP←复杂但树小) ④如果数据集小(MEP←不准确树大&PEP←不稳定) https:// zhuanlan.zhihu.com/p/30 296061
3.预剪枝与后剪枝对比
预剪枝通常会有欠拟合的问题. 而后剪枝, 相比前剪枝保留了更多的分支. 因此通常情况下, 后剪枝欠拟合的风险很小. 但是, 对于性能的开销, 由于后剪枝需要先生成一颗完整的决策树, 再去考察各个节点, 因此后剪枝的训练时间开销要比预剪枝大很多.
参考资料:
- http://mlwiki.org/index.php/Cost-Complexity_Pruning
- https://www.jianshu.com/p/b90a9ce05b28
- 周志华《机器学习》
推荐阅读:
https://www.cnblogs.com/starfire86/p/5749334.html
谢谢大家持续关注ARGO,ARGO将持续奉上上佳内容,大家敬请期待。
![c3bac815e04381a981b12a69b18b0ccf.png](https://img-blog.csdnimg.cn/img_convert/c3bac815e04381a981b12a69b18b0ccf.png)