决策树系列算法详解与经验总结

转载请注明出处:https://blog.csdn.net/tyhj_sf/article/details/78987358

0 引言

决策树算法在机器学习中是一类比较经典的算法。针对分类和回归问题都有相应的决策树算法可用。对预测结果具备很好的可解释性,在工业界的应用较受欢迎。本文试图从数学建模的角度对ID3、C4.5、CART算法原理进行详细的分析,涵盖如下问题:

  1. 这三个决策树算法的目标函数各是怎样的?
  2. 决策树构建过程有何差异?
  3. 这三个决策树算法适用于解决什么样的问题?
  4. 这三个算法的各有什么优缺点?

如果你对上述问题没有清晰的认识,那么这篇文章对你是有价值的。

1 问题建模

假设给定训练数据集:
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } D = \{(x_1,y_1),(x_2,y_2),...,(x_m,y_m)\} D={(x1,y1),(x2,y2),...,(xm,ym)}
其中, x i = ( x i ( 1 ) , ( x i ( 2 ) , . . . , ( x i ( n ) ) T x_i=(x^{(1)}_i,(x^{(2)}_i,...,(x^{(n)}_i)^T xi=(xi(1),(xi(2),...,(xi(n))T为输入实例的特征向量,n为特征个数,特征集为 A = { a 1 , a 2 , … , a n } A=\left\{a_{1}, a_{2}, \dots, a_{n}\right\} A={a1,a2,,an} y i ∈ { 1 , 2 , . . . , K } y_i \in \{1,2,...,K\} yi{1,2,...,K}为标记值, i = 1 , 2 , . . . , m i=1,2,...,m i=1,2,...,m, m为样本容量。

学习的目标是根据给定的训练数据集构建一个决策树模型,是它能够对实例的标记值进行正确的预测。
如果标记值 y y y是离散值,那么这是分类问题;
如果标记值 y y y是连续值,那么这是回归问题。

另外我们已知决策树的基本算法,其伪代码如下:

--------------------------------------------------------------------------------------

输入:训练集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x m , y m ) } D=\left\{\left(\boldsymbol{x}_{1}, y_{1}\right),\left(\boldsymbol{x}_{2}, y_{2}\right), \ldots,\left(\boldsymbol{x}_{m}, y_{m}\right)\right\} D={(x1,y1),(x2,y2),,(xm,ym)};
        特征集 A = { a 1 , a 2 , … , a n } A=\left\{a_{1}, a_{2}, \dots, a_{n}\right\} A={a1,a2,,an}.
过程:函数TreeGenerate(D, A)
1: 生成结点node;
2: if D 中样本全属于同一类别C then
3:     将node 标记为C 类叶结点 return
4: end if
5: if A = ∅ A=\varnothing A= OR D 中样本在A上取值相同 then
6:     将node 标记为叶结点,其类别标记为D 中样本数最多的类; return
7: end if
8: 从A 中选择最优划分特征 a ∗ a_* a;
9: for特征 a ∗ a_* a的每一个值 a ∗ v a^v_* av do
10:     为node生成一个分支;令 D v D_v Dv 表示D 中在 a ∗ a_* a取值为 a ∗ v a^v_* av 的样本子集;
11:     if D v D_v Dv 为空 then
12:         将分支结点标记为叶结点,其类别标记为D 中样本最多的类; return
13:     else
14:         以TreeGenerate( D v D_v Dv, A \ { a ∗ a_* a} )为分支结点
15:     end if
16: end for
输出: 以node为根结点的一棵决策树

--------------------------------------------------------------------------------------

值得注意的是:
以上伪代码中第8步“从A中选择最优划分特征值 a ∗ a_* a”,这个最优特征选择方法可以有很多种,以下要介绍的ID3、C4.5等算法其差别基本都是对最优特征选择方法设计和改进。

2 ID3算法

2.1 概念及公式的理解

ID3算法(其中的ID是Iterative Dichotomiser的简称,即二分器)是基本决策树算法的一个实现,它是怎么解决上面的问题的呢?
首先按数学建模的方法对上述问题进行建模,问题的目标是对给定的数据集的每个实例能够正确预测其标记值。如果从决策树根节点到分支节点的每个节点上划分的实例的标记越来越单一,直至结点没有特征可以选择为止时,其划分到的实例完全为某个单一标记类型,那么这颗决策树就能完全正确地预测每个实例。
ID3算法使用信息熵来表示每个节点上划分的实例的标记纯度高低。关于信息熵的概念,不了解的同学可以参见本人另一博客:交叉熵、相对熵(KL散度)的数学原理及在机器学习中应用

决策树算法伪代码的一个关键一步: “从特征集 A A A 中选择最优划分特征 a ∗ a_* a”这个最优划分特征的选择标准并没有给出清晰的定义。结合问题的目标,我们自然想到用信息熵的大小衡量所选特征的优劣。当我们选择某个特征时,如果这个特征相比其他特征使训练数据集D的信息熵增加量最大,这就是最优划分特征。ID3使用信息增益来表示信息熵增加量, 用信息增益大小来判断当前节点应该用什么特征来构建决策树,用计算出的信息增益最大的特征来建立决策树的当前节点。
信息增益定义:数据集 C D , i C_{D,i} CD,i为分类i的数据在数据集D中的个数,特征a对训练数据集D的信息增益 g ( D , a ) g(D,a) g(D,a),定义为集合D的经验熵 H ( D ) H(D) H(D)与特征a给定条件下D的经验条件熵 H ( D ∣ a ) H(D|a) H(Da)之差,即
g ( D , a ) = H ( D ) − H ( D ∣ a ) g(D, a)=H(D)-H(D | a) g(D,a)=H(D)H(Da)
其中,
经验熵 H ( D ) = − ∑ i = 1 n p i log ⁡ p i H(D)=-\sum_{i=1}^{n} p_{i} \log p_{i} H(D)=i=1npilogpi,
经验条件熵 H ( D ∣ a ) = ∑ i = 1 n p i H ( D ∣ a = a i ) H(D |a)=\sum_{i=1}^{n} p_{i} H\left(D | a=a_{i}\right) H(Da)=i=1npiH(Da=ai)
概率 p i = ∣ C D , i ∣ ∣ D ∣ p_i=\frac{|C_{D,i}|}{|D|} pi=DCD,i.

如何理解上么这个定义呢?

这里我们举一个信息增益计算的具体的例子。比如我们有15个样本D,输出为0或者1。其中有9个输出为1, 6个输出为0。 样本中有个特征a,取值为a1,a2和a3。在取值为a1的样本的输出中,有3个输出为1, 2个输出为0,取值为a2的样本输出中,2个输出为1,3个输出为0, 在取值为a3的样本中,4个输出为1,1个输出为0.

样本D的经验熵为:
H ( D ) = − ( 9 15 log ⁡ 2 9 15 + 6 15 log ⁡ 2 6 15 ) = 0.971 \begin{aligned} H(D) &=-\left(\frac{9}{15} \log _{2} \frac{9}{15}+\frac{6}{15} \log _{2} \frac{6}{15}\right)\\ &=0.971 \end{aligned} H(D)=(159log2159+156log2156)=0.971

样本D在特征下的经验条件熵为:
H ( D ∣ a ) = 5 15 H ( D 1 ) + 5 15 H ( D 2 ) + 5 15 H ( D 3 ) = − 5 15 ( 3 5 log ⁡ 2 3 5 + 2 5 log ⁡ 2 2 5 ) − 5 15 ( 2 5 log ⁡ 2 2 5 + 3 5 log ⁡ 2 3 5 ) − 5 15 ( 4 5 log ⁡ 2 4 5 + 1 5 log ⁡ 2 1 5 ) = 0.888 \begin{aligned} H(D | a) &=\frac{5}{15} H(D 1)+\frac{5}{15} H(D 2)+\frac{5}{15} H(D 3) \\ &=-\frac{5}{15}\left(\frac{3}{5} \log _{2} \frac{3}{5}+\frac{2}{5} \log _{2} \frac{2}{5}\right)-\frac{5}{15}\left(\frac{2}{5} \log _{2} \frac{2}{5}+\frac{3}{5} \log _{2} \frac{3}{5}\right)-\frac{5}{15}\left(\frac{4}{5} \log _{2} \frac{4}{5}+\frac{1}{5} \log _{2} \frac{1}{5}\right)\\ &=0.888 \end{aligned} H(Da)=155H(D1)+155H(D2)+155H(D3)=155(53log253+52log252)155(52log252+53log253)155(54log254+51log251)=0.888
对应的信息增益为: g ( D , a ) = H ( D ) − H ( D ∣ a ) = 0.083 g(D, a)=H(D)-H(D | a)=0.083 g(D,a)=H(D)H(Da)=0.083

2.2 ID3伪代码

在前面决策树基本算法伪代码基础上,我们得到了ID3算法的决策树构造过程,其伪代码如下:

--------------------------------------------------------------------------------------

输入:训练集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x m , y m ) } D=\left\{\left(\boldsymbol{x}_{1}, y_{1}\right),\left(\boldsymbol{x}_{2}, y_{2}\right), \ldots,\left(\boldsymbol{x}_{m}, y_{m}\right)\right\} D={(x1,y1),(x2,y2),,(xm,ym)};
        特征集 A = { a 1 , a 2 , … , a n } A=\left\{a_{1}, a_{2}, \dots, a_{n}\right\} A={a1,a2,,an}.
过程:函数TreeGenerate(D, A)
1: 生成结点node;
2: if D 中样本全属于同一类别C then
3:     将node 标记为C 类叶结点 return
4: end if
5: if A = ∅ A=\varnothing A= OR D 中样本在A上取值相同 then
6:     将node 标记为叶结点,其类别标记为D 中样本数最多的类; return
7: end if
8: 从A 中选择最优划分特征 a ∗ = arg ⁡ m a x A g ( D , A ) = arg ⁡ m a x A { H ( D ) − H ( D ∣ A ) } a_*= \arg max_A g(D, A)=\arg max_A \{ H(D)-H(D | A) \} a=argmaxAg(D,A)=argmaxA{H(D)H(DA)};
9: if a ∗ a_* a的信息增益值 g ( D , A ) g(D,A) g(D,A)小于阈值 ϵ ϵ ϵ then
10:     将node节点标记类别为样本D中实例数最多的类别, return
11: end if
12: for 特征 a ∗ a_* a的每一个值 a ∗ v a^v_* av do
13:     为node生成一个分支;令 D v D_v Dv 表示D 中在 a ∗ a_* a取值为 a ∗ v a^v_* av 的样本子集;
14:     if D v D_v Dv 为空 then
15:         将分支结点标记为叶结点,其类别标记为D 中样本最多的类; return
16:     else
17:         以TreeGenerate( D v D_v Dv, A \ { a ∗ a_* a} )为分支结点
18:     end if
19: end for
输出: 以node为根结点的一棵决策树

--------------------------------------------------------------------------------------

注意:
从伪代码第8-9步可知,ID3算法构造的一棵多叉树。

2.3 ID3算法的缺点

ID3算法虽然提出了新思路,但是还是有很多值得改进的地方。

  1. ID3只能应用于离散特征,比如长度,密度都是连续值,无法在ID3运用。这大大限制了ID3的用途。
  2. ID3采用信息增益大的特征优先建立决策树的节点。很快就被人发现,在相同条件下,取值比较多的特征比取值少的特征信息增益大。比如一个变量有2个值,各为1/2,另一个变量为3个值,各为1/3,其实他们都是完全不确定的变量,但是取3个值的比取2个值的信息增益大。如果校正这个问题呢?
  3. ID3算法对于缺失值的情况没有做考虑 。
  4. 没有考虑过拟合的问题。

ID3 算法的作者Quinlan基于上述不足,对ID3算法做了改进,产生了C4.5算法,也许你会问,为什么不叫ID4,ID5之类的名字呢?那是因为决策树太火爆,他的ID3一出来,别人二次创新,很快就占了ID4, ID5,所以他另辟蹊径,取名C4.0算法,后来的进一步改进有了C4.5算法。下面我们就来聊下C4.5算法

3 C4.5算法

3.1 改进部分

第2.3节我们讲到ID3算法有四个主要的不足,Quinlan在C4.5算法中改进了上述4个问题。

对于第一个问题,不能处理连续特征, C4.5的思路是将连续的特征离散化。比如m个样本的连续特征a有m个,从小到大排列为 a 1 , a 2 , . . . , a m a_1,a_2,...,a_m a1,a2,...,am,则C4.5取相邻两样本值的平均数,一共取得m-1个划分点,其中第i个划分点 T i T_i Ti表示为: T i = a i + a i + 1 2 T_i=\frac{a_i+a_{i+1}}{2} Ti=2ai+ai+1。对于这m-1个点,分别计算以该点作为二元分类点时的信息增益。选择信息增益最大的点作为该连续特征的二元离散分类点。比如取到的增益最大的点为 a t a_t at,则小于 a t a_t at的值为类别1,大于 a t a_t at的值为类别2,这样我们就做到了连续特征的离散化。要注意的是,与离散属性不同的是,如果当前节点为连续属性,则该属性后面还可以参与子节点的产生选择过程。
对于第二个问题,信息增益作为标准容易偏向于取值较多的特征的问题。我们引入一个信息增益比的变量 I R ( X , Y ) I_R(X,Y) IR(X,Y),它是信息增益和特征熵的比值。表达式如下:
I R ( D , a ) = g ( D , a ) H ( D ∣ A = a ) I_R(D,a)=\frac {g(D, a)}{H(D|A=a)} IR(D,a)=H(DA=a)g(D,a)
其中, D为样本特征输出的集合,A为特征变量,a为样本特征,对于特征熵 H ( D ∣ A = a ) H(D|A=a) H(DA=a), 表达式如下:
H ( D ∣ A = a ) = − ∑ i = 1 n ∣ C D , i ∣ ∣ D ∣ l o g ∣ C D , i ∣ ∣ D ∣ H(D|A=a)=−∑_{i=1}^n\frac{|C_{D,i}|}{|D|}log\frac{|C_{D,i}|}{|D|} H(DA=a)=i=1nDCD,ilogDCD,i
其中n为特征a的类别数, C_{D,i}为在D中特征a的第i个取值对应的样本个数。|D|为样本个数。

特征数越多的特征对应的特征熵 H ( D ∣ A = a ) H(D|A=a) H(DA=a)越大,它作为信息增益比 I R ( D , a ) I_R(D,a) IR(D,a)的分母,可以校正信息增益容易偏向于取值较多的特征的问题。

3.2 C4.5的缺点

C4.5虽然改进或者改善了ID3算法的几个主要的问题,当本身仍然存在一些缺点。

  1. 由于决策树算法非常容易过拟合,因此对于生成的决策树必须要进行剪枝。剪枝的算法有非常多,C4.5的剪枝方法有优化的空间。思路主要是两种,一种是预剪枝,即在生成决策树的时候就决定是否剪枝。另一个是后剪枝,即先生成决策树,再通过交叉验证来剪枝。后面在下篇讲CART树的时候我们会专门讲决策树的减枝思路,主要采用的是后剪枝加上交叉验证选择最合适的决策树。
  2. C4.5生成的是多叉树,即一个父节点可以有多个节点。很多时候,在计算机中二叉树模型会比多叉树运算效率高。如果采用二叉树,可以提高效率。
  3. C4.5只能用于分类,如果能将决策树用于回归的话可以扩大它的使用范围。
  4. C4.5由于使用了熵模型,里面有大量的耗时的对数运算,如果是连续值还有大量的排序运算。如果能够加以模型简化可以减少运算强度但又不牺牲太多准确性的话,那就更好了。

这4个问题在CART树里面部分加以了改进。所以目前如果不考虑集成学习话,在普通的决策树算法里,CART算法算是比较优的算法了。scikit-learn的决策树使用的也是CART算法。在下面的章节里我们会重点聊下CART算法的主要改进思路。

4 CART算法

4.1 CART分类树的最优特征选择方法

无论是ID3还是C4.5,都是基于信息论的熵模型的,这里面会涉及大量的对数运算。CART分类树算法使用基尼系数来代替信息增益比,基尼系数代表了模型的不纯度,基尼系数越小,则不纯度越低,特征越好。这和信息增益(比)是相反的。
在分类问题中,假设有 k 个类别,第 k 个类别的概率为 p k p_{k} pk ,则基尼系数的表达式为:
G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(p)=∑_{k=1}^Kp_k(1−p_k)=1−∑_{k=1}^Kp^2_k Gini(p)=k=1Kpk(1pk)=1k=1Kpk2
对于个给定的样本D,假设有K个类别, 第k个类别的数量为 C k C_k Ck,则样本D的基尼系数表达式为:
G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini(D)=1−∑_{k=1}^K(\frac {|C_k|}{|D|})^2 Gini(D)=1k=1K(DCk)2
特别的,对于样本D,如果根据特征a的某个值 a i a_i ai,把D分成D1和D2两部分,则在特征a的条件下,D的基尼系数表达式为:
G i n i ( D , a ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,a)=\frac {|D1|}{|D|}Gini(D1)+\frac {|D2|}{|D|}Gini(D2) Gini(D,a)=DD1Gini(D1)+DD2Gini(D2)
比较下基尼系数表达式和熵模型的表达式,二次运算要比对数简单很多,尤其是二类分类的计算,更加简单。但是简单归简单,和熵模型的度量方式比,基尼系数对应的误差有多大呢?对于二类分类,基尼系数和熵之半的曲线如下:
决策树系列算法详解与经验总结_第1张图片
从上图可以看出,基尼系数和熵之半的曲线非常接近,仅仅在45度角附近误差稍大。因此,基尼系数可以做为熵模型的一个近似替代。

而CART分类树算法就是使用的基尼系数来选择决策树的特征。

同时,为了进一步简化,CART分类树算法每次仅仅对某个特征的值进行二分,而不是多分,这样CART分类树算法建立起来的是二叉树,而不是多叉树。这样一可以进一步简化基尼系数的计算,二可以建立一个更加优雅的二叉树模型。

4.2 CART分类树对特征处理的改进

CART分类树对连续特征的处理,其思想和C4.5是相同的,都是将连续的特征离散化。唯一的区别在于在选择划分点时的度量方式不同,C4.5使用的是信息增益比,则CART分类树使用的是基尼系数。

要注意的是
与ID3或者C4.5处理离散特征不同的是,如果当前节点为连续特征,则该特征后面还可以参与子节点的产生选择过程。

对于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的一棵子树中,离散特征只会参与一次节点的建立。

4.3 CART回归树的构建

CART回归树和CART分类树的建立算法大部分是类似的,所以这里我们只讨论CART回归树和CART分类树的建立算法不同的地方。

首先,我们要明白,什么是回归树,什么是分类树。两者的区别在于样本输出,如果样本输出是离散值,那么这是一颗分类树。如果果样本输出是连续值,那么那么这是一颗回归树。

除了概念的不同,CART回归树和CART分类树的建立和预测的区别主要有下面两点:

1)连续值的处理方法不同;

2)决策树建立后做预测的方式不同。

对于连续值的处理,我们知道CART分类树采用的是用基尼系数的大小来度量特征的各个划分点的优劣情况。这比较适合分类模型,但是对于回归模型,我们使用了常见的方差和的度量方式,CART回归树的度量目标是,对于任意划分特征a,对应的任意划分点s两边划分成的数据集D1和D2,求出使D1和D2各自集合的均方差最小,同时D1和D2的均方差之和最小所对应的特征和特征值划分点。表达式为:
m i n ⎵ a , s [ m i n ⎵ c 1 ∑ x i ∈ D 1 ( a , s ) ( y i − c 1 ) 2 + m i n ⎵ c 2 ∑ x i ∈ D 2 ( a , s ) ( y i − c 2 ) 2 ] \underbrace{min}_{a,s}\Bigg[\underbrace{min}_{c_1}\sum\limits_{x_i \in D_1(a,s)}(y_i - c_1)^2 + \underbrace{min}_{c_2}\sum\limits_{x_i \in D_2(a,s)}(y_i - c_2)^2\Bigg] a,s min[c1 minxiD1(a,s)(yic1)2+c2 minxiD2(a,s)(yic2)2]
其中,c1为D1数据集的样本输出均值,c2为D2数据集的样本输出均值。

对于决策树建立后做预测的方式,上面讲到了CART分类树采用叶子节点里概率最大的类别作为当前节点的预测类别。而回归树输出不是类别,它采用的是用最终叶子的均值或者中位数来预测输出结果。

除了上面提到了以外,CART回归树和CART分类树的建立算法和预测没有什么区别。

4.4 CART的剪枝策略

CART回归树和CART分类树的剪枝策略除了在度量损失的时候一个使用均方差,一个使用基尼系数,算法基本完全一样。

由于决策时算法很容易对训练集过拟合,而导致泛化能力差,为了解决这个问题,我们需要对CART树进行剪枝,即类似于线性回归的正则化,来增加决策树的泛化能力。

但是,有很多的剪枝方法比如预剪枝和后剪枝,我们应该这么选择呢?
CART采用的是后剪枝法,即先生成决策树,然后产生所有可能的剪枝后的CART树,然后使用交叉验证来检验各种剪枝的效果,选择泛化能力最好的剪枝策略。

也就是说,CART树的剪枝算法可以概括为两步:

  1. 从原始决策树生成各种剪枝效果的决策树;
  2. 用交叉验证来检验剪枝后的预测能力,选择泛化预测能力最好的剪枝后的数作为最终的CART树。

首先我们看看剪枝的损失函数度量,在剪枝的过程中,对于任意的一刻子树T,其损失函数为:
C α ( T t ) = C ( T t ) + α ∣ T t ∣ C_α(T_t)=C(T_t)+α|T_t| Cα(Tt)=C(Tt)+αTt
其中,α为正则化参数,这和线性回归的正则化一样。 C ( T t ) C(T_t) C(Tt)为训练数据的预测误差,分类树是用基尼系数度量,回归树是均方差度量。 ∣ T t ∣ |T_t| Tt是子树T的叶子节点的数量。该损失函数的正则化项为L1正则化。

一般来说,α越大,则剪枝剪的越厉害,生成的最优子树相比原生决策树就越偏小。对于固定的α,一定存在使损失函数 C α ( T ) C_α(T) Cα(T)最小的唯一子树。
看过剪枝的损失函数度量后,我们再来看看剪枝的思路,对于位于节点t的任意一颗子树 T t T_t Tt,如果没有剪枝,它的损失是
C α ( T t ) = C ( T t ) + α ∣ T t ∣ C_α(T_t)=C(T_t)+α|T_t| Cα(Tt)=C(Tt)+αTt
如果将其剪掉,仅仅保留根节点,则损失是
C α ( T ) = C ( T ) + α C_α(T)=C(T)+α Cα(T)=C(T)+α
当α=0或者α很小时, C α ( T t ) < C α ( T ) C_α(T_t)<C_α(T) Cα(Tt)<Cα(T) , 当α增大到一定的程度时 C α ( T t ) = C α ( T ) C_α(T_t)=C_α(T) Cα(Tt)=Cα(T)。当α继续增大时不等式反向,也就是说,如果满足下式:
α = C ( T ) − C ( T t ) ∣ T t ∣ − 1 α=\frac {C(T)−C(T_t)}{|T_t|−1} α=Tt1C(T)C(Tt)
T t T_t Tt和T有相同的损失函数,但是T节点更少,因此可以对子树 T t T_t Tt进行剪枝,也就是将它的子节点全部剪掉,变为一个叶子节点T。

最后我们看看CART树的交叉验证策略。上面我们讲到,可以计算出每个子树是否剪枝的阈值α,如果我们把所有的节点是否剪枝的值α都计算出来,然后分别针对不同的α所对应的剪枝后的最优子树做交叉验证。这样就可以选择一个最好的α,有了这个α,我们就可以用对应的最优子树作为最终结果。

现在来看看CART树的剪枝算法。

--------------------------------------------------------------------------------------

输入:CART树建立算法得到的原始决策树T。
输出:最优决策子树 T α T_α Tα
算法过程如下:
1: 初始化 α m i n = ∞ α_{min}=∞ αmin=, 最优子树集合 ω = T ω=T ω=T
2: 从叶子节点开始自下而上计算各内部节点t的训练误差损失函数 C α ( T t ) C_α(T_t) Cα(Tt)(回归树为均方差,分类树为基尼系数), 叶子节点数 ∣ T t ∣ |T_t| Tt,以及正则化阈值 α = m i n { C ( T ) − C ( T t ) ∣ T t ∣ − 1 , α m i n } α=min\{\frac {C(T)−C(T_t)}{|T_t|−1},α_{min}\} α=min{Tt1C(T)C(Tt),αmin}, 更新 α m i n = α α_{min}=α αmin=α
3: 得到所有节点的α值的集合M。
4: 从M中选择最大的值 α k α_k αk,自上而下的访问子树t的内部节点,如果 C ( T ) − C ( T t ) ∣ T t ∣ − 1 ≤ α k \frac {C(T)−C(T_t)}{|T_t|−1}≤α_k Tt1C(T)C(Tt)αk时,进行剪枝。并决定叶节点t的值。如果是分类树,则是概率最高的类别,如果是回归树,则是所有样本输出的均值。这样得到 α k α_k αk对应的最优子树 T k T_k Tk
5: 最优子树集合 ω = ω ∪ T k , M = M − α k ω=ω∪T_k, M=M−{α_k} ω=ωTkM=Mαk
6: 如果M不为空,则回到步骤4。否则就已经得到了所有的可选最优子树集合ω.
7: 采用交叉验证在ω选择最优子树 T α T_α Tα

--------------------------------------------------------------------------------------

4.5 CART算法的缺点

  1. 应该大家有注意到,无论是ID3, C4.5还是CART,在做特征选择的时候都是只选择最优的一个特征来做分类决策,但是大多数,分类决策不应该是由某一个特征决定的,而是应该由一组特征决定的。这样决策得到的决策树更加准确。这个决策树叫做多变量决策树(multi-variate decision tree)。在选择最优特征的时候,多变量决策树不是选择某一个最优特征,而是选择最优的一个特征线性组合来做决策。这个算法的代表是OC1,后面有机会再探讨。
  2. 树结构对样本比较敏感。如果样本发生一点点的改动,就会导致树结构的剧烈改变。这个可以通过集成学习里面的随机森林之类的方法解决。

5 总结

  1. 算法对比
算法 支持类型 树结构 特征选择 连续值处理 缺失值处理 剪枝
ID3 分类 多叉树 信息增益 不支持 不支持 不支持
C4.5 分类 多叉树 信息增益比 支持 支持 支持
CART 分类、回归 二叉树 Gini系数、均方差 支持 支持 支持
  1. CART算法解决了ID3、C4.5存在的诸多缺点,在考虑使用决策树算法时,建议优先选择CART算法。

6 参考资料

[1]. 《统计学习方法》李航,第五章-决策树
[2]. 《机器学习》周志华,第四章-决策树
[3]. http://www.cnblogs.com/pinard/p/6050306.html
[4]. https://zhuanlan.zhihu.com/p/29858685

你可能感兴趣的:(机器学习)