决策树算法在机器学习中算是很经典的一个算法系列了。它既可以作为分类算法,也可以作为回归算法,同时也特别适合集成学习比如随机森林。决策树算法主要有:ID3, C4.5和CART,scikit-learn使用了优化版的CART算法作为其决策树算法的实现。
基本流程
一般的,一棵决策树包含一个根节点、若干个内部结点和若干个叶节点;叶节点对应于决策结果,其他每个节点对应于一个属性测试;每个节点包含的样本集合根据属性测试的结果被划分到子节点中;根节点包含样本全集。
决策树算法流程如下:
输入:训练集 D = {(x1,y1), (x2,y2)...(xm,ym)}
属性集 A = {a1, a2...ad}
过程:函数TreeGenerate(D, A)
1:生成节点node
2:if D中样本属于同一类别 C THEN
3: 将node标记为 C 类叶节点 RETURN
4:end if
5: if A = 空集 OR D中样本在A上取值相同
6: 将node标记为叶节点,其类别标记为D中样本数最多的类 RETURN
7:end if
8:从A中选取最优划分属性 a*
9:for a* 的每一个值 a*v do
10: 为node生成一个分支;令Dv 表示 D 中在 a* 上取值为 a*v 的样本子集
11: if Dv 为空 then
12: 将分支节点标记为叶节点,其类别标记为 D 中样本最多的类 RETURN
13: else
14: 以TreeGenerate(Dv, A\{a*})为分支节点
15: end if
16:end for
输出:以node为根节点的一棵决策树
决策时的生成过程是个递归的过程。有三种情况导致递归返回:
- 当前节点包含的样本全属于同一类别,无需划分(行号3)
- 当前属性集为空,或是所有样本在所有属性上取值相同,无法划分(行号6)
- 当前节点包含的样本集合为空,不能划分(行号12)
第2种情形下,把当前节点标记为叶节点,并将类别设定为该节点所含样本最多的类别;在第3种情形下,同样把当前节点标记为叶节点,但类别为其父节点所含样本最多的类别。
划分选择
算法的第8行需要选出最优属性。一般而言,随着划分过程的进行,希望决策树分支节点所包含的样本尽可能属于同一类别,即节点的“纯度”越来越高。
信息增益
“信息熵”是度量样本集合纯度最常用的一种指标。假定当前样本集合D中第k类样本所占的比例为 pk (k=1,2…),则D的信息熵定义为:
E n t ( D ) = − ∑ p k l o g 2 p k Ent(D)=-\sum p_k log_2 p_k Ent(D)=−∑pklog2pk
E n t ( D ) Ent(D) Ent(D)的值越小,则 D 的纯度越高。
假定离散属性a有V个可能的取值{a1, a2 . . .av},D中在属性a上取值为 av的样本,记为Dv,于是可以计算用属性a对样本集D进行划分所获得的“信息增益”:
G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) 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)
信息增益越大,使用属性a进行划分所获得的“纯度提升”越大。用信息增益来进行决策树的划分属性选择,即在第8行选择属性 a ∗ = a r g m a x G a i n ( D , a ) a_* = argmaxGain(D, a) a∗=argmaxGain(D,a),这就是ID3算法。
不足
- ID3没有考虑连续特征,比如长度,密度都是连续值,无法在ID3运用。这大大限制了ID3的用途。
- 在相同条件下,取值比较多的特征比取值少的特征信息增益大
- ID3算法对于缺失值的情况没有做考虑
信息增益率
信息增益准则对取值数目较多的属性有所偏好,C4.5算法选择使用“增益率”来选择最优划分属性。其公式如下:
G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) Gain\_ratio(D, a)=\frac{Gain(D, a)}{IV(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)
其中 I V ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ l o g 2 ∣ D v ∣ ∣ D ∣ IV(a) = - \sum_{v=1}^V \frac{|D^v|}{|D|} log_2 {\frac{|D^v|}{|D|}} IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
称为属性a的“固有值”。属性a的可能取值数目越多,IV(a)的值越大。
增益率准则对可能取值数目较少的属性有所偏好,因此C4.5算法并不是直接选择增益率最大的候选属性,而是使用一个启发式:先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。
不足
- C4.5生成的是多叉树,即一个父节点可以有多个节点。很多时候,在计算机中二叉树模型会比多叉树运算效率高。如果采用二叉树,可以提高效率。
- C4.5只能用于分类,如果能将决策树用于回归的话可以扩大它的使用范围。
基尼指数
CART(Classification and Regression Tree)决策树使用基尼指数来选择划分属性,它既能用于分类问题,也可以用在回归问题上,数据集D 的纯度用基尼值来度量:
G i n i ( D ) = ∑ k ∣ y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ y ∣ p k 2 Gini(D)=\sum_k^{|y|}\sum_{k' \neq k} p_k p_k' = 1 - \sum_{k=1}^{|y|} p_k^2 Gini(D)=k∑∣y∣k′=k∑pkpk′=1−k=1∑∣y∣pk2
p k p_k pk表示第k个类别的概率,直观来说,Gini(D) 反映了从数据集 D 中随机抽取两个样本,其类别标记不一致的概率。因此,Gini(D) 越小,数据集D的纯度越高。
如果是二分类问题,那D的基尼指数是:
G i n i ( D ) = 2 p ( 1 − p ) Gini(D)=2p(1-p) Gini(D)=2p(1−p)
属性a的基尼指数定义为:
G i n i _ i n d e x ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) Gini\_index(D, a)=\sum_{v=1}^V \frac{|D^v|}{|D|} Gini(D^v) Gini_index(D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
基尼指数不同于信息增益和信息增益率这类熵模型,相比熵模型中复杂的对数运算,基尼指数的计算代价更小。对于二类分类,基尼系数和熵之半的曲线如下:
从上图可以看出,基尼系数和熵之半的曲线非常接近,仅仅在45度角附近误差稍大。因此,基尼系数可以做为熵模型的一个近似替代。而CART分类树算法就是使用的基尼系数来选择决策树的特征。同时,为了进一步简化,CART分类树算法每次仅仅对某个特征的值进行二分,而不是多分,这样CART分类树算法建立起来的是二叉树,而不是多叉树。这样一可以进一步简化基尼系数的计算,二可以建立一个更加优雅的二叉树模型。
另外,CART分类树用基尼指数作为最小化准则,CART回归树用平方误差最小化准则。
剪枝处理
剪枝是决策树学习算法解决过拟合问题的主要手段。剪枝的策略有预剪枝和后剪枝。预剪枝是指决策树生成过程中,对每个节点在划分前后进行估计,若当前节点的划分不能带来决策树泛化性能的提升,则停止划分并将当前节点标记为叶节点;后剪枝则是先从训练集生成一棵完整的决策树,然后自底向上对非叶节点进行考察,若将该节点替换为叶节点能带来决策树泛化性能的提升,则将该子树替换为叶节点。
判断决策树泛化性能提升需要用到验证集。预剪枝基于“贪心”本质上禁止这些分支展开,给预剪枝决策树带来了欠拟合的风险。后剪枝通常比预剪枝保留了更多的分支,欠拟合风险更小,泛化性能优于预剪枝决策树。但因此是生成后再剪枝,所以时间开销很大。
决策树的剪枝也可以通过极小化决策树的整体的损失函数或代价函数实现。(这一部分转到下边CART树部分)
连续和缺失值
连续值处理
基于离散属性的决策树好理解,对于连续属性的处理,需要考虑连续属性的离散化技术,最简单的策略是采用二分法对连续属性进行处理。C4.5对连续属性处理时采用了该策略。
与离散属性不同,若当前划分点属于连续属性,该属性还可作为其后代节点的划分属性(在从根节点出来的单个分支上某个离散属性只出现一次)。
缺失值处理
需要解决两个问题:1)如何在属性值缺失的情况下进行划分属性的选择,2)给定划分属性,若样本在该属性上值缺失,如何对样本进行划分。
对于第一个子问题,对于某一个有缺失特征值的特征A。C4.5的思路是将数据分成两部分,对每个样本设置一个权重(初始可以都为1),然后划分数据,一部分是有特征值A的数据D1,另一部分是没有特征A的数据D2. 然后对于没有缺失特征A的数据集D1来和对应的A特征的各个特征值一起计算加权重后的信息增益比,最后乘上一个系数,这个系数是无特征A缺失的样本加权后所占加权总样本的比例。
对于第二个子问题,可以将缺失特征的样本同时划分入所有的子节点,不过将该样本的权重按各个子节点样本的数量比例来分配。比如缺失特征A的样本a之前权重为1,特征A有3个特征值A1,A2,A3。 3个特征值对应的无缺失A特征的样本个数为2,3,4.则a同时划分入A1,A2,A3。对应权重调节为2/9,3/9, 4/9。
多变量决策树
若把每个属性视为一个空间中的轴,分类就是在这个空间中寻找不同样本的分类边界。**决策树所形成的的分类边界有个明显的特点:轴平行,即分类边界由与坐标轴平行的多个线段组成。**这样的边界解释性较好,但在任务很复杂时,决策树也就相当复杂。如果使用斜的划分边界,决策树就会简化。多变量决策树就能实现这种斜划分。在这类决策树中,非叶节点不再是针对某个属性,而是对属性的线性组合进行测试;每个非叶节点时一个形如 ∑ i = 1 d w i a i = t \sum_{i=1}^d w_i a_i = t ∑i=1dwiai=t 的线性分类器,其中wi是属性 ai 的权重,wi 和 t 可在该节点所含的样本集和属性集中学得。
CART
CART不仅用于分类还用于回归。回归树相关内容可以看参考3(我觉得回归树直观上不如分类树好理解,哈哈!),这个部分重点说下CART分数树的剪枝问题,首先明确一点,CART采用的是后剪枝。
首先我们看看剪枝的损失函数度量,在剪枝的过程中,对于任意的一刻子树T,那么损失函数为:
C α ( T t ) = C ( T t ) + α ∣ T t ∣ Cα(Tt)=C(Tt)+α|Tt| Cα(Tt)=C(Tt)+α∣Tt∣
其中, α α α为正则化参数,这和线性回归的正则化一样。 C ( T t ) C(Tt) C(Tt)为训练数据的预测误差,分类树是用基尼系数度量,回归树是均方差度量。 ∣ T t ∣ |Tt| ∣Tt∣是子树T的叶子节点的数量。
当 α = 0 α=0 α=0时,即没有正则化,原始的生成的CART树即为最优子树。当 α = ∞ α=∞ α=∞时,即正则化强度达到最大,此时由原始的生成的CART树的根节点组成的单节点树为最优子树。当然,这是两种极端情况。一般来说, α α α越大,则剪枝剪的越厉害,生成的最优子树相比原生决策树就越偏小。对于固定的 α α α,一定存在使损失函数 C ( T t ) C(Tt) C(Tt)最小的唯一子树。
看过剪枝的损失函数度量后,我们再来看看剪枝的思路,对于位于节点t的任意一颗子树 T t Tt Tt, 如果没有剪枝,它的损失是
C α ( T ) = C ( T ) + α Cα(T)=C(T)+α Cα(T)=C(T)+α
当α=0者α很小时,Cα(Tt)<Cα(T) , 当α增大到一定的程度时
C α ( T t ) = C α ( T ) Cα(Tt)=Cα(T) Cα(Tt)=Cα(T)
当α继续增大时不等式反向,也就是说,如果满足下式:
α = C ( T ) − C ( T t ) ∣ T t ∣ − 1 α=\frac{C(T)−C(Tt)}{|Tt|−1} α=∣Tt∣−1C(T)−C(Tt)
Tt 和 T 有相同的损失函数,但是 T 节点更少,因此可以对子树 Tt 进行剪枝,也就是将它的子节点全部剪掉,变为一个叶子节点T。
最后我们看看CART树的交叉验证策略。上面我们讲到,可以计算出每个子树是否剪枝的阈值α,如果我们把所有的节点是否剪枝的值α都计算出来,然后分别针对不同的α所对应的剪枝后的最优子树做交叉验证。这样就可以选择一个最好的α,有了这个α,我们就可以用对应的最优子树作为最终结果。
对比
算法 | 支持模型 | 树结构 | 特征选择 | 连续值处理 | 缺失值处理 | 剪枝 |
---|---|---|---|---|---|---|
ID3 | 分类 | 多叉树 | 信息增益 | 不支持 | 不支持 | 不支持 |
C4.5 | 分类 | 多叉树 | 信息增益比 | 支持 | 支持 | 支持 |
CART | 分类,回归 | 二叉树 | 基尼系数,均方差 | 支持 | 支持 | 支持 |
PS
有研究表明,不同的划分方法,对决策树的尺寸影响较大,但是对泛化性能影响有限。信息增益和基尼指数也仅在2%的情况下有所不同。但剪枝策略包括剪枝方法和程度对决策树的泛化性能影响显著。
一些决策树算法还能进行“增量学习”,主要通过调整分支路径上的划分属性的次序来对树进行部分重构,代表性的有ID4, ID5R,ITI等。但增量学习在进行多步以后,学习的模型与基于全部数据训练的模型有较大差别。
参考
周志华《机器学习》
https://www.cnblogs.com/pinard/p/6050306.html
https://www.cnblogs.com/pinard/p/6053344.html
https://blog.csdn.net/u012328159/article/details/79413610