天天看点

决策树算法总结(下:CART决策树)一、CART树原理二、CART分类树三、CART回归树四、CART树算法的剪枝五、决策树总结

文章目录

  • 一、CART树原理
  • 二、CART分类树
    • 2.1 特征选择
    • 2.2 建立流程
    • 2.3 连续特征和离散特征的处理
  • 三、CART回归树
  • 四、CART树算法的剪枝
    • 4.1 剪枝的损失函数度量
    • 4.2 剪枝的思路
    • 4.3 CART树的交叉验证
    • 4.4 CART树的剪枝算法
  • 五、决策树总结

上一篇文章中,讲解了ID3决策树及C4.5决策树,但是特们仍有许多不足:比如模型是用较为复杂的熵来度量,使用了相对较为复杂的多叉树,只能处理分类不能处理回归等。对于这些问题, CART算法大部分做了改进。由于CART算法可以做回归,也可以做分类,我们分别加以介绍,先从CART分类树算法开始,重点比较和C4.5算法的不同点。接着介绍CART回归树算法,重点介绍和CART分类树的不同点。然后我们讨论CART树的建树算法和剪枝算法,最后总结决策树算法的优缺点。

一、CART树原理

CART 全称为 Classification And Regression Trees,即分类回归树。顾名思义,该算法既可以用于分类还可以用于回归。

克服了 ID3 算法只能处理离散型数据的缺点,CART 可以使用二元切分来处理连续型变量。二元切分法,即每次把数据集切分成两份,具体地处理方法是:如果特征值大于给定值就走左子树,否则就走右子树。对 CART 稍作修改就可以处理回归问题。先前我们使用香农熵来度量集合的无组织程度,如果选用其它方法来代替香农熵,就可以使用树构建算法来完成回归。

与ID3决策树及C4.5决策树一样,CART是决策树的一种,主要由特征选择,树的生成和剪枝三部分组成。它主要用来处理分类和回归问题,下面对分别对其进行介绍。

本部分将构建两种树,第一种是分类树;第二种是回归树。

二、CART分类树

2.1 特征选择

CART分类树使用基尼指数最小化准则来选择最佳属性。

ID3算法使用了信息增益来选择特征,信息增益大的优先选择。C4.5算法采用了信息增益比来选择特征,以减少信息增益容易选择特征值多的特征的问题。但是无论是ID3还是C4.5,都是基于信息论的熵模型的,这里面会涉及大量的对数运算。因此,我们希望有一种方法简化模型同时又不至于完全丢失熵模型的优点,这就是基尼系数。CART分类树算法使用基尼系数来代替信息增益比,基尼系数代表了模型的不纯度,基尼系数越小,则不纯度越低,特征越好。这和信息增益(比)是相反的。

在分类问题中,假设有K个类别,第k个类别的概率为 p k p_k pk​, 则基尼系数的表达式为:

G i n i ( p ) = ∑ k = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(p)=∑k=\sum_{k=1}^{K}p_k(1−p_k)=1-\sum_{k=1}^{K}p^2_k Gini(p)=∑k=k=1∑K​pk​(1−pk​)=1−k=1∑K​pk2​

如果是二类分类问题,计算就更加简单了,如果属于第一个样本输出的概率是p,则基尼系数的表达式为:

G i n i ( p ) = 2 p ( 1 − p ) Gini(p)=2p(1−p) Gini(p)=2p(1−p)

对于个给定的样本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-\sum_{k=1}^{K}(\frac{|C_k|}{|D|})^2 Gini(D)=1−k=1∑K​(∣D∣∣Ck​∣​)2

特别的,对于样本D,如果根据特征A的某个值a,把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{|D_1|}{|D|}Gini(D_1)+\frac{|D_2|}{|D|}Gini(D_2) Gini(D,A)=∣D∣∣D1​∣​Gini(D1​)+∣D∣∣D2​∣​Gini(D2​)

其中:

  • Gini(D):表示集合D的不确定性。
  • Gini(A,D):表示经过A=a分割后的集合D的不确定性。

对比基尼系数表达式和熵模型的表达式,二次运算要比对数简单很多,尤其是二类分类的计算,更加简单。但是简单归简单,和熵模型的度量方式比,基尼系数对应的误差有多大呢?对于二类分类,基尼系数和熵之半的曲线如下:

决策树算法总结(下:CART决策树)一、CART树原理二、CART分类树三、CART回归树四、CART树算法的剪枝五、决策树总结

 从上图可以看出,基尼系数和熵之半的曲线非常接近,仅仅在45度角附近误差稍大。因此,基尼系数可以做为熵模型的一个近似替代。而CART分类树算法就是使用的基尼系数来选择决策树的特征。同时,为了进一步简化,CART分类树算法每次仅仅对某个特征的值进行二分,而不是多分,这样CART分类树算法建立起来的是二叉树,而不是多叉树。这样一可以进一步简化基尼系数的计算,二可以建立一个更加优雅的二叉树模型。

2.2 建立流程

算法从根节点开始,用训练集递归的建立CART树。

  • 1)对于当前节点的数据集为D,如果样本个数小于阈值或者没有特征,则返回决策子树,当前节点停止递归。
  • 2)计算样本集D的基尼系数,如果基尼系数小于阈值,则返回决策树子树,当前节点停止递归。
  • 3)计算当前节点现有的各个特征的各个特征值对数据集D的基尼系数。
  • 4)在计算出来的各个特征的各个特征值对数据集D的基尼系数中,选择基尼系数最小的特征A和对应的特征值a。根据这个最优特征和最优特征值,把数据集划分成两部分D1和D2,同时建立当前节点的左右节点,做节点的数据集D为D1,右节点的数据集D为D2.
  • 5)对左右的子节点递归的调用1-4步,生成决策树。

对于生成的决策树做预测的时候,假如测试集里的样本A落到了某个叶子节点,而节点里有多个训练样本。则对于A的类别预测采用的是这个叶子节点里概率最大的类别。

2.3 连续特征和离散特征的处理

1)、连续特征的处理

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

具体的思路如下,比如m个样本的连续特征A有m个,从小到大排列为 a 1 , a 2 , . . . , a m a_1,a_2,...,a_m a1​,a2​,...,am​,则CART算法取相邻两样本值的平均数,一共取得m-1个划分点,其中第i个划分点 T i T_i Ti​表示为: T i = a i + a ( i + 1 ) 2 Ti=\frac{a_i+a_{(i+1)}}{2} Ti=2ai​+a(i+1)​​。对于这m-1个点,分别计算以该点作为二元分类点时的基尼系数。选择基尼系数最小的点作为该连续特征的二元离散分类点。比如取到的基尼系数最小的点为 a t a_t at​,则小于 a t a_t at​的值为类别1,大于 a t a_t at​的值为类别2,这样我们就做到了连续特征的离散化。要注意的是,与ID3或者C4.5处理离散属性不同的是,如果当前节点为连续属性,则该属性后面还可以参与子节点的产生选择过程。

2)、离散特征处理

对于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回归树

CART回归树使用平方误差最小准则。

训练回归树其实和训练分类树没有本质不同,也是自上而下,不断分裂节点的过程。不同之处在于对节点分裂的分裂准则和分裂值的选择方法上。我下面将一步步推导回归树的构建算法。

设有训练数据集 D = { ( X 1 , y 1 ) , ( X 2 , y 2 ) , … , ( X n , y n ) } D=\{(X_1,y_1),(X_2,y_2),…,(X_n,y_n)\} D={(X1​,y1​),(X2​,y2​),…,(Xn​,yn​)}。我们知道决策树最终将数据元组划分到了多个叶子节点中,比如分类树的每个叶子就有一个类标号,作为元组的预测类。回归树的思路类似,我将数据空间划分成了mm个区域 { R 1 , R 2 , … , R m } \{R_1,R_2,…,R_m\} {R1​,R2​,…,Rm​},实际上就是将训练元组的分区。然后赋给每个区域有一个固定的代表值 C i C_i Ci​(类似于分类树中的类标号),这样,回归树的模型可以表示成r如下公式的形式:

f ( X ) = ∑ i = 1 m C i I ( X ∈ R i ) f(X)=\sum_{i=1}^{m}C_iI(X \in R_i) f(X)=i=1∑m​Ci​I(X∈Ri​)

其中 I ( X ∈ R i ) = 1 I(X∈R_i)=1 I(X∈Ri​)=1,如果 X ∈ R i X∈R_i X∈Ri​;否则, I ( X ∈ R i ) = 0 I(X∈R_i)=0 I(X∈Ri​)=0。这么看来,上式的含义是:先判断X属于哪个区域,然后返回这个区域的代表值。

这样,我们可以写出对于某个区域Ri回归模型的损失函数:

J ( C ) = ∑ X j ∈ R i ( f ( X j ) − g i ) 2 J(C)=\sum_{X_j \in R_i}(f(X_j)-g_i)^2 J(C)=Xj​∈Ri​∑​(f(Xj​)−gi​)2

其中, g i g_i gi​为这个区域的代表值(这里用 g i g_i gi​而不用 C i C_i Ci​的原因是我要表达 g i g_i gi​是分裂中间的某个区域的代表值,而 C i C_i Ci​为最终完成分裂之后的叶子节点的代表值), g i g_i gi​的计算方法一般是这个区域中的元组的y值的均值(取均值时,损失函数达到最优)。

g i = 1 N i ∑ X j ∈ R i y i g_i=\frac{1}{N_i}\sum_{X_j \in R_i}y_i gi​=Ni​1​Xj​∈Ri​∑​yi​

其中, N i N_i Ni​为这个区域内数据元组的总数。初始时,所有的数据元组都在一个区域内,我们按照 J ( C ) J(C) J(C)计算损失函数,如果计算得到的误差值太大,不能满足要求,则寻找最佳的分裂准则(属性)和分裂值将数据集一分为二。这里的关键在于怎样的分裂准则和分裂值对于回归树来说是最佳的。其实很明显,“最佳”指我按照这样的属性和属性值将数据集一分为二后,使得分裂得到的两个子区域的误差和最小。

综上所述,回归树的计算步骤如下:

  • 1)初始时,将所有训练元组放置于根节点中,计算损失函数得到误差值,倘若误差大于事先定好的参数,那么执行下面的2~4步;
  • 2)选择用于分裂区域的属性A和对应的属性值s,将当前节点的数据元组划分到以下两个区域 R 1 R_1 R1​, R 2 R_2 R2​中。:

    R 1 = { X ∣ x i ≤ s } ; R 1 = { X ∣ x i > s } R_1=\{X|x_i\leq s\};R_1=\{X|x_i>s\} R1​={X∣xi​≤s};R1​={X∣xi​>s}

其中 x i x_i xi​为元组 X X X中属性 A A A的值。而选择分裂属性 A A A以及属性值 s s s的依据是使得分裂后的子区域误差值的和最小。即:

m i n ∑ X j ∈ R 1 ( f ( X j ) − y 1 ) 2 + ∑ X j ∈ R 2 ( f ( X j ) − y 2 ) 2 min\sum_{X_j \in R_1}(f(X_j)-y_1)^2+\sum_{X_j \in R_2}(f(X_j)-y_2)^2 minXj​∈R1​∑​(f(Xj​)−y1​)2+Xj​∈R2​∑​(f(Xj​)−y2​)2

这一步具体执行的时候,我们遍历所有的属性以及每个属性的所有可能的划分值,分别计算他们划分数据元组之后的两个子区域的代表值 y 1 , y 2 y_1,y_2 y1​,y2​,这样就可以计算 R 1 , R 2 R_1,R_2 R1​,R2​的误差和上式,最终选择误差和最小的属性 A A A和属性值 s s s,作为分裂依据。

四、CART树算法的剪枝

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

由于决策时算法很容易对训练集过拟合,而导致泛化能力差,为了解决这个问题,我们需要对CART树进行剪枝,即类似于线性回归的正则化,来增加决策树的泛化能力。但是,有很多的剪枝方法,我们应该这么选择呢?CART采用的办法是后剪枝法,即先生成决策树,然后产生所有可能的剪枝后的CART树,然后使用交叉验证来检验各种剪枝的效果,选择泛化能力最好的剪枝策略。

也就是说,CART树的剪枝算法可以概括为两步,第一步是从原始决策树生成各种剪枝效果的决策树,第二步是用交叉验证来检验剪枝后的预测能力,选择泛化预测能力最好的剪枝后的数作为最终的CART树。

4.1 剪枝的损失函数度量

首先我们看看剪枝的损失函数度量,在剪枝的过程中,对于任意的一刻子树T,其损失函数为:

C α ( T t ) = C ( T t ) + α ∣ T t ∣ C_{\alpha}(T_t)=C(T_t)+\alpha|T_t| Cα​(Tt​)=C(Tt​)+α∣Tt​∣

其中, α α α为正则化参数,这和线性回归的正则化一样。 C ( T t ) C(T_t) C(Tt​)为训练数据的预测误差,分类树是用基尼系数度量,回归树是均方差度量。 ∣ T t ∣ |T_t| ∣Tt​∣是子树T的叶子节点的数量。

当 α = 0 α=0 α=0时,即没有正则化,原始的生成的CART树即为最优子树。当 α = ∞ α=∞ α=∞时,即正则化强度达到最大,此时由原始的生成的CART树的根节点组成的单节点树为最优子树。当然,这是两种极端情况。一般来说, α α α越大,则剪枝剪的越厉害,生成的最优子树相比原生决策树就越偏小。对于固定的 α α α,一定存在使损失函数 C α ( T ) C_α(T) Cα​(T)最小的唯一子树。

4.2 剪枝的思路

对于位于节点t的任意一颗子树Tt,如果没有剪枝,它的损失是:

C α ( T t ) = C ( T t ) + α ∣ T t ∣ 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)+α

当 α = 0 α=0 α=0或者 α α α很小时, C α ( T t ) &lt; C α ( T ) C_α(T_t)&lt;C_α(T) Cα​(Tt​)<Cα​(T) , 当 α α α增大到一定的程度时:

C α ( T t ) = C α ( T ) C_{\alpha}(T_t)=C_{\alpha}(T) Cα​(Tt​)=Cα​(T)

当α继续增大时不等式反向,也就是说,如果满足下式:

α = C ( T ) − C ( T t ) ∣ T t ∣ − 1 \alpha=\frac{C(T)-C(T_t)}{|T_t|-1} α=∣Tt​∣−1C(T)−C(Tt​)​

T t T_t Tt​ 和 T T T有相同的损失函数,但是 T T T节点更少,因此可以对子树 T t T_t Tt​进行剪枝,也就是将它的子节点全部剪掉,变为一个叶子节点T。

4.3 CART树的交叉验证

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

4.4 CART树的剪枝算法

  • 输入:CART树建立算法得到的原始决策树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{∣Tt​∣−1C(T)−C(Tt​)​,αmin​},更新 α m i n = α α_{min}=α αmin​=α;
  • 3)得到所有节点的 α α α值的集合 M M M;
  • 4)从M中选择最大的值 α k α_k αk​,自上而下的访问子树 t t t的内部节点,如果 C ( T ) − C ( T t ) ∣ T t ∣ − 1 \frac{C(T)−C(T_t)}{|T_t|−1} ∣Tt​∣−1C(T)−C(Tt​)​时,进行剪枝。并决定叶节点 t t t的值。如果是分类树,则是概率最高的类别,如果是回归树,则是所有样本输出的均值。这样得到αk对应的最优子树Tk;
  • 5)最优子树集合 ω = ω ∪ T k ω=ω∪T_k ω=ω∪Tk​, M = M − α k M=M−{α_k} M=M−αk​;
  • 6)如果M不为空,则回到步骤4。否则就已经得到了所有的可选最优子树集合ω;
  • 7)采用交叉验证在ω选择最优子树 T α T_α Tα​。

五、决策树总结

决策树优点:

  • 1)简单直观,生成的决策树很直观。
  • 2)基本不需要预处理,不需要提前归一化,处理缺失值。
  • 3)使用决策树预测的代价是O(log2m)。 m为样本数。
  • 4)既可以处理离散值也可以处理连续值。很多算法只是专注于离散值或者连续值。
  • 5)可以处理多维度输出的分类问题。
  • 6)相比于神经网络之类的黑盒分类模型,决策树在逻辑上可以得到很好的解释
  • 7)可以交叉验证的剪枝来选择模型,从而提高泛化能力。
  • 8) 对于异常点的容错能力好,健壮性高。

决策树缺点:

  • 1)决策树算法非常容易过拟合,导致泛化能力不强。可以通过设置节点最少样本数量和限制决策树深度来改进。
  • 2)决策树会因为样本发生一点点的改动,就会导致树结构的剧烈改变。这个可以通过集成学习之类的方法解决。
  • 3)寻找最优的决策树是一个NP难的问题,我们一般是通过启发式方法,容易陷入局部最优。可以通过集成学习之类的方法来改善。
  • 4)有些比较复杂的关系,决策树很难学习,比如异或。这个就没有办法了,一般这种关系可以换神经网络分类方法来解决。
  • 5)如果某些特征的样本比例过大,生成决策树容易偏向于这些特征。这个可以通过调节样本权重来改善。

文章有很多直接复制了决策树算法原理(下)中的总结,因为该文章写的太全了。

继续阅读