决策树剪枝、连续值、缺省值处理

1.决策树剪枝

首先剪枝(pruning)的目的是为了避免决策树模型的过拟合。因为决策树算法在学习的过程中为了尽可能的正确的分类训练样本,不停地对结点进行划分,因此这会导致整棵树的分支过多,也就导致了过拟合。决策树的剪枝策略最基本的有两种:预剪枝(pre-pruning)和后剪枝(post-pruning):

预剪枝(pre-pruning):预剪枝就是在构造决策树的过程中,先对每个结点在划分前进行估计,若果当前结点的划分不能带来决策树模型泛华性能的提升,则不对当前结点进行划分并且将当前结点标记为叶结点。
后剪枝(post-pruning):后剪枝就是先把整颗决策树构造完毕,然后自底向上的对非叶结点进行考察,若将该结点对应的子树换为叶结点能够带来泛华性能的提升,则把该子树替换为叶结点。

一、预剪枝(pre-pruning)
        关于预剪枝(pre-pruning)的基本概念,在前面已经介绍过了,下面就直接举个例子来看看预剪枝(pre-pruning)是怎样操作的。数据集为(图片来自西瓜书):

这个数据集根据信息增益可以构造出一颗未剪枝的决策树(图片来自西瓜书):

下面来看下具体的构造过程:
前面博客(决策树(一))讲过用信息增益怎么构造决策树,这边还是用信息增益构造决策树,先来计算出所有特征的信息增益值:

因为色泽和脐部的信息增益值最大,所以从这两个中随机挑选一个,这里选择脐部来对数据集进行划分,这会产生三个分支,如下图所示:

但是因为是预剪枝,所以要判断是否应该进行这个划分,判断的标准就是看划分前后的泛华性能是否有提升,也就是如果划分后泛华性能有提升,则划分;否则,不划分。 下面来看看是否要用脐部进行划分,划分前:所有样本都在根节点,把该结点标记为叶结点,其类别标记为训练集中样本数量最多的类别,因此标记为好瓜,然后用验证集对其性能评估,可以看出样本{4,5,8}被正确分类,其他被错误分类,因此精度为43.9%。划分后: 划分后的的决策树为:

则验证集在这颗决策树上的精度为:5/7 = 71.4% > 42.9%。因此,用 脐部 进行划分。
        接下来,决策树算法对结点 (2) 进行划分,再次使用信息增益挑选出值最大的那个特征,这里我就不算了,计算方法和上面类似,信息增益值最大的那个特征是“色泽”,则使用“色泽”划分后决策树为:

但到底该不该划分这个结点,还是要用验证集进行计算,可以看到划分后,精度为:4/7=0.571<0.714,因此,预剪枝策略将禁止划分结点 (2) 。对于结点 (3) 最优的属性为“根蒂”,划分后验证集精度仍为71.4%,因此这个划分不能提升验证集精度,所以预剪枝将禁止结点 (3) 划分。对于结点 (4) ,其所含训练样本已属于同一类,所以不再进行划分。
        所以基于预剪枝策略生成的最终的决策树为:

总结: 对比未剪枝的决策树和经过预剪枝的决策树可以看出:预剪枝使得决策树的很多分支都没有“展开”,这不仅降低了过拟合的风险,还显著减少了决策树的训练时间开销和测试时间开销。但是,另一方面,因为预剪枝是基于“贪心”的,所以,虽然当前划分不能提升泛华性能,但是基于该划分的后续划分却有可能导致性能提升,因此预剪枝决策树有可能带来欠拟合的风险。

二、后剪枝(post-pruning)
        后剪枝就是先构造一颗完整的决策树,然后自底向上的对非叶结点进行考察,若将该结点对应的子树换为叶结点能够带来泛华性能的提升,则把该子树替换为叶结点。前面已经说过了,使用前面给出的训练集会生成一颗(未剪枝)决策树:

后剪枝算法首先考察上图中的结点 (6),若将以其为根节点的子树删除,即相当于把结点 (6) 替换为叶结点,替换后的叶结点包括编号为{7,15}的训练样本,因此把该叶结点标记为“好瓜”(因为这里正负样本数量相等,所以随便标记一个类别),因此此时的决策树在验证集上的精度为57.1%(为剪枝的决策树为42.9%),所以后剪枝策略决定剪枝,剪枝后的决策树如下图所示:

 

        接着考察结点 5,同样的操作,把以其为根节点的子树替换为叶结点,替换后的叶结点包含编号为{6,7,15}的训练样本,根据“多数原则”把该叶结点标记为“好瓜”,测试的决策树精度认仍为57.1%,所以不进行剪枝。
        考察结点 2 ,和上述操作一样,不多说了,叶结点包含编号为{1,2,3,14}的训练样本,标记为“好瓜”,此时决策树在验证集上的精度为71.4%,因此,后剪枝策略决定剪枝。剪枝后的决策树为:

接着考察结点 3 ,同样的操作,剪枝后的决策树在验证集上的精度为71.4%,没有提升,因此不剪枝;对于结点 1 ,剪枝后的决策树的精度为42.9%,精度下降,因此也不剪枝。
        因此,基于后剪枝策略生成的最终的决策树如上图所示,其在验证集上的精度为71.4%。

总结:对比预剪枝和后剪枝,能够发现,后剪枝决策树通常比预剪枝决策树保留了更多的分支,一般情形下,后剪枝决策树的欠拟合风险小,泛华性能往往也要优于预剪枝决策树。但后剪枝过程是在构建完全决策树之后进行的,并且要自底向上的对树中的所有非叶结点进行逐一考察,因此其训练时间开销要比未剪枝决策树和预剪枝决策树都大得多。

2.连续值处理

因为连续属性的可取值数目不再有限,因此不能像前面处理离散属性枚举离散属性取值来对结点进行划分。因此需要连续属性离散化,常用的离散化策略是二分法,这个技术也是C4.5中采用的策略。下面来具体介绍下,如何采用二分法对连续属性离散化:

    

下面举个具体的例子,来看看到底是怎样划分的。给定数据集如下(数据集来自周志华《机器学习》,我已经把数据集放到github上了,地址为:西瓜数据集3.0):

对于数据集中的属性“密度”,决策树开始学习时,根节点包含的17个训练样本在该属性上取值均不同。我们先把“密度”这些值从小到大排序:

根据上面计算 的公式,可得:

下面开始计算t 取不同值时的信息增益:

对属性“含糖率”,同样的计算,能够计算出:

再由第一篇博客中决策树(一)计算得到的各属性的信息增益值:

比较能够知道纹理的信息增益值最大,因此,“纹理”被选作根节点划分属性,下面只要重复上述过程递归的进行,就能构造出一颗决策树:

**有一点需要注意的是:与离散属性不同,若当前结点划分属性为连续属性,该属性还可作为其后代结点的划分属性。**如下图所示的一颗决策树,“含糖率”这个属性在根节点用了一次,后代结点也用了一次,只是两次划分点取值不同。

3.缺省值处理

现实生活中的数据集中的样本通常在某系属性上是缺失的,如果属性值缺失的样本数量比较少,我们可以直接简单粗暴的把不完备的样本删除掉,但是如果有大量的样本都有属性值的缺失,那么就不能简单地删除,因为这样删除了大量的样本,对于机器学习模型而言损失了大量有用的信息,训练出来的模型性能会受到影响。这篇博客就来介绍在决策树中是如何处理属性值有缺失的样本的,本篇博客使用的数据集如下(数据集来自周志华《机器学习》):

在决策树中处理含有缺失值的样本的时候,需要解决两个问题:

如何在属性值缺失的情况下进行划分属性的选择?(比如“色泽”这个属性有的样本在该属性上的值是缺失的,那么该如何计算“色泽”的信息增益?)
    给定划分属性,若样本在该属性上的值是缺失的,那么该如何对这个样本进行划分?(即到底把这个样本划分到哪个结点里?)
    下面就来介绍如何解决这两个问题:

比较发现,“纹理”在所有属性中的信息增益值最大,因此,“纹理”被选为划分属性,用于对根节点进行划分。划分结果为:“纹理=稍糊”分支:{7,9,13,14,17},“纹理=清晰”分支:{1,2,3,4,5,6,15},“纹理=模糊”分支:{11,12,16}。如下图所示:

    那么问题来了,编号为{8,10}的样本在“纹理”这个属性上是缺失的,该被划分到哪个分支里?前面讲过了,这两个样本会同时进入到三个分支里,只不过进入到每个分支后权重会被调整(前面也说过,在刚开始时每个样本的权重都初始化为1)。编号为8的样本进入到三个分支里后,权重分别调整为5/15,7/15 和 3/15;编号为10的样本同样的操作和权重。因此,经过第一次划分后的决策树如下图所示:

我们都知道构造决策树的过程是一个递归过程,原来不打算继续介绍递归过程了,但是因为权重发生了变化,所以继续介绍下递归过程。接下来,递归执行“纹理=稍糊”这个分支,样本集= {7,8,9,10,13,14,17},共7个样本。如下图所示:

下面来看具体的计算过程:

对比能够发现属性“敲声”的星系增益值最大,因此选择“敲声”作为划分属性,划分后的决策树如下图所示:

接下来对分支{敲声 = 沉闷}即结点{9,14,17}进行划分,根据博客决策树(一)介绍的三种递归返回情形,结点{9,14,17}因为包含的样本全部属于同一类别,因此无需划分,直接把结点{9,14,17}标记为叶结点,如下图所示:

根据递归过程,接下来对分支“敲声 = 浊响”即结点{7,8,13}进行划分,计算过程和上面一样,虽然我也算过了,但是不再贴出来了,需要注意的是样本的权重是1/3。计算完比较能够知道属性“脐部”的信息增益值最大,因此选择“脐部”作为划分属性,划分完的决策树如下图所示:

接下来,继续,对于结点{13},因为就一个样本了,直接把该结点标记为叶结点,类别为“坏瓜”;递归到结点{7,8},因为样本类别相同,所以也标记为叶结点,类别为“好瓜”;递归到结点“脐部=平坦”,因为这个结点不包含任何样本为空集,因此,把该结点标记为叶结点,类别设置为父节点中多数类的类别,即为“好瓜”。因此“纹理=稍糊”这颗子树构造完毕,如下图所示:

接下来,只需递归的重复上述过程即可,即能训练出一颗完整的决策树,最终的决策树如下图所示(该图片来自西瓜书):

 

以上介绍了决策树在训练阶段是如何处理有缺失值的样本的,从而构造出一颗树。当我们构造完一棵树后,有新的样本过来就可以对新的样本进行分类了,那么问题来了,如果测试样本属性也有缺失值那要怎么办?这一点西瓜书上并未有涉及,下面的评论有同学问,因此去找了Quinlan的论文,Quinlan在论文《unknown attribute values in introduction》中总结了一些方法:

If there is a special branch for unknown value of A take it
    Determine the most likely outcome of the test as above and act accordingly
    Treat this case as if it had the most common value of A
    Explore all branches combining the results to reflect the relative probabilities of the different outcomes (Quinlan,1987a)
    Halt at this point and assign the case to the most likely class.
简单翻译下,就是:

  •     如果有专门处理缺失值的分支,就走这个分支。
  •     用这篇论文提到的方法来确定属性a的最有可能取值,然后走相应的分支。
  •     从属性a最常用的分支走
  •     同时探查所有的分支,并组合他们的结果来得到类别对应的概率,(取概率最大的类别)
  •     将最有可能的类别赋给该样本。

上面的这么多方法只是提一下,C4.5中采用的方法是:测试样本在该属性值上有缺失值,那么就同时探查(计算)所有分支,然后算每个类别的概率,取概率最大的类别赋值给该样本。好像这个方法并不怎么好用语言描述,我们直接看例子吧,相信你看完例子就立刻明白了,由于这是今天(19年4月9号)新添加的内容,上面西瓜书上的例子当时计算的权重没有保留下来,因此这里直接引用Quinlan在著作《C4.5: Programs For Machine Learning》里举的例子(在该书的p31-p32),先看数据集:

注意,编号12的样本属性outlook上有缺失值,我们基于上面介绍的构造决策树的方法来构造一颗决策树(C4.5用信息增益率,除此之外,构造方法与上述方法一致),构造出来的决策树为:

上图中,红色数字表示样本编号,括号内的值表示样本12的权重。叶结点中的数值(N/E),比如no(3.38/0.38)表示这个叶子节点被标记为no也就是don't play,3.38=1+1+0.38,编号1,2的样本没有缺失值,权重为1进来的,编号12进入到这个叶结点时权重为0.38。

如果,此时我们有一条样本:outlook=sunny, temperature=70, humidity=?, windy=false  能够看出这条样本的属性humidity是缺失的,那么构建好的决策怎么对这个样本分类?

首先这个样本的outlook为sunny,肯定会进入到“humidity”这个节点里,因为该样本humidity属性值缺失,两个分支都有可能进入:

  • 如果humidity<=75,则类别为play。
  •     如果humidity>75,don't play的概率为3/3.38=88.7%,play的概率为0.38/3.38=11.3%。

大家肯定有一点疑惑,就是上面humidity>75里,明明叶结点的label为no啊,那应该是don't play啊,怎么还有don't play和paly的概率,这是Quinlan的定义,上面的(N/E)中,N,E的定义分别是:

  • N表示该叶节点中所包含的总样本数(总权重更恰当点)
  •  E表示与该叶节点的类别不同的样本数(权重),比如上面第二个叶结点的label为no(dont play),包含的样本数为1,2,8,12(0.38),这里编号12的样本类别为play,因此与该叶结点的类别不同,所以这叶结点会产生11.3%的概率为play。

那么根据上面介绍的,此时同时探查(计算)所有分支,然后算每个类别的概率,取概率最大的类别赋值给该样本。这里humidity下就有两个分支,<=75 => yes 和 >75 =>no。下面分别计算这两个类别的概率:

yes(play):2.0/5.38 * 100% + 3.38/5.38 * 11.3% = 44.27%

no(don't play): 3.38/5.38 * 88.7% = 55.73%

因此no的概率更大,所以该测试样本的类别被指派为no,即don't play。

参考文献:

    周志华《机器学习》
    Quinlan C4.5: Programs For Machine Learning
    Quinlan unknown attribute values in introduction
    xindong wu等著,李文波等译《数据挖掘十大算法》,这其实是paper 《the top ten algorithms in data mining》的翻译版
 

 

 
 

 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值