决策树

首先决策树是一种分类算法,长得像是一个根在上枝朝下的树。在介绍决策树之前首先介绍一下信息熵,这是决策树中一个非常重要的知识点。


信息熵

有些地方把信息熵叫做信息量,其实也能大致这样理解。信息量就是你知道一件事以后能得到的信息的多少,说白了是一种度量单位,然而得到信息的多少跟事件发生的概率有关系。最常举的例子,若有人告诉你,“太阳从东方升起从西方落下”,那你得到的信息量就为0,因为这件事发生的概率为1,就是一定会发生,所以在别人告诉你的那一刻,你就没有获得信息量。若别人告诉你,世界杯国足出线了,那么你获得的信息量就是巨大的,因为这件事发生的概率太低了(皮一下很开心)。从这里我们就得到了一条重要的性质或者可以叫信息熵的一条必要条件:信息熵随着事件发生的概率的增大而减小。

随之我们还可以想到一条性质:信息熵一定大于等于0。这个很好理解,因为不可能别人告诉了你一件事情你的信息量却减少了,那明显是不可能的。

还是上面的例子,若别人告诉你国足出线了,这件事的概率记做P(x),信息熵为X。同时又告诉你,今天上课点名了,这件事的概率记做P(y),信息熵为Y。你知道了两件事,你所得到的信息量一定是X+Y,然而这两件事情是独立的(不要说老师知道你看球故意点名),他们同时发生的概率P(x,y)=P(x)P(y)。这便得到了信息熵的第三个性质:两件独立的事情发生时,概率是乘积,信息熵是累加。

如果要用一个公式来表示信息熵,从第三条性质我们很容易想到它一定与log有关系,然而log是个递增函数,我们需要个递减的,那么log前面一定需要加一个负号。还要不为负数,那么一定是概率作为log的自变量,因为概率最大为1。综上所述,信息熵的公式就浮出水面了。

H(x)=−∑i=1nP(xi)log2P(xi)H(x)=-\sum_{i=1}^{n}P(x_{i})log_{2}P(x_{i})H(x)=i=1nP(xi)log2P(xi)

为什么log前面还要加概率?首先这里的X表示一个离散型随机变量,有n种结果,如果想要从整体角度求这个随机变量的信息熵就要考虑到这个随机变量的所有可能性,故这里用期望的思想来求。
为什么用2作为底数?其实这里用e作为底数也行,这里的log只是为了实现第一条性质和第三条性质,它的底数是没关系的,所以根据传统取2。

信息熵是表示随机变量不确定性的一种指标,熵越大,不确定性越高。同时也可以说信息熵是衡量样本集合纯度的一种指标,熵越小,越纯。

决策树

首先明确决策树是一种分类算法,它像是一个倒着的树,遵循if—then原则来对样本进行分类,如下图。
这里写图片描述
这是我在网上随便找的一张图(侵删),是一个简单的决策树模型,它通过样本数据的特征来一点一点判断,最终将样本归到正确的分类中。最上面的"拥有房产"这个节点称为根节点,中间诸如"已婚"、"年收入"等节点称为内部节点,内部节点就是表示一个特征或属性的取值。“可以偿还”、"无法偿还"等节点称为叶节点,叶节点对应着类别。
想要建立这个模型,如今的问题就是特征划分应该怎么个顺序去写。一般而言随着划分过程的不断深入,我们希望决策树的分支节点所包含的样本尽可能属于同一类别。遵循这个原则,我们提出以信息增益来判断特征对分类的贡献程度。

Gain(D,A)=H(D)−H(D∣A)Gain(D,A)=H(D)-H(D|A)Gain(D,A)=H(D)H(DA)

信息增益是熵与条件熵的差。前面是训练集D的熵,表示训练机D的不确定程度。后面是训练集D在特征A给定的情况下不确定程度。那么二者的差值就可以理解为由于给定了特征A,训练集D的不确定性降低了多少。显然,这个值越大说明这个特征对提纯的贡献越多。具体的公式如下:
Gain(D,A)=H(D)−∑v=1V∣Dv∣∣D∣H(Dv)Gain(D,A)=H(D)-\sum_{v=1}^{V}\frac{|D^{v}|}{|D|}H(D^{v})Gain(D,A)=H(D)v=1VDDvH(Dv)

根据信息增益的特征选择方法为:对数据集D的每个特征计算其信息增益,然后排序,选择最大的最为最先划分的特征。根据此特征划分之后可以形成几波子集(取决于此特征的取值多少),然后在这些子集上再分别计算信息增益并选择最大的进行划分,这样不断循环下去,直到所有特征都被划分完。下面来看一个周志华《机器学习》中的例子,加深理解。

这里写图片描述
这是一个二分类问题,色泽、根蒂、敲声、纹理、肚脐、触感是特征,是不是好瓜是标签,下面按照步骤先来计算"色泽"的信息增益。
这里写图片描述
这里写图片描述
注意其中条件熵的求法,特征不同取值的概率与不同取值所划分的子集的熵的积。
类似的还可以求出其他特征的信息增益。
这里写图片描述
发现纹理的信息增益是最大的,那么第一步就要从纹理开始划分。
这里写图片描述
纹理有三个取值,将训练集分成了三个子集,按照同样的原理准则,继续在这些子集上计算特征的信息增益,继续进行划分,直到每个分支包含的样本都属于同一类别。以下是结果。
这里写图片描述
以上方法叫做ID3算法。

ID3算法的缺点:

1、无法处理连续值特征,比如来一个西瓜的密度作为特征,密度的数值是连续的,它就无法处理。
2、对取值较多的特征有偏向。还是借用《机器学习》这本书中的例子,若数据集中最左侧的编号也作为一个特征的话,那么他被首先选上是必然的,因为总共17条数据它就有17个取值,意思是用它来划分将会产生17个分支,这17个分支每个分支仅仅包含一个样本,纯度自然非常非常高。当然这是一个比较极端的例子,但也反映了ID3算法对取值较多的特征有偏向。
3、没有考虑缺失值的处理。
4、没有考虑过拟合。

C4.5算法###

针对ID3的第一条和第二条缺点,C4.5算法做出了相应的改进。C4.5算法大致原理还是和ID3算法相同的,不同的是它以增益率作为选择特征的依据。增益率的定义为:
Gain_ratio(D,a)=Gain(D,a)IV(a)Gain\_ratio(D,a)=\frac{Gain(D,a)}{IV(a)}Gain_ratio(D,a)=IV(a)Gain(D,a) IV(a)=−∑v=1V∣Dv∣∣D∣log2∣Dv∣∣D∣IV(a)=-\sum_{v=1}^{V}\frac{|D^{v}|}{|D|}log_{2}\frac{|D^v|}{|D|}IV(a)=v=1VDDvlog2DDv

其中IV称为特征a的固有值,a的可取值数目越多,IV(a)通常会越大,作为分母它可以矫正信息增益偏向可取值数目多的特征的缺点。相反,增益率准则对可取值数量较少的特征会有偏向。为了解决这个问题,在C4.5算法中使用启发式来选择特征:先计算信息增益,将信息增益高于平均水平的特征摘出来,再从中选择增益率最高的。

针对信息增益无法处理连续值特征的问题,C4.5决策树算法采用连续特征离散化的方法来处理。假设连续特征a有n个取值,从小到大排列分别是a1,a2,a3…an。将其作为一个二元分类点来考虑,找到一个划分点t,小于等于t的作为一个分支,大于t的作为另一个分支。那么如何来找这个t呢?
假设这个t在a2和a3之间,那么无论t取什么值,数据集的划分都是一样的,所以我们不妨把t取成a2和a3的中点。于是我们找到特征a所有取值与相邻取值的中点,也就是
ti=ai+ai+12∣1≤i≤n−1t_{i}=\frac{a^{i}+a^{i+1}}{2}| 1\leq i \leq n-1ti=2ai+ai+11in1
我们将这些点作为离散属性,以这些点依次作为划分点来计算信息增益,最终选择信息增益最大的那一个划分点来作为最终的划分点。

C4.5决策树算法中有处理缺失值的方案。一般这里缺失值指的是缺失某些特征的取值,如果缺失标签的话这里的方法不适用。缺失值带来的问题有两个:
1、有缺失值的数据如何计算信息增益来实现特征选择?
2、有缺失值的特征在缺失的结点处该分到哪一类?

针对第一个问题,假设训练集D中没有缺失值的数据组成的子集为D~\widetilde{D}D,我们完全可以利用这些不缺失的数据来进行特征选择,但是有缺失值的数据的影响我们也要考虑。我们定义几个变量:
ρ=∑xϵD~ωx∑xϵDωx\rho = \frac{\sum_{x\epsilon \widetilde{D}}\omega_{x}}{\sum_{x\epsilon D}\omega_{x}}ρ=xϵDωxxϵDωx
表示无缺失样本所占的比例,其中ωx\omega_{x}ωx表示每个样本的权重,初始化样本的权重都是1。
p~k=∑xϵD~kωx∑xϵD~ωx其中1≤k≤∣y∣\widetilde{p}_{k} = \frac{\sum_{x\epsilon \widetilde{D}_{k}}\omega_{x}}{\sum_{x\epsilon \widetilde{D}}\omega_{x}} 其中 1\leq k \leq |y|pk=xϵDωxxϵDkωx1ky
表示无缺失值样本中第k类所占的比例。
γ~v=∑xϵD~vωx∑xϵD~ωx其中1≤v≤V\widetilde{\gamma}_{v} = \frac{\sum_{x\epsilon \widetilde{D}^{v}}\omega_{x}}{\sum_{x\epsilon \widetilde{D}}\omega_{x}}其中1\leq v \leq Vγv=xϵDωxxϵDvωx1vV
表示无缺失样本中在属性a上取值ava^{v}av的样本所占的比例。
基于这些定义我们就可以给出信息增益的用于应对有缺失值样本的推广:
Gain(D,a)=ρ∗Gain(D~,a)=ρ∗(Ent(D~)−∑v=1Vr~vEnt(D~v))Gain(D,a)=\rho*Gain(\widetilde{D},a)=\rho*(Ent(\widetilde{D})-\sum_{v=1}^{V}\widetilde{r}_{v}Ent(\widetilde{D}^{v}))Gain(D,a)=ρGain(D,a)=ρ(Ent(D)v=1VrvEnt(Dv))
其中:
Ent(D~)=−∑k=1∣y∣p~klog2p~kEnt(\widetilde{D})=-\sum_{k=1}^{|y|}\widetilde{p}_{k}log_{2}\widetilde{p}_{k}Ent(D)=k=1ypklog2pk
这个推广说白了就是未缺失值的子集的概率乘以子集的信息增益,这样就利用无缺失值的子集建立了计算信息增益的方程,同时还能考虑带有缺失值的数据带来了的概率问题。

对于第二个问题,当一个样本分类走到某个结点而此特征缺失时,将这个样本划分到下面所有的分支下,并调整这个样本的权值。假设样本在a属性的取值未知,在划分到取值为v的分支后,将权值调整为γ~v∗ωx\widetilde{\gamma}_{v}*\omega_{x}γvωx,其他分支也是同样的道理。权值的作用在于,在最后叶节点输出的时候,概率大的类别将作为输出,而权值将会影响最终的结果。

虽然C4.5算法改进了ID3算法的一些缺点,但其自身仍有缺点:
1、容易过拟合。(决策树过拟合的解决方法一般是剪枝)
2、C4.5生成的是多叉树结构,运行效率较低。(二叉树效率高)
3、C4.5中的大量的对数计算影响效率。
4、C4.5算法只能处理分类问题。

###CART ###

分类树

下面来介绍一下CART算法,全称为Classification and Regression Tree,分类与回归树。这个算法可以处理分类问题也可以处理回归问题。基本原理还是与之前的两个算法相同,不同的仍然是选择特征的依据。CART算法依据基尼指数(此处指分类树):
Gini(D)=∑k=1∣y∣∑k′≠kpkpk′=1−∑k=1∣y∣pk2Gini(D)=\sum_{k=1}^{|y|}\sum_{k^{'}\neq k}^{}p_{k}p_{k^{'}}=1-\sum_{k=1}^{|y|}p^{2}_{k}Gini(D)=k=1yk̸=kpkpk=1k=1ypk2
基尼指数反映了从数据集D中随机抽取两个样本,其类别标记不一致的概率,其实非常好理解,基尼指数越小,数据集的纯度越高。
那么特征A的基尼指数定义为:
Gini_index(D,a)=∑v=1V∣Dv∣∣D∣Gini(Dv)Gini\_index(D,a)=\sum_{v=1}^{V}\frac{|D^{v}|}{|D|}Gini(D^{v})Gini_index(D,a)=v=1VDDvGini(Dv)
只需利用这个准则算出当前数据集中所有特征的基尼指数并选择基尼指数最小的特征进行划分即可。

对于连续型特征CART算法的处理思路与C4.5算法相同,也是将所有点的中点作为划分点来一一计算,不同的是这里计算的是基尼指数,并根据基尼指数来选择最终划分点。

针对C4.5算法的第二条缺点,CART算法采用无限二分的方法解决。假设特征A的取值有a,b,c三种,那么可以分成a和bc或者是别的组合,看哪种组合的基尼指数更小。依次划分后在下一分支里特征A因为有bc两个取值还未被完全划分,特征A仍然可以和别的特征参与"竞选"。

针对C4.5算法的第三条缺点,基尼指数的计算不涉及对数,自然解决。对于处理回归问题,CART也能生成回归树模型。
######回归树#
回归问题与分类问题最大的不同就是回归问题的输出是连续值,这也直接导致了回归树选择特征的依据的不同。回归树采用平方误差的准则来选择特征和切分数据集,并以无限二叉树的原则不断形成决策树。

具体策略是这样的。选择一个特征j(任意)并以这个特征的取值s作为切分点来将数据集切分成两部分,计算这个取值s作为划分点划分开的两个数据集的方差的和。将特征j的所有取值都作为划分点并求方差和,选出使两个数据集方差和最小的那个值作为最优切分点。用公式来表达如下:
minj,s[minc1∑xiϵR1(j,s)(yi−c1)2+minc2∑xiϵR2(j,s)(yi−c2)2]\underset{j,s}{min}\left [ \underset{c_{1}}{min}\sum_{x_{i}\epsilon R_{1}(j,s)}(y_{i}-c_{1})^{2}+ \underset{c_{2}}{min}\sum_{x_{i}\epsilon R_{2}(j,s)}(y_{i}-c_{2})^{2}\right ]j,sminc1minxiϵR1(j,s)(yic1)2+c2minxiϵR2(j,s)(yic2)2

其中c1和c2分别是被切分成的两个数据集的标签的均值。

将上述步骤遍历所有特征,求出每个特征的最优切分点s和以此点切分成的两个数据集的方差和q。比较所有特征的最小方差,选择q最小的特征作为优先划分的节点,用此特征的最优划分点s将将数据集划分成两部分,也就是发展出两个分枝。之后在两个子集上重复两个步骤,直到划分完毕。
形成决策树后每个叶节点可能包含不止一条数据,这时我们采用这些数据的中位数或者平均值作为输出。

剪枝

容易过拟合是决策树的一个缺点,剪枝处理就是决策树对付过拟合的主要手段。剪枝顾名思义就是遵循一定规则把决策树的树枝剪了以使得模型表现出更好的性能,剪枝分为预剪枝和后剪枝。

预剪枝是在选择特征划分结点的时候计算将当前特征作为结点划分能不能提高模型的泛化能力。如果有训练集可以计算划分结点前后训练集被分类正确的正确率,如果没有训练集可以从测试集中事先留出一部分作测试集。当当前结点的划分不能使得模型的泛化性能提高时,从这个结点开始就不再展开,直接变成叶结点,以子集中数目最多的类别作为输出。
优缺点:
优点是非常明显的,预剪枝不仅降低了过拟合的风险,还减少了决策树的训练时间开销和测试时间开销。
这样"一刀切"的准则给预剪枝带来了"欠拟合"的风险,也是预剪枝的缺点。因为当前结点的划分虽不能提高模型的泛化性能,但此结点之后的结点划分有可能提高模型的泛化性能,这样直接一刀切未免太过武断。

后剪枝是先从训练集生成一棵完整的决策树,然后自下而上进行修剪,依据的原则也是模型的泛化能力。如果剪之后比剪之前的泛化能力强就修剪掉,否则保留。一般来说后剪枝都会比预剪枝保留更多的分支。
与预剪枝不同的是,后剪枝需要对决策树中的所有非叶结点进行考察。借用周志华的西瓜书中的例子。
这里写图片描述
假如对"纹理"这个结点计算后,剪掉能提高泛化能力,那么就剪掉。接着对5号结点的"色泽"计算后,留着比较好,那么就留着。此时还需要对这条路上的3号结点"根蒂"进行计算,并不是5号结点"色泽"留住后就不需要考虑3号了。3号的计算结果要和5号的计算结果相比较(5号计算后决定留住的情况下),因为把3号剪了5号也会被剪。
优缺点:
一般情况下,后剪枝的欠拟合风险较小,泛化性能往往优于预剪枝。
但后剪枝需要决策树完全生成后才能进行,并且要自下而上对所有非叶结点进行一一考察,其训练时间开销相对要大。

借用博客园 “刘建平Pinard” 大神博客中的一个表格来总结对比一下三个决策树算法:
这里写图片描述

多变量决策树

不同的决策树模型采用不同的方法来选择特征,但相同的是他们都是一个一个进行特征选择,在很多情况下连续利用一个一个的特征去进行分类任务往往不是最优选择,这时候用一组特征去分类可能会达到更好的效果。这时就需要选择哪种特征组合是最好的,然后首先进行结点划分,这里不仅要考虑组合的不同还要考虑使用多少特征去进行组合,这种算法叫做多变量决策树。这里就不介绍了,以后有空再说。

现在我们站在总体的角度来看一下决策树的优缺点。
优点:
1、简单易于理解,生成的树形图非常直观。
2、既可处理离散值也可处理连续值,且可以处理缺失值。
3、能够处理多输出问题。
4、决策树算法的时间复杂度(即预测数据)是用于训练决策树的数据点的对数,即代价为O(log2m) 。
5、使用白盒模型,逻辑上更容易解释和理解。(人工神经网络就是黑箱模型)
6、可以通过统计验证来验证模型。

缺点:
1、容易过拟合。(可以通过剪枝处理、限制结点最少样本数量、限制树的深度来解决)
2、决策树会因为样本中的一点改变而导致整个树结构的改变,结果不稳定。(可以通过集成学习算法来解决)
3、寻找最优决策树的问题是一个NP问题,容易陷入局部最优解的情况。(可以通过集成学习算法来解决)
4、有些比较难复杂的关系(如异或)决策树无法学习。
5、当出现数据不平稳问题时,生成的决策树会偏向占主导的样本。
6、忽略特征之间的相互联系。

决策树在sklearn中的应用说明

本节参考sklearn官方文档和博客园“刘建平Pinard“大神的博客。

from sklearn.tree import DicisionTreeClassifier

参数:

  • criterion:string, optional (default=”gini”) 决定选择特征的函数,可选gini,entropy。分别表示基尼指数和信息增益。
  • splitter : string, optional (default=”best”) 可选best,random。前者在特征的所有划分点中找出最优的划分点。后者是随机的在部分划分点中找局部最优的划分点。默认的best适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐random
  • max_depth : int or None, optional (default=None) 最大深度。如果是None,就会将所有特征都划分完或者直到某个结点包含的样本数少于规定的结点最少样本。除此之外可以使用很多种类型的值,如果是"log2"意味着划分时最多考虑log2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑根号N个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。(一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。)
  • min_samples_split : int, float, optional (default=2)结点再划分最小样本数,如果低于设定的数字就不再进行划分。这个可以根据样本量的大小进行调整。(同样int是确定的数,float是百分比)
  • min_samples_leaf : int, float, optional (default=1) 叶节点所包含的最小样本数,如果少于设定值,此叶节点将会和兄弟结点一同被剪枝。(同样int是确定的数,float是百分比)
  • min_weight_fraction_leaf : float, optional (default=0.) 叶节点最小样本权重和,低于设定值将会,此叶节点将会和兄弟结点一同被剪枝。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
  • max_features : int, float, string or None, optional (default=None) 划分时所考虑的最大特征数。(可以int,float,log2,auto,sqrt,含义与之前相同)
  • random_state : int, RandomState instance or None, optional (default=None) 随机数种子生成器,当上面splitter=random时决定随机数种子。
  • max_leaf_nodes : int or None, optional (default=None) 最多叶节点数,通过限制可以防止过拟合。
  • min_impurity_decrease : float, optional (default=0.) 最低不纯度降低率。如果某节点样本的不纯度减少率低于设定值,就不再生长。
  • min_impurity_split : float 和上一条类似,只不过这个是确定的值,上面是变化率。
  • class_weight : dict, list of dicts, “balanced” or None, default=None 类别的权重,为了应对样本不平衡问题。选择banlanced会按照系统事先编好的方式来计算。
  • presort : bool, optional (default=False) 是否对数据预排序。

属性比较简单,就不多做说明,直接贴一张官网的截图。
这里写图片描述

方法:
返回预测值所属的叶节点的序号
这里写图片描述
返回决策路径
这里写图片描述
训练模型
这里写图片描述
返回模型参数
这里写图片描述
预测
这里写图片描述
返回概率形式的结果
这里写图片描述
给模型在训练集上评分
这里写图片描述
设定模型参数
这里写图片描述

from sklearn.tree import DecisionTreeRegeressor

(与回归树相同的不再介绍)

参数:

  • criterion : string, optional (default=”mse”) 可选mse和mae。可以使用"mse"或者"mae",前者是均方差,后者是和均值之差的绝对值之和。推荐使用默认的"mse"。一般来说"mse"比"mae"更加精确。
  • splitter : string, optional (default=”best”)
  • max_depth : int or None, optional (default=None)
  • min_samples_split : int, float, optional (default=2)
  • min_samples_leaf : int, float, optional (default=1)
  • min_weight_fraction_leaf : float, optional (default=0.)
  • max_features : int, float, string or None, optional (default=None)
  • random_state : int, RandomState instance or None, optional (default=None)
  • max_leaf_nodes : int or None, optional (default=None)
  • min_impurity_decrease : float, optional (default=0.)
  • min_impurity_split : float
  • presort : bool, optional (default=False)

属性:
这里写图片描述

方法:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值