《Python数据分析与机器学习实战-唐宇迪》读书笔记第7章--决策树
第7章决策树
决策树算法是机器学习中最经典的算法之一。大家可能听过一些高深的算法,例如在竞赛中大杀四方的Xgboost、各种集成策略等,其实它们都是基于树模型来建立的,掌握基本的树模型后,再去理解集成算法就容易多了,本章介绍树模型的构造方法以及其中涉及的剪枝策略。
7.1决策树原理
先来看一下决策树能完成什么样的任务。假设一个家庭中有5名成员:爷爷、奶奶、妈妈、小男孩和小女孩。现在想做一个调查:这5个人中谁喜欢玩游戏,这里使用决策树演示这个过程,如图7-1所示。
图7-1 决策树分类方法
开始的时候,所有人都属于一个集合。第一步,依据年龄确定哪些人喜欢玩游戏,可以设定一个条件,如果年龄大于15岁,就不喜欢玩游戏;如果年龄小于15岁,则可能喜欢玩游戏。这样就把5个成员分成两部分,一部分是右边分支,包含爷爷、奶奶和妈妈;另一部分是左边分支,包含小男孩和小女孩。此时可以认为左边分支的人喜欢玩游戏,还有待挖掘。右边分支的人不喜欢玩游戏,已经淘汰出局。
对于左边这个分支,可以再进行细分,也就是进行第二步划分,这次划分的条件是性别。如果是男性,就喜欢玩游戏;如果是女性,则不喜欢玩游戏。这样就把小男孩和小女孩这个集合再次分成左右两部分。左边为喜欢玩游戏的小男孩,右边为不喜欢玩游戏的小女孩。这样就完成了一个决策任务,划分过程看起来就像是一棵大树,输入数据后,从树的根节点开始一步步往下划分,最后肯定能达到一个不再分裂的位置,也就是最终的结果。
下面请大家思考一个问题:在用决策树的时候,算法是先把数据按照年龄进行划分,然后再按照性别划分,这个顺序可以颠倒吗?为什么要有一个先后的顺序呢?这个答案其实也就是决策树构造的核心。
7.1.1决策树的基本概念
熟悉决策树分类过程之后,再来解释一下其中涉及的基本概念。首先就是树模型的组成,开始时所有数据都聚集在根节点,也就是起始位置,然后通过各种条件判断合适的前进方向,最终到达不可再分的节点,因而完成整个生命周期。决策树的组成如图7-2所示。
图7-2 决策树组成
- 根节点:数据的聚集地,第一次划分数据集的地方。
- 非叶子节点与分支:代表中间过程的各个节点。
- 叶子节点:数据最终的决策结果。
刚才完成的决策过程其实是已经创建好了一个树模型,只需要把数据传进去,通过决策树得到预测结果,也就是测试阶段,这步非常简单。决策树的核心还是在训练阶段,需要一步步把一个完美的决策树构建出来。那么问题来了,怎样的决策树才是完美的呢?训练阶段需要考虑的问题比较多,例如根节点选择什么特征来划分?如果按照年龄划分,年龄的判断阈值应该设置成多少?下一个节点按照什么特征来划分?一旦解决这些问题,一个完美的树模型就构建出来了。
7.1.2衡量标准
总结上面所提到的问题,归根到底就是什么特征能够把数据集划分得更好,也就是哪个特征最好用,就把它放到最前面,因为它的效果最好,当然应该先把最厉害的拿出来。就像是参加比赛,肯定先上最厉害的队员(决策树中可没有田忌赛马的故事)。那么数据中有那么多特征,怎么分辨其能力呢?这就需要给出一个合理的判断标准,对每个特征进行评估,得到一个合适的能力值。
这里要介绍的衡量标准就是熵值,大家可能对熵有点陌生,先来解释一下熵的含义,然后再去研究其数学公式吧。
熵指物体内部的混乱程度,怎么理解混乱程度呢?可以分别想象两个场景:第一个场景是,当你来到义乌小商品批发市场,市场里有很多商品,看得人眼花缭乱,这么多商品,好像哪个都想买,但是又比较纠结买哪个,因为可以选择的商品实在太多。
根据熵的定义,熵值越高,混乱程度越高。这个杂货市场够混乱吧,那么在这个场景中熵值就较高。但是,模型是希望同一类别的数据放在一起,不同类别的数据分开。那么,如果各种类别数据都混在一起,划分效果肯定就不好,所以熵值高意味着数据没有分开,还是混杂在一起,这可不是模型想要的。
第二个场景是当你来到一个苹果手机专卖店,这一进去,好像没得选,只能买苹果手机。这个时候熵值就很低,因为这里没有三星、华为等,选择的不确定性就很低,混乱程度也很低。
如果数据划分后也能像苹果专卖店一样,同一类别的都聚集在一起,就达到了分类的目的,解释过后,来看一下熵的公式:
对于一个多分类问题,需要考虑其中每一个类别。式中,n为总共的类别数量,也就是整体的熵值是由全部类别所共同决定的;pi为属于每一类的概率。式(7.1)引入了对数函数,它的作用是什么呢?先来观察一下图7-3。
如果一个节点中所有数据都属于同一类别,此时概率pi值就为1。在对数图中,当x=1时对应的输出值恰好为0,此时熵值也就为0。因为数据都是一个类别的,没有任何混乱程度,熵值就为最低,也就是0。
图7-3 对数函数
再举一个极端的例子,如果一个节点里面的数据都分属于不同的类别,例如10个数据属于各自的类别,这时候概率pi值就很低,因为每一个类别取到的概率都很小,观察图7-3可以发现,当x取值越接近于0点,其函数值的绝对值就越大。
由于概率值只对应对数函数中[0,1]这一部分,恰好其值也都是负数,所以还需在熵的公式最前面加上一个负号,目的就是负负得正,将熵值转换成正的。并且随着概率值的增大,对数函数结果越来越接近于0,可以用其表示数据分类的效果。
下面再通过一个数据例子理解一下熵的概念:假设A集合为[1,1,1,1,1,1,1,1,2,2]、B集合为[1,2,3,4,5,6,7,8,9,10]。在分类任务中,A集合里面的数据相对更纯,取到各自类别的概率值相对较大,此时熵值就偏低,意味着通过这次划分的结果还不错。反观B集合,由于里面什么类别都有,鱼龙混杂,取到各自类别的概率值都较低,由于对数函数的作用,其熵值必然偏高,也就是这次划分做得并不好。
再来说一说抛硬币的事,把硬币扔向天空后落地的时候,结果基本就是对半开,正反各占50%,这也是一个二分类任务最不确定的时候,由于无法确定结果,其熵值必然最大。但是,如果非常确定一件事发生或者不发生时,熵值就很小,熵值变化情况如图7-4所示。
图7-4 熵值变化情况
- 当p=0或p=1时,H(p)=0,随机变量完全没有不确定性。
- 当p=0.5时,H(p)=1(式(7.1)中的对数以2为底),此时随机变量的不确定性最大。
在构建分类决策树时,不仅可以使用熵值作为衡量标准,还可以使用Gini系数,原理基本一致,公式如下:
7.1.3信息增益
既然熵值可以衡量数据划分的效果,那么,在构建决策树的过程中,如何利用熵值呢?这就要说到信息增益了,明确这个指标后,决策树就可以动工了。
数据没有进行划分前,可以得到其本身的熵值,在划分成左右节点之后,照样能分别对其节点求熵值。比较数据划分前后的熵值,目标就是希望熵值能够降低,如果划分之后的熵值比之前小,就说明这次划分是有价值的,信息增益公式如下:
这里计算了划分前后熵值的变化,右项中的具体解释留到下节的计算实例中更容易理解。
总结一下,目前已经可以计算经过划分后数据集的熵值变换情况,回想一下最初的问题,就是要找到最合适的特征。那么在创建决策树时,基本出发点就是去遍历数据集中的所有特征,看看到底哪个特征能够使得熵值下降最多,信息增益最大的就是要找的根节点。接下来就要在剩下的特征中再找到使得信息增益最大的特征,以此类推,直到构建完成整个树模型。
7.1.4决策树构造实例
下面通过一个实例来看一下决策树的构建过程,这里有14条数据,表示在各种天气状况下是否去打球。数据中有4个特征,用来描述当天的天气状况,最后一列的结果就是分类的标签,如表7-1所示。
表7-1 天气数据集
数据集包括14天的打球情况(用yes或者no表示),所给的数据特征有4种天气状况(outlook、temperature、humidity、windy):
- outlook表示天气状况,有3种取值,分别是sunny、rainy、overcast。
- temperature表示气温,有3种取值,分别是hot、cool、mild。
- humidity表示潮湿度,有2种取值,分别是high、normal。
- windy表示是否有风,有2种取值,分别是TRUE、FALSE。
目标就是构建一个决策树模型,现在数据集中有4个特征,所以要考虑的第一个问题就是,究竟用哪一个特征当作决策树的根节点,可以有4种划分方式(见图7-5)。
图7-5 4种特征划分
根据上图的划分情况,需要从中选择一种划分当作根节点,如何选择呢?这就要用到前面介绍的信息增益。
在历史数据中,迪哥有9天打球,5天不打球,所以此时还未经过划分的数据集熵值应为:
为了找到最好的根节点,需要对4个特征逐一分析,先从outlook特征开始。
- 当outlook=sunny时,总共对应5条数据,其中有2天出去打球,3天不打球,则熵值为0.971(计算方法同上)。
- 当outlook=overcast时,总共对应4条数据,其中4天出去打球,此时打球的可能性就为100%,所以其熵值为0。
- 当outlook=rainy时,总共对应5条数据,其中有3天出去打球,2天不打球,则熵值为0.971。
Outlook取值为sunny、overcast、rainy的概率分别为5/14、4/14、5/14,最终经过outlook节点划分后,熵值计算如下(相当于加权平均):
5/14×0.971+4/14×0+5/14×0.971=0.693
以outlook作为根节点,系统的熵值从初始的0.940下降到0.693,增益为0.247。用同样的方式可以计算出其他特征的信息增益,以temperature、humidity、windy分别作为根节点的信息增益为gain(temperature)=0.029,gain(humidity)=0.152,gain(windy)=0.048。这相当于遍历所有特征,接下来只需选择信息增益最大的特征,把它当作根节点拿出即可。
根节点确定后,还需按顺序继续构建决策树,接下来的方法也是类似的,在剩下的3个特征中继续寻找信息增益最大的即可。所以,决策树的构建过程就是不断地寻找当前的最优特征的过程,如果不做限制,会遍历所有特征。
7.1.5连续值问题
上一小节使用的是离散属性的特征,如果数据是连续的特征该怎么办呢?例如对于身高、体重等指标,这个时候不仅需要找到最合适的特征,还需要找到最合适的特征切分点。在图7-1所示例子中,也可以按照年龄30岁进行划分,这个30也是需要给定的指标,因为不同的数值也会对结果产生影响。
如何用连续特征x=[60,70,75,85,90,95,100,120,125,220]选择最合适的切分点呢?需要不断进行尝试,也就是不断二分的过程,如图7-6所示。
图7-6 连续值切分
数据x一共有9个可以切分的点,需要都计算一遍,这一过程也是连续值的离散化过程。对于每一个切分点的选择,都去计算当前信息增益值的大小,最终选择信息增益最大的那个切分点,当作实际构建决策树时选择的切分点。
在这样一份数据中,看起来一一尝试是可以的,但是,如果连续值数据过于庞大怎么办呢?也可以人为地选择合适的切分点,并不是非要遍历所有的数据点。例如,将数据集划分成N块,这就需要遍历N次,其实无非就是效率问题,如果想做得更完美,肯定需要更多的尝试,这些都是可以控制的。
7.1.6信息增益率
在决策树算法中,经常会看到一些有意思的编号,例如ID3、C4.5,相当于对决策树算法进行了升级。基于信息增益的构建方法就是ID3,那么还有哪些问题需要改进呢?可以想象这样一种特征,样本编号为ID,由于每一个样本的编号都是唯一的,如果用该特征来计算信息增益,可能得到的结果就是它能把所有样本都分开,因为每一个节点里面只有一个样本,此时信息增益最大。但是类似ID这样的特征却没有任何实际价值,所以需要对信息增益的计算方法进行改进,使其能够更好地应对属性值比较分散的类似ID特征。
为了避免这个不足,科学家们提出了升级版算法,俗称C4.5,使用信息增益比率(gain ratio)作为选择分支的准则去解决属性值比较分散的特征。“率”这个词一看就是要做除法,再来看看ID这样的特征,由于取值可能性太多,自身熵值已经足够大,如果将此项作为分母,将信息增益作为分子,此时即便信息增益比较大,但由于其自身熵值更大,那么整体的信息增益率就会变得很小。
7.1.7回归问题求解
熵值可以用来评估分类问题,那么决策树是不是只能做分类任务呢?当然不止如此,回归任务照样能解决,只需要将衡量标准转换成其他方法即可。
在划分数据集时,回归任务跟分类任务的目标相同,肯定还是希望类似的数值划分在一起,例如,有一批游戏玩家的充值数据[100,150,130,120,90,15000,16000,14500,13800],有的玩家充得多,有的玩家充得少。决策树在划分时肯定希望区别对待这两类玩家,用来衡量不同样本之间差异最好的方法就是方差。在选择根节点时,分类任务要使得熵值下降最多,回归任务只需找方差最小的即可。
最终的预测结果也是类似,分类任务中,某一叶子节点取众数(哪种类别多,该叶子节点的最终预测类别就是多数类别的);回归任务中,只需取平均值当作最后的预测结果即可。
分类任务关注的是类别,可以用熵值表示划分后的混乱程度;回归任务关注的则是具体的数值,划分后的集合方差越小,把同类归纳在一起的可能性越大。
7.2决策树剪枝策略
讨论了如何建立决策树,下面再来考虑另一个问题:如果不限制树的规模,决策树是不是可以无限地分裂下去,直到每个叶子节点只有一个样本才停止?在理想情况下,这样做能够把训练集中所有样本完全分开。此时每个样本各自占领一个叶子节点,但是这样的决策树是没有意义的,因为完全过拟合,在实际测试集中效果会很差。
所以,需要额外注意限制树模型的规模,不能让它无限制地分裂下去,这就需要对决策树剪枝。试想,小区中的树木是不是经常修剪才能更美观?决策树算法也是一样,目的是为了建模预测的效果更好,那么如何进行剪枝呢?还是需要一些策略。
7.2.1剪枝策略
通常情况下,剪枝方案有两种,分别是预剪枝(Pre-Pruning)和后剪枝(Post-Pruning)。虽然这两种剪枝方案的目标相同,但在做法上还是有区别。预剪枝是在决策树建立的过程中进行,一边构建决策树一边限制其规模。后剪枝是在决策树生成之后才开始,先一口气把决策树构建完成,然后再慢慢收拾它。
(1)预剪枝。在构造决策树的同时进行剪枝,目的是限制决策树的复杂程度,常用的停止条件有树的层数、叶子节点的个数、信息增益阈值等指标,这些都是决策树算法的输入参数,当决策树的构建达到停止条件后就会自动停止。
(2)后剪枝。决策树构建完成之后,通过一定的标准对其中的节点进行判断,可以自己定义标准,例如常见的衡量标准:
式(7.4)与正则化惩罚相似,只不过这里惩罚的是树模型中叶子节点的个数。式中,C(T)为当前的熵值;Tleaf为叶子节点个数,要综合考虑熵值与叶子节点个数。分裂的次数越多,树模型越复杂,叶子节点也就越多,熵值也会越小;分裂的次数越少,树模型越简单,叶子节点个数也就越少,但是熵值就会偏高。最终的平衡点还在于系数(它的作用与正则化惩罚中的系数相同),其值的大小决定了模型的趋势倾向于哪一边。对于任何一个节点,都可以通过比较其经过剪枝后值与未剪枝前值的大小,以决定是否进行剪枝操作。
后剪枝做起来较麻烦,因为首先需要构建出完整的决策树模型,然后再一点一点比对。相对而言,预剪枝就方便多了,直接用各种指标限制决策树的生长,也是当下最流行的一种决策树剪枝方法。
现阶段在建立决策树时,预剪枝操作都是必不可少的,其中涉及的参数也较多,需要大量的实验来选择一组最合适的参数,对于后剪枝操作来说,简单了解即可。
7.2.2决策树算法涉及参数
决策树模型建立的时候,需要的参数非常多,它不像逻辑回归那样可以直接拿过来用。绝大多数参数都是用来控制树模型的规模的,目的就是尽可能降低过拟合风险,下面以Sklearn工具包中的参数为例进行阐述(见表7-2)。
表7-2 Sklearn工具包中的参数
针对sklearn工具包中的树模型,介绍了一下其参数的含义,后续任务中,就要使用这些参数来建立模型,只不过不仅可以建立一棵“树”,还可以使用一片“森林”,等弄明白集成算法之后再继续实战。
本章小结:本章介绍了决策树算法的构建方法,在分类任务中,以熵值为衡量标准来选择合适的特征,从根节点开始创建树模型;在回归任务中,以方差为标准进行特征选择。还需注意树模型的复杂程度,通常使用预剪枝策略来控制其规模。决策树算法现阶段已经融入各种集成算法中,后续章节还会以树模型为基础,继续提升整体算法的效果。
第7章完。
该书资源下载,请至异步社区:https://www.epubit.com