Decision Tree
在分类模型中,决策树算法绝对是最常用的模型之一,当然目前基本没有人会用单棵决策树去做分类或者回归,都是用的集成的树模型。决策树的思想其实并不复杂,人类在判断一件事物是好是坏,是优是劣的时候,通常是这样做的,比如判断一个男人容不容易找到女朋友:先考虑年龄,太大的找不到,年龄合适的再看工资,太少的找不到,太多的没问题,中等水平的再看有没有房,没房的找不到,有房的再看……那么决策树就是在做这样一种判断,它借助树模型,把每个特征看作是一个节点,对每个特征进行划分,构建起一棵树,如图所示:

那么当我们拿到一条新数据的时候,预测的过程就是我们上面语言描述的过程。继续这个例子,假设现在有一位人类高质量男性,他30岁、年薪30k,在上海有一套汤臣一品,那么我们把这位人类高质量男性输入我们的决策树,模拟的过程如下:
- 年龄30岁,进入左子树
- 年新30k,进入左子树
- 有房产,进入左子树
- 已经是叶子节点了,返回结果:“能找到女朋友”
决策树算法通用形式伪代码如下:

那么问题来了,我怎么知道以什么顺序去评估每个节点呢?或者说,每当我要递归建树的时候,该怎么去选取我当前的根节点呢?也就是伪代码中“从A中选择最优划分属性a∗a_*a∗”。答案是不唯一的,但不管是那种度量方法,我们的原则是不变的:按照该特征划分后,数据集的纯度能够越来越高。当下有三种非常经典的决策树模型:ID3、C4.5、CART。下面我们分别来详细介绍
ID3
在介绍ID3之前,我们先来介绍一个信息论当中非常重要的概念:熵
Entropy
信息熵是度量样本集合纯度的一种指标,假设样本集DDD中第kkk个类别的样本占比重为pkp_kpk,那么样本集DDD的信息熵(香农熵)定义为:
Ent(D) = −∑i=1kpklog2pk
Ent(D) \ = \ -\sum_{i=1}^kp_klog_2{p_k}
Ent(D) = −i=1∑kpklog2pk
Ent(D)Ent(D)Ent(D)越小代表样本集纯度越高。
Information Gain
假设特征aaa有VVV个不同的取值{a1,a2,…,aV}\{a^1, a^2,\dots,a^V\}{a1,a2,…,aV},如果使用特征aaa对当前样本进行划分,那么就会产生VVV个子结点,定义DvD_vDv表示所有在特征aaa取值为ava^vav的样本集合,那么我们定义按照特征aaa进行划分的信息增益为:
Gain(D,a)=Ent(D)−∑v=1V∣Dv∣∣D∣Ent(Dv)
Gain(D, a)=Ent(D)-\sum_{v=1}^V{\frac{|D_v|}{|D|}Ent(D_v)}
Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
之前我们说EntEntEnt越小,样本集纯度越高,那么来观察信息增益的式子,如果信息增益越大,就说明后面的那一项小,也就是EntEntEnt小,那么样本集纯度就得到了提升。因此,ID3算法的划分属性依据就是信息增益,每一次选取剩余特征中信息增益最大的特征最为 当前的节点。
a∗=argmax Gain(D,a)
a^*=argmax \ \ \ Gain(D,a)
a∗=argmax Gain(D,a)
西瓜书上的这个例子非常的具体,看一遍就能完全理解这个过程



Algorithm
输入训练集DDD、特征集AAA、阈值ϵ\epsilonϵ,输出决策树TTT,ID3算法的大体流程如下:
- 如果当前DDD中所有样本都属于同一类别,那么TTT为点单点树,并以这个类别作为该节点的类别,返回TTT。
- 如果A=ϕA=\phiA=ϕ,则TTT为单节点树,返回DDD中样本数最多的类别CCC作为该节点的类别,返回TTT。
- 否则,计算AAA中所有特征对样本集DDD的信息增益,选取信息增益最大的特征AgA_gAg。
- 如果AgA_gAg对DDD的信息增益小于阈值ϵ\epsilonϵ,那么TTT为单节点树,返回DDD中样本数最多的类别CCC作为该节点的类别,返回TTT。
- 否则,对于AgA_gAg每一种可能的取值aia_iai,按照Ag=aiA_g=a_iAg=ai将DDD划分为若干非空集合DiD_iDi,将DiD_iDi中样本数最多的类别作为当前节点的类别,构建子节点,由该结点和其子结点构成树TTT,返回TTT。
- 对于第5步中得到的每个子结点iii,以DiD_iDi为训练集,A−{Ag}A-\{A_g\}A−{Ag}为特征集,递归地调用第1~5步,得到子树TiT_iTi,返回TiT_iTi。
C4.5
下面我们来考虑一下信息增益的缺点:信息增益会偏向特征取值多的特征。举个最极端的例子,每个样本有都有一个编号,假如我们把编号也当做是一个特征,那么很显然,按照编号划分后的样本集纯度是最高的。但这样的模型显然过拟合现象非常严重。为了改进这一缺点,有人提出了C4.5算法。
Gain Ratio
C4.5采用的度量最优划分特征的依据是“信息增益率”,公式为:
Gain_Ratio(D,a)=Gain(D,a)IV(a)IV(a)=−∑v=1V∣Dv∣∣D∣log2∣Dv∣∣D∣
Gain\_Ratio(D,a)=\frac{Gain(D,a)}{IV(a)} \\
IV(a)=-\sum_{v=1}^V{\frac{|D_v|}{|D|}log_2{\frac{|D_v|}{|D|}}}
Gain_Ratio(D,a)=IV(a)Gain(D,a)IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
其中,IV(a)IV(a)IV(a)可以看作是特征aaa的某种属性值,是一个固定的数。
Algorithm
输入训练集DDD、特征集AAA、阈值ϵ\epsilonϵ,输出决策树TTT,ID3算法的大体流程如下:
- 如果当前DDD中所有样本都属于同一类别,那么TTT为单结点树,并以这个类别作为该节点的类别,返回TTT。
- 如果A=ϕA=\phiA=ϕ,则TTT为单节点树,返回DDD中样本数最多的类别CCC作为该节点的类别,返回TTT。
- 否则,计算AAA中所有特征对样本集DDD的信息增益率,选取信息增益最大的特征AgA_gAg。
- 如果AgA_gAg对DDD的信息增益率小于阈值ϵ\epsilonϵ,那么TTT为单节点树,返回DDD中样本数最多的类别CCC作为该节点的类别,返回TTT。
- 否则,对于AgA_gAg每一种可能的取值aia_iai,按照Ag=aiA_g=a_iAg=ai将DDD划分为若干非空集合DiD_iDi,将DiD_iDi中样本数最多的类别作为当前节点的类别,构建子节点,由该结点和其子结点构成树TTT,返回TTT。
- 对于第5步中得到的每个子结点iii,以DiD_iDi为训练集,A−{Ag}A-\{A_g\}A−{Ag}为特征集,递归地调用第1~5步,得到子树TiT_iTi,返回TiT_iTi。
CART
CART是Classification and Regression Tree的缩写,这个名字直接点明了CART可以做分类和回归任务,也就是说CART可以处理离散和连续数据(其实上面两个决策树算法也可以处理连续数据,采用的是二分法)。CART决策树是一棵严格的二叉树,对于每个结点,CART会根据GiniGiniGini指数来选取最优的划分特征以及该最优特征下最优的划分值。因此,每个结点的取值只有“是”或“否”(对于数字来说也可以是大于或小于),这也就是CART树是一棵二叉树的原因。
Classification
Gini Index
先来介绍一下基尼指数,基尼指数也是度量样本集纯度的一种指标,设数据集DDD中共有KKK种类别的数据,每种类别占比为pkp_kpk,则数据集DDD的计算公式为:
Gini(D) = 1−∑k=1Kpk2
Gini(D) \ = \ 1 - \sum_{k=1}^Kp^2_k
Gini(D) = 1−k=1∑Kpk2
同样的,Gini指数越小,数据集的纯度越高。选择当前特征为AAA,按照AAA的某个值aaa将DDD划分为两个子集D1D_1D1和D2D_2D2,那么当前划分的基尼指数就是:
Gini_index(D,a)=∣D1∣∣D∣Gini(D1) + ∣D2∣∣D∣Gini(D2)
Gini\_index(D,a)={\frac{|D_1|}{|D|}}Gini(D_1) \ + \ {\frac{|D_2|}{|D|}}Gini(D_2)
Gini_index(D,a)=∣D∣∣D1∣Gini(D1) + ∣D∣∣D2∣Gini(D2)
这次,我们选择能使得Gini指数最小的特征和特征值最为最优划分特征和最优划分值。
Algorithm
构建CART决策树的算法过程如下:
- 设当前节点的数据集为DDD,计算现有特征对DDD的Gini指数。具体来说,对于每一个特征AAA,根据AAA的每一种取值aaa将DDD划分为两个子集D1D_1D1和D2D_2D2,计算在给定特征AAA和特征取值aaa的Gini指数。
- 在所有可能的特征AAA和特征AAA取值aaa中,选取能够使得Gini指数最小的特征和特征值作为当前的最优划分特征和最优划分特征值。依据最优划分特征和最优划分特征值构建两个子结点,将数据集分配到两个子结点中,具体来说,满足A=a或A≥aA=a或A\ge aA=a或A≥a的样本进入左子结点,不满足的进入右子结点。
- 递归调用上述步骤,直至达到递归终止条件,如样本集数量已经小于阈值等
- 生成CART决策树
Regression
Min Square Error
之前提到CART可以用来做回归,下面来简单介绍一下。之前在分类任务当中,我们选取结点、划分数据的依据是基尼指数,基尼指数和信息熵一样,都是用来衡量一个集合的不纯度的。但在回归任务中,我们不需要衡量数据集的不纯度(很显然回归任务中的不纯度是非常大的,而且基本不会变),我们只需要衡量回归的误差。那么回归问题最经典常用的误差函数就是MSE,因此,将Gini Index替换为MSE用于特征、特征值选取,并用均值替换多数类别标记,我们就得到了一棵CART回归树。
具体来讲,每次得到两个子集合时,计算 minj,s[minc1∑xi∈R1(j,s)(yi − c1)2 + minc2∑xi∈R2(j,s)(yi − c2)2]其中,j表示特征,s表示特征划分值,R1、R2是划分之后的两个子集合,c1、c2是两个子集合数据的均值
具体来讲,每次得到两个子集合时,计算 \ \ \ min_{j,s}[min_{c_1}\sum_{x_i\in{R_1(j,s)}}(y_i \ - \ c_1)^2 \ + \ min_{c_2}\sum_{x_i\in{R_2(j,s)}}(y_i \ - \ c_2)^2]\\
其中,j表示特征,s表示特征划分值,R_1、R_2是划分之后的两个子集合,c_1、c_2是两个子集合数据的均值
具体来讲,每次得到两个子集合时,计算 minj,s[minc1xi∈R1(j,s)∑(yi − c1)2 + minc2xi∈R2(j,s)∑(yi − c2)2]其中,j表示特征,s表示特征划分值,R1、R2是划分之后的两个子集合,c1、c2是两个子集合数据的均值
Algorithm

Pruning
其实介绍完三种决策树以后,我们不难发现决策树其实是一个比较容易过拟合的模型,因为随着树的深度变大,结点数变多,模型的泛化能力是会随之减弱的。因此,我们可以对决策树进行剪枝操作来降低模型的复杂度以达到抑制模型过拟合的效果。剪枝的方法有两种:预剪枝和后剪枝
Pre-Pruning
预剪枝的主要思想就是在选定特征进行划分之前,先使用测试集进行正确率的测试,以判断是否有必要按照当前这个结点进行展开。简言之,只要按照当前属性进行划分能够提高模型的准确率,那就划分;否则,就把当前结点标记为叶结点,并以样本数最多的类别作为该叶结点的类别标记。

Post Pruning
后剪枝相对于预剪枝来说复杂了很多。后剪枝是在决策树构建完成后,再自下而上地对所有非叶结点进行剪枝,最终得到一个子树序列{T0,T1,…,Tn}\{T_0, T_1, \dots, T_n\}{T0,T1,…,Tn},然后采取交叉验证的方法选出序列中最优的子树作为我们最终的模型。下面,我们介绍几个量
- TtT_tTt表示以结点ttt为根节点的子树
- ∣Tt∣|T_t|∣Tt∣表示子树TtT_tTt中的结点数量(可以认为是子树TtT_tTt的复杂程度)
- C(T)C(T)C(T)表示子树TTT对其所包含的训练数据的预测误差,如信息熵、基尼指数
- C(t)C(t)C(t)表示把ttt当作单结点树对其所包含的训练数据的预测误差,如信息熵、基尼指数(是3的特例情况)
于是,我们定义Cα(T)C_{\alpha}(T)Cα(T)表示子树TTT的损失函数,那么
Cα(Tt)=C(Tt)+α∣Tt∣
C_{\alpha}(T_t) = C(T_t) + \alpha|T_t|
Cα(Tt)=C(Tt)+α∣Tt∣
考虑我们剪枝的操作,其实就是把一棵子树变成了一棵单结点的树,所以剪枝以后,我们的损失函数就变为了
Cα(t)=C(t)+α
C_{\alpha}(t) = C(t)+\alpha
Cα(t)=C(t)+α
我们肯定希望的是损失函数能够减小,但同时又不希望树模型的复杂度升高,因此,取折中的办法就是当
Cα(Tt)=Cα(t),即α = C(t) − C(Tt)∣Tt∣ − 1
C_{\alpha}(T_t) = C_{\alpha}(t),即 \\\alpha \ = \ \frac{C(t) \ - \ C(T_t)}{|T_t| \ - \ 1}
Cα(Tt)=Cα(t),即α = ∣Tt∣ − 1C(t) − C(Tt)
我们就进行剪枝。于是,对于初始的决策树T0T_0T0,我们找到能够使得α\alphaα最小的结点进行剪枝得到子树T1T_1T1,然后递归此过程得到T2,T3…TnT_2, T_3 \dots T_nT2,T3…Tn。

Multi Variable Decision Tree
上述介绍的决策树模型都是单变量的决策树,什么叫单变量?其实就是在每个结点处,我们只考虑了一种特征的取值,因此如果将分类过程可视化,我们的决策边界都是平行于坐标轴的,如图所示:

也正是因为我们每次只能画平行线,导致模型的复杂度会比较大,影响了泛化能力。显然,如果我们能够使用斜线,以上图为例,我们可以用两条斜线就实现四条平行线的任务。如果我们把每个特征看作是一个变量xxx,那么单变量相当于是每次用常数函数,多变量相当于是一个所有变量的线性组合,如下图所示:

因此,多变量决策树就是把每个结点从只考虑单一特征变为考虑多个特征。
斜线,以上图为例,我们可以用两条斜线就实现四条平行线的任务。如果我们把每个特征看作是一个变量xxx,那么单变量相当于是每次用常数函数,多变量相当于是一个所有变量的线性组合。
因此,多变量决策树就是把每个结点从只考虑单一特征变为考虑多个特征。
1470



被折叠的 条评论
为什么被折叠?



