决策树
来源:互联网 发布:托业网络课程 编辑:程序博客网 时间:2024/06/07 04:06
决策树
模型介绍
决策树算法在机器学习中算是很经典的一个算法系列了。它既可以作为分类算法,也可以作为回归算法,同时也特别适合集成学习比如随机森林。
决策树是对特征空间(数据集)的一个划分,在每个划分单元上有一个特定的输出值。假设决策树将特征空间划分成M个单元
而决策树的树形结构展现的是对特征空间的划分规则。划分规则可以有很多,也可能不存在,如何选择最好的划分规则是构建决策树的关键。
如何度量一个决策树的好坏呢?根据(1)中的
特征空间的划分过程对应于决策树的构造过程,而特征空间的划分依据的是特征和特征的取值,所以特征的选择成为构建决策树的关键。根据特征选择的方式可以将决策树算法分为ID3,C4.5和CART。
特征选择
信息增益
学习信息增益,首先要明白什么是熵和条件熵
熵:表示随机变量不确定性的度量。设X是一个取值有限的随机变量,其概率分布为
P(X=xi)=pii=1,2,...,n 则随机变量X的熵定义为
H(X)=−∑i=1npilogpi 条件熵:条件熵
H(Y|X) 表示在已知随机变量X的条件下,随机变量Y的不确定性,定义为X给定条件下Y的条件概率分布的熵对X的数学期望H(Y|X)=∑i=1npiH(Y|X=xi) 其中
H(Y|X=xi) 是Y的条件概率分布的熵互信息:表示得知X之后,Y的信息的不确定性减少的程度
I(Y,X)=H(Y)−H(Y|X) 信息增益:在决策树中的信息增益等价于训练数据D中类别与特征A的互信息
g(D,A)=H(D)−H(D|A) 其中
H(D) 表示对训练数据集D分类的不确定性,是对类别分布的熵。H(D|A) 是在特征A确定的条件下,数据集分类的不确定。信息增益即在给定特征A之后,数据集分类不确定性的减少。
如何根据信息增益选择最优的特征?对训练数据集D,计算每个特征的信息增益,选择信息增益最大的特征为最优的特征。
设训练数据集为D,|D|是样本的个数。设有K个类别
计算数据集D的熵
H(D) H(D)=−∑i=1K|ck||D|log|ck||D| 计算特征A对数据集D的条件熵
H(D|A) H(D|A)=∑i=1n|Di|DH(Di)=−∑i=1n|Di|D∑i=1K|Dik||Di|log|Dik||Di| 计算信息增益
g(D,A)=H(D)−H(D|A)
信息增益比
以信息增益作为划分训练数据集的度量,容易偏向选择取值较多的特征,使用信息增益比可以解决这一问题。
其中
基尼系数
以随机变量X为例,基尼系数的定义为
如果是二分类问题,属于第一类的概率为
基尼系数常用于CART分类树的构建,而CART树是二叉树,根据特征A将数据集分为两部分
基尼系数代表了模型的不纯度,基尼系数越小,模型的不纯度越低,表示特征越好,这和信息增益(比)是相反的。
同时基尼系数的计算中没有对数的计算,比信息增益比要快速和精确,而且基尼系数的曲线和熵近似,可以作为熵的一种替代。
决策树的生成
决策树的生成对应于特征空间划分的过程。首先将数据集(特征空间)作为根节点,在所有特征中选择一个最好特征最为划分特征,根据特征的取值将数据集划分为多个子集,作为子节点,然后递归地对子节点进行划分,直到满足停止条件。
根据上节三种特征选择的度量方式,可以将决策树生成算法分为ID3,C4.5和CART。
ID3
ID3算法构造一棵分类树。首先给出ID3算法的流程:
输入:数据集D
输出:决策树T
- 判断D中所有实例是否只属于一类
ck ,如果是,则返回单节点树,并将ck 作为节点该的类标记,即该划分子空间的输出 - 判断特征是否为空,如果为空,用多数投票选出该节点的类别,并返回单节点树和类别标记
- 计算样本中各个特征对应的信息增益,选择信息增益最大的特征作为最佳划分特征
- 如果最佳划分特征下数据的信息增益小于阈值,则返回单节点树,并用多数投票的方法选出该节点的类别标记;否则,根据该特征的每一个可能值,将数据集划分成若干个非空子集,每个子集作为该节点的子节点
- 对每一个子节点重复2-5
决策树构建完毕之后,每一个叶节点对应的是一个划分空间,假设有M个划分空间
ID3算法虽然提出了新思路,但是还是有很多值得改进的地方。
- ID3没有考虑连续特征,比如长度,密度都是连续值,无法在ID3运用。而且ID3只能用于分类。
- ID3采用信息增益大的特征优先建立决策树的节点。但是在相同条件下,取值比较多的特征比取值少的特征信息增益大。比如一个变量有2个值,各为1/2,另一个变量为3个值,各为1/3,其实他们都是完全不确定的变量,但是取3个值的比取2个值的信息增益大。如果校正这个问题呢?
- ID3算法对于缺失值的情况没有做考虑
- 没有考虑过拟合的问题
C4.5
C4.5利用信息增益比改善ID3中的第二个问题,同时可以将连续特征离散化来解决第一个问题。至于第三个和第四个问题,之后具体讲解。
C4.5和利用信息增益比选择特征,其余和ID3完全一样。不做解释。
但是C4.5仍然有一些缺点,1、信息增益比的计算中有对数的计算,在计算过程中会损失准确定;2、C4.5是一颗多叉树,很多时候,在计算机中二叉树模型会比多叉树运算效率高。如果采用二叉树,可以提高效率。3、C4.5仍然只能用于分类。
CART
CART采用基尼系数来选择特征,避免了对数的计算。同时每次划分数据集是只将其划分为两部分,所以CART是一棵二叉树,而且CART回归树可以处理回归问题。
CART分类树
CART是一颗二叉树,首先选择最佳划分的特征,然后选择最佳划分的值,每次划分出一棵二叉树。回忆下ID3或者C4.5,如果某个特征A被选取建立决策树节点,如果它有a1,a2,a3三种类别,我们会在决策树上一下建立一个三叉的节点。这样导致决策树是多叉树。但是CART分类树使用的方法不同,他采用的是不停的二分,还是这个例子,CART分类树会考虑把A分成{a1}和{a2,a3}, {a2}和{a1,a3}, {a3}和{a1,a2}三种情况,找到基尼系数最小的组合,比如{a2}和{a1,a3},然后建立二叉树节点,一个节点是a2对应的子集,另一个节点是{a1,a3}对应的子集。同时,由于这次没有把特征A的取值完全分开,后面我们还有机会在子节点继续选择到特征A来划分a1和a3。这和ID3或者C4.5不同,在ID3或者C4.5的一棵子树中,离散特征只会参与一次节点的建立。
CART分类树的算法如下:
- 给定训练数据D和标签以及类别
{c1,c2,...,cK} - 设节点的训练数据集为D,计算现有特征对该数据集的基尼系数。对每一个特征A,对其可能的每一个取值
ai ,判断A=ai 是否成立将数据集分成两部分,计算相应的基尼系数,并选择基尼系数最小的特征和取值划分数据,生成两个子节点 - 对两个子节点递归调用2,直到满足停止条件
停止条件是1、节点中样本个数小于阈值;2、样本子集的基尼系数小于阈值;3、没有更多的特征用于划分
CART回归树
回归树不再次用信息增益(比)或基尼系数来选择特征和划分点,而是使用平方误差最小的准则求解最优的特征和划分值。遍历数据集中的每一个特征和该特征的每个取值,对于第j个特征的取值s,将数据集划分为两个子集,划分规则是
计算对应子集的输出值
其中
最后求解平方误差
选择可以使上式最小的j,s划分数据集。
CART回归树的算法流程如下:
根据上文选择最优的特征j和切分点s
用选定的
(j,s) 将数据集划分成两个区域作为两个子节点,并确定相应的输出值划分区域为
R1(j,s)={x|x(j)≤s}andR2(j,s)={x|x(j)>s} 输出值为
c1=ave(yi|xi∈R1(j,s))andc2=ave(yi|xi∈R2(j,s)) 对子节点(子集)重复1,2,直到满足停止条件
停止条件是1、节点中样本个数小于阈值;2、样本集的平方误差小于阈值;3、没有更多的特征用于划分
构建好决策树之后,给定待预测的样本
CART回归树和分类树有两点主要的区别:1、选择特征和切分点的度量方式不同,分类树采用基尼系数,而回归树采用平方误差;2、叶节点的输出求解方式不同,分类树叶节点的输出是该节点对应子集中采用大多数样本的类别,而回归树叶节点的输出是该节点对应子集中所有样本目标的均值。
ID3,C4.5和CART的区别
看起来CART算法高大上,那么CART算法还有没有什么缺点呢?有!主要的缺点我认为如下:
- 应该大家有注意到,无论是ID3, C4.5还是CART,在做特征选择的时候都是选择最优的一个特征来做分类决策,但是大多数,分类决策不应该是由某一个特征决定的,而是应该由一组特征决定的。这样的决策树更加准确。这个决策树叫做多变量决策树(multi-variate decision tree)。在选择最优特征的时候,多变量决策树不是选择某一个最优特征,而是选择最优的一个特征线性组合来做决策。这个算法的代表是OC1,这里不多介绍
- 如果样本发生一点点的改动,就会导致树结构的剧烈改变,即决策树对异常点很敏感。这个可以通过集成学习里面的随机森林之类的方法解决。
剪枝
魏红宁. 决策树剪枝方法的比较[J]. 西南交通大学学报, 2005, 40(1):44-48.
决策树算法递归地产生决策树,直到不能继续下去为止,这样得到的决策树往往对训练数据分类很准确,但是对未知的测试数据却没有那么准确,即偏差小,方差大,容易出现过拟合现象。过拟合的原因在于学习时过多考虑如何提高对训练数据的正确分类,从而得到复杂的决策树。所以要对决策树进行简化,简化的过程称为剪枝(pruning)。剪枝的方法分为两种:预剪枝和后剪枝。
预剪枝:在决策树构造过程中,根据某些条件,提早停止树的构造。比如节点中样本个数小于阈值,决策树的高度达到指定高度等,sklearn.tree中使用的就是预剪枝,阈值需要自己设置。缺点是可能会产生欠拟合。
后剪枝:在生成决策树之后进行剪枝,得到简化的决策树。后剪枝又可以分为两类:1、自底向上;2、自顶向下。思想就是从原始决策树中,按照规则将非叶节点剪枝成为叶节点,比较剪枝前后决策树的误差决定是否要剪枝,直到得到误差最小的决策树。后剪枝和预剪枝相比,需要消耗额外的时间,但是效果更好。
REP(reduced error pruning):REP是当前最简单的后剪枝方法,需要一个额外的数据集D辅助剪枝过程。基本思路是,对于决策树T中的每个非叶子节点S,将其子树都剪去,成为一个叶节点,此时的决策树为
TS ,计算D在T和TS 上的误差,如果TS 的误差小于T的误差,则对该非叶节点剪枝,否则不剪枝。虽然REP很简单,但是需要一个额外的数据集,当数据量小的时候,一般不采用这种方法。REP是自底向上的后剪枝方法。PEP(pessmistic error pruning):PEP方法是为了克服REP方法需要额外剪枝数据缺点而提出的,不需要额外的剪枝数据。PEP按照以下公式对每个非叶节点自上而下计算,如果满足,则将该非叶节点剪枝成为叶节点,直到遍历完所有非叶节点。
——(1)e′(t)≤e′(Tt)+Se(e′(Tt)) 其中
e′(t)=e(t)+0.5 e′(Tt)=∑ie(i)+2/Nt Se(e′(Tt))=[e′(Tt)n(t)−e′(Tt)n(t))]12 e(t) 是非叶节点t处的误差,Tt 是以t为根节点的子树,i 是子树Tt 的叶子结点的编号,Nt 是子树Tt 叶子结点的个数,n(t) 是非叶节点t处训练样本的个数。对于每个非叶节点,如果满足(1)式,在在该处剪枝。下面给出一个例子:
上图中的非叶节点有5个,从
t1 到t5 。首先对t1 计算:e′(t1)=25+0.5=25.5 ,以t1 为根的子树有6个叶节点,所以e′(Tt1)=1+2+1+1+6/2=8 ,Se(e′(Tt1)=[8∗80−880]12=2.68 ,因为25.5>8+2.68 ,所以不用剪枝。依次计算t2 到t5 ,只有t4 需要剪枝,所以讲t2 的两个子树剪掉,是t4 称为一个叶节点。PEP是一种自顶向下的剪枝方法,是目前比较精确的一种剪枝方法。但是PEP和预剪枝有同样的缺陷,由于是自顶向下的剪枝,如果某个非叶节点需要剪枝,则连通其所有子节点一同剪去,而这些剪去的叶节点并没有判断。
在PEP中,每个非叶节点最多只用判断一次,所以剪枝速度很快。
CCP(cost-complexity pruning):CCP主要包含两个步骤,1、从原始的决策树
T0 中按照规则生成一个子树序列T0,T1,...,Tn ,其中Tn 是只包含根节点的树;2、从子树序列中根据误差估计选择一棵最好的树最为剪枝后的决策树。(在《统计学习方法》P72页有详细介绍)1、如何从原始决策树生成一个子树序列:子树
Ti+1 是从子树Ti 生成的。对子树Ti 的每个非叶节点计算下式α=R(t)−R(Tt)|L(Tt)|−1 其中
Tt 是以非叶节点t 为根节点的子树,R(Tt) 是测试数据在该子树上的误差(如果是回归树,计算均方误差),R(t) 是剪枝后该节点上的误差,|L(Tt)| 是子树的叶子节点数。选择α 最小的非叶节点进行剪枝得到Ti+1 ,并记录对应的αi+1=α 直到只剩一个根节点为止,即Tn 。2、如何从子树序列中选择最优的决策树:在得到子树序列后,用测试数据在每个决策树上计算
Rα(Ti)=R(Ti)+α|L(Ti)|,i=0,1,2,...,n ,找到使Tα(Ti) 最小的i,对应的决策树即为剪枝后的决策树。具体步骤如下:
输入:原始决策树
T0 输出:剪枝后最优决策树
Tα 设
k=0,T=T0,α=+∞ 自下而上地对每个非叶节点计算
g(ti)=R(ti)−R(Tt)|L(Tti)|−1 并找到使
g(ti) 最小的非叶节点tm ,对该节点进行剪枝,并对该叶节点以多数表决法决定其输出类别,得到树T,并有α=g(tm) 设
k=k+1,αk=g(tm),Tk=T 如果
T 不是只有根节点构成的树,则回到第2步采用交叉验证法计算
Rα(Ti)=R(Ti)+α|L(Ti)|,i=0,1,2,...,n ,得到miniRα(Ti) ,得到最优子树Ti
以上图为例,图中所示的是
T0 ,首先对非叶节点T−2T5 计算g(ti) ,R(t5)=4/80,R(Tt5)=0,L(TT5)=2,g(t5)=4/80=0.02 ,依次计算g(t4)=0.0125,g(t3)=0.0375,g(t2)=0.0293 ,其中最小的是g(t4) ,所以对t4 剪枝得到T1 ,并且α1 =0.0125。CCP是一个自底向上的剪枝方法,所需的时间与非叶节点的个数成二次关系,所以和PEP相比比较慢,而且CCP方法存在一个缺点,就是最优决策树只能从
T0,T1,...,Tn 中选择,如果最优决策树不再这个序列中,的不能得到。
总之,决策树的剪枝是在遍历每个非叶节点的过程中,通过剪枝和测试的动态过程中完成的。
缺失值处理
巩固, 张虹. 决策树算法中属性缺失值的研究[J]. 计算机应用与软件, 2008, 25(9):242-244.
《机器学习》 周志华
http://blog.csdn.net/zrjdds/article/details/50223091
Python中处理缺失值
决策树为什么对缺失值不敏感
决策树的优点和缺点
总结于scikit-learn的英文文档。
首先我们看看决策树算法的优点:
- 简单直观,生成的决策树很直观。
- 基本不需要预处理,不需要提前归一化,处理缺失值。(sklearn.tree中不能处理缺失值)
- 使用决策树预测的代价是O(log2m)。 m为样本数。
- 既可以处理离散值也可以处理连续值。很多算法只是专注于离散值或者连续值。
- 可以处理多维度输出的分类问题。
- 相比于神经网络之类的黑盒分类模型,决策树在逻辑上可以得到很好的解释
- 可以交叉验证的剪枝来选择模型,从而提高泛化能力。
- 对于异常点的容错能力好,健壮性高。
我们再看看决策树算法的缺点:
- 决策树算法非常容易过拟合,导致泛化能力不强。可以通过设置节点最少样本数量和限制决策树深度来改进。即使通过剪枝,也不能完全避免。
- 决策树会因为样本发生一点点的改动,就会导致树结构的剧烈改变。这个可以通过集成学习之类的方法解决。
- 寻找最优的决策树是一个NP难的问题,我们一般是通过启发式方法,容易陷入局部最优。可以通过集成学习之类的方法来改善。
- 有些比较复杂的关系,决策树很难学习,比如异或。这个就没有办法了,一般这种关系可以换神经网络分类方法来解决。
- 如果某些特征的样本比例过大,生成决策树容易偏向于这些特征。这个可以通过调节样本权重来改善。
sklearn.tree
scikit-learn决策树算法类库内部实现是使用了调优过的CART树算法,既可以做分类,又可以做回归。分类决策树的类对应的是DecisionTreeClassifier,而回归决策树的类对应的是DecisionTreeRegressor。两者的参数定义几乎完全相同,但是意义不全相同。下面就对DecisionTreeClassifier和DecisionTreeRegressor的重要参数做一个总结,重点比较两者参数使用的不同点和调参的注意点。
除了这些参数要注意以外,其他在调参时的注意点有:
- 当样本少数量但是样本特征非常多的时候,决策树很容易过拟合,一般来说,样本数比特征数多一些会比较容易建立健壮的模型
- 如果样本数量少但是样本特征非常多,在拟合决策树模型前,推荐先做维度规约,比如主成分分析(PCA),特征选择(Losso)或者独立成分分析(ICA)。这样特征的维度会大大减小。再来拟合决策树模型效果会好。
- 推荐多用决策树的可视化,同时先限制决策树的深度(比如最多3层),这样可以先观察下生成的决策树里数据的初步拟合情况,然后再决定是否要增加深度。
- 在训练模型先,注意观察样本的类别情况(主要指分类树),如果类别分布非常不均匀,就要考虑用class_weight来限制模型过于偏向样本多的类别。
- 决策树的数组使用的是numpy的float32类型,如果训练数据不是这样的格式,算法会先做copy再运行。
- 如果输入的样本矩阵是稀疏的,推荐在拟合前调用
csc_matrix
稀疏化,在预测前调用csr_matrix稀疏化。
关于DecisionTreeClassifier 和 DecisionTreeRegressor 中的方法
首先实例化,实例化的参数根据上表选择
利用fit(X,y)函数构建决策树
采用predict(testSet)预测类别或者也测目标值
次用score(testSet)计算分类误差(分类树)或者均方误差(回归树)
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- HDU-5929 Basic Data Structure
- Android进阶#(1/12)Android的构成基石——四大组件_Service与AIDL
- ComponentFactory取得DOM节点
- Android开发中windowSoftInputMode属性详解
- 廖雪峰《python3 基础教程》读书笔记——第十九章 电子邮件
- 决策树
- ubuntu16.04配置py-faster-rcnn
- Khatri-Rao积(KR积)
- NFS(Network File System) Configuration
- UEditor + golang 实现图片上传
- Storm+Kafka+Hbase的wordcount统计
- 三步搞定Windows下的qt静态编译环境
- getAttribute&getParameter 区别
- conda 安装软件