决策树(decision tree):ID3、C4.5、CART

决策树(decision tree)

  决策树模型是一个分类与回归方法,属于监督学习模型,是一个概率模型和判别模型。决策树可以理解为后验概率函数P(Y|X),通过特征X求取得类别Y的概率,一般Y的取值是特征向量X给定后的记录中的多数类(极大似然估计),所以说决策树模型是一个概率模型。
  树结构不多说,决策树的基本思想是从训练集归纳出一组if-then分类规则,利用树的内部结点(internal node,包括根节点)进行划分,叶结点(leaf node)为最终分类结果,例如人类的性别划分,我们可以取身高为其中一个内部结点的划分依据,身高大于170cm数据进入右子树,小于等于170cm进入左子树,再取体重为子结点划分依据,最终看数据进入哪个叶结点,叶结点代表的类别就是最终分类结果,所以决策树算法就是if-then规则的集合,该集合互斥并且完备,每一个实例都被一条路径或一条规则所覆盖。

决策树模型

  决策树模型包括特征选择,决策树生成和决策树剪枝,常见的算法有ID3、C4.5、CART回归树、CART分类树。其最关键问题是最优特征的选取方法,ID3利用信息增益最大、C4.5利用信息增益比最大、CART回归树利用平方误差最小、CART分类树利用基尼指数最小,CART回归树和CART分类树还需要额外选择特征的最优值。


特征选择

  特征选择在于选取对分类有帮助的特征,基本方法有信息增益和信息增益比两种方法。首先介绍一下信息论中熵(entropy)的概念,熵描述的是随机变量的不确定性,对于随机变量X,其熵 H ( X ) H(X) H(X)定义如下:

H ( X ) = H ( p ) = ∑ i = 1 n − p i log ⁡ p i H(X)=H(p)=\sum\limits_{i=1}^{n}-p_{i}\log p_{i} H(X)=H(p)=i=1npilogpi

   p i p_{i} pi表示随机变量取不同值时的概率,定义 0 log ⁡ 0 = 0 0\log 0=0 0log0=0,对数函数可以以2为底,此时熵的单位是比特(bit),也可以以自然对数 e e e为底,此时熵的单位是纳特(nat)。同时我们注意到熵的定义和随机变量X的取值无关,仅仅和取值的概率有关,所以熵也可以表示为 H ( p ) H(p) H(p)
  下面引出条件熵的定义,条件熵 H ( Y ∣ X ) H(Y|X) H(YX)表示在随机变量X已知时随机变量Y的不确定性,条件熵 H ( Y ∣ X ) H(Y|X) H(YX)定义如下:

H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) H(Y|X)=\sum\limits_{i=1}^{n}p_{i}H(Y|X=x_{i}) H(YX)=i=1npiH(YX=xi)

p i = p ( X = x i ) p_{i}=p(X=x_{i}) pi=p(X=xi)

  当熵或者条件熵中的概率由概率估计(特别是极大似然估计)得到时,熵和条件熵分别称为经验熵(empirical entropy)和经验条件熵(empirical conditional entropy)。

信息增益

  对于训练集D,A为其中某个特征,信息增益 g ( D , A ) g(D,A) g(D,A)定义为经验熵与经验条件熵的差值,又叫互信息 :
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 = ∑ i = 1 K − ∣ C i ∣ ∣ D ∣ log ⁡ ∣ C i ∣ ∣ D ∣ H(D)=\sum\limits_{i=1}^{n}-p_{i}\log p_{i}=\sum\limits_{i=1}^{K}-\frac{|C_{i}|}{|D|}\log \frac{|C_{i}|}{|D|} H(D)=i=1npilogpi=i=1KDCilogDCi

H ( D ∣ A ) = ∑ i = 1 n p ( X = x i ) ⋅ H ( Y ∣ X = x i ) = ∑ i = 1 m ∣ D i ∣ ∣ D ∣ ∑ j = 1 K − ∣ D i j ∣ ∣ D i ∣ log ⁡ ∣ D i j ∣ ∣ D i ∣ H(D|A)=\sum\limits_{i=1}^{n}p(X=x_{i})·H(Y|X=x_{i})=\sum\limits_{i=1}^{m}\frac{|D_{i}|}{|D|}\sum\limits_{j=1}^{K}-\frac{|D_{ij}|}{|D_{i}|}\log \frac{|D_{ij}|}{|D_{i}|} H(DA)=i=1np(X=xi)H(YX=xi)=i=1mDDij=1KDiDijlogDiDij

  熵和条件熵中的概率估计均是通过极大似然估计得到的(频率等于概率其依据就是极大似然估计,我在证明朴素贝叶斯分类器学习过程时,附带证明了这一点), ∣ D ∣ |D| D表示总的记录条数, ∣ C i ∣ , i = 1 , 2 … K |C_{i}|,i=1,2 \dots K Ci,i=1,2K表示训练集中每个类的记录条数, ∣ D i ∣ , i = 1 , 2 … m |D_{i}|,i=1,2\dots m Di,i=1,2m表示训练集D中特征A取不同值时的记录条数, ∣ D i j ∣ , i = 1 , 2 … m , j = 1 , 2 … K |D_{ij}|,i=1,2\dots m,j=1,2\dots K Dij,i=1,2m,j=1,2K表示训练集在特征A取不同值的记录中,分属不同类的记录条数, D i j = D i ∩ C j D_{ij}=D_{i} \cap C_{j} Dij=DiCj

信息增益比

  信息增益存在偏向于选择取值较多的特征的问题。原因引用blog:https://www.cnblogs.com/muzixi/p/6566803.html

当特征的取值较多时,根据此特征划分更容易得到纯度更高的子集,因此划分之后的熵更低,由于划分前的熵是一定的,因此信息增益更大,因此信息增益比较偏向取值较多的特征。

  因此提出一种校正方法,即信息增益比。
g R ( D , A ) = g ( D , A ) H A ( D ) g_{R}(D,A)=\frac{g(D,A)}{H_{A}(D)} gR(D,A)=HA(D)g(D,A)

H A ( D ) = ∑ i = 1 m − ∣ D i ∣ ∣ D ∣ log ⁡ ∣ D i ∣ ∣ D ∣ H_{A}(D)=\sum\limits_{i=1}^{m}-\frac{|D_{i}|}{|D|}\log \frac{|D_{i}|}{|D|} HA(D)=i=1mDDilogDDi

  m是特征A取值的个数。相当于给信息增益乘上一个惩罚参数。特征个数较多时,惩罚参数较小;特征个数较少时,惩罚参数较大。


ID3决策树生成算法

  ID3是一个常见的决策树生成算法。其基本思路就是自根节点开始,对当前剩余的特征比较信息增益,选择信息增益最大的字段分割当前结点(决策数的生成过程也是训练集数据随结点的生成被切分到子结点的过程,因此对每个结点的数据都可以计算熵H(D)),直到所有字段全部用完或者信息增益小于阈值或者当前结点的所有数据都是同一个类别的数据,此时的结点记为叶节点,叶节点中剩余数据的多数类记为叶节点的最终分类。

算法流程

输入:训练数据集D,特征集合A,阈值 ξ \xi ξ
输出:生成的决策树T
执行流程:

  1. 对当前结点(在第一次递归过程中就是根结点)中的数据D,若数据均属于同一个类 c k c_{k} ck,则该结点为叶结点,叶结点的分类为 c k c_{k} ck
  2. 对当前结点,若待选特征集合 A = ∅ A=\varnothing A=,则该结点为叶结点,叶结点的分类为当前结点中剩余数据的多数类。
  3. 对当前结点,对待选特征集合A中的特征,分别计算其信息增益,其中具有最大的信息增益的特征记为 A g A_{g} Ag
  4. A g A_{g} Ag的信息增益小于阈值 ξ \xi ξ,则该结点为叶结点,叶结点的分类为当前结点中剩余数据的多数类。否则,按特征 A g A_{g} Ag的取值分割该结点,得到该结点的若干子结点,相应的该结点中的数据也按特征 A g A_{g} Ag的取值,被分到了各个子结点中。
  5. 对各个子结点,考虑特征集合A- { A g } \{A_{g}\} {Ag},递归地执行步骤1-5,直到所有叶结点均有分类结果为止。

C4.5决策树生成算法

  C4.5是一个对ID3算法改进后的决策树生成算法,改进地方只有一个,就是把特征选择的信息增益方法变成信息增益比方法,其它一样,其算法流程就是把上面的ID3算法流程中的"信息增益"替换成"信息增益比"。


决策树剪枝

   由ID3或者C4.5决策树生成算法得到的决策树往往对训练集过拟合,泛化能力较差,解决方法就是进行决策树剪枝,基本思路就是决策树不生成的那么深,到叶结点的父结点或者更靠近根结点的结点就停下,其依据是结构风险最小化原则。结构风险函数定义如下:
R s t m ( T ) = ∑ i = 1 ∣ T ∣ N t H t ( p ) + α ∣ T ∣ (1) R_{stm}(T)=\sum \limits_{i=1}^{|T|}N_{t}H_{t}(p)+\alpha |T| \tag{1} Rstm(T)=i=1TNtHt(p)+αT(1)

  其中t表示决策树T中的某个叶结点, t = 1 , 2 … ∣ T ∣ t=1,2 \dots |T| t=1,2T ∣ T ∣ |T| T表示决策树中叶结点的个数,也表示决策树T的复杂程度, α ∣ T ∣ \alpha |T| αT就是正则化项, α \alpha α是正则化系数, N t N_{t} Nt表示叶结点t中包含的训练集数据的条数, H t ( p ) H_{t}(p) Ht(p)为叶结点t的经验熵,其定义式如下:
H t ( p ) = ∑ k = 1 K − N t k N t log ⁡ N t k N t H_{t}(p)=\sum\limits_{k=1}^{K}-\frac{N_{tk}}{N_{t}} \log \frac{N_{tk}}{N_{t}} Ht(p)=k=1KNtNtklogNtNtk
  其中 N t k N_{tk} Ntk表示叶结点t中类别是 c k c_{k} ck的数据条数, k = 1 , 2 … K k=1,2 \dots K k=1,2K

算法流程

输入:决策树生成算法得到的决策树T,正则化系数 α \alpha α
输出:经过剪枝的决策树T。
执行流程:

  1. 对所有的叶结点,计算其经验熵 H t ( p ) H_{t}(p) Ht(p),从叶结点开始,递归的向上剪枝;
  2. 对当前结点,设剪枝到其父节点前后的结构风险分别为 R s t m ( T B ) R_{stm}(T_{B}) Rstm(TB) R s t m ( T A ) R_{stm}(T_{A}) Rstm(TA)。若 R s t m ( T B ) ≥ R s t m ( T A ) R_{stm}(T_{B}) \geq R_{stm}(T_{A}) Rstm(TB)Rstm(TA),保留该剪枝,即将父节点变为叶结点,否则,不进行该剪枝操作。
  3. 沿决策树T向上递归执行步骤2,到不能继续为止。

  决策树剪枝过程的计算过程可以只在局部进行,所以可以使用动态规划算法,关于动态规划,这里暂不说明。


CART

  ID3决策树和C4.5决策树有一些缺点,例如模型是用较为复杂的熵来度量(需要对数运算),使用了相对较为复杂的多叉树,只能处理分类不能处理回归等,对这些问题,CART(classification and regression tree,分类与回归树)算法做了大部分改进。CART决策树分为CART回归树和CART分类树,和之前提到的ID3和C4.5模型不同的是,CART决策树模型只能是二叉树,我们在选取分割特征的同时,也要确定该分割特征的最适分割值是多少(ID3和C4.5在选取特征后,该特征的所有取值都会用在决策树的某个结点的分割中,这也是多叉树形成的原因),存在同一个特征由于分割值的不同而多次出现在决策树中的可能。

CART回归树生成

  CART回归树的基本思路是分割输入空间到若干单元 R m , m = 1 , 2 … M R_{m},m=1,2\dots M Rm,m=1,2M,每个单元有固定的输出值 c m c_{m} cm,只要输入落在 R m R_{m} Rm中,就输出 c m c_{m} cm。所以CART回归树有两个重要步骤,如何划分输入空间以及如何找到每个单元的合适输出值,CART回归树通过计算平方误差,来执行这两步骤。
  先说一下,当划分单元 R m R_{m} Rm确定,如何确定一个单元的合适输出值 c m c_{m} cm,最直观的方法就是平方误差最小,即:
a r g min ⁡ c m ∑ x i ∈ R m ( y i − c m ) 2 arg\min\limits_{c_{m}}\sum\limits_{x_{i}\in R_{m}}(y_{i}-c_{m})^{2} argcmminxiRm(yicm)2

  其实不难看出, c m = ∑ x i ∈ R m y i ∣ N m ∣ c_{m}=\frac{\sum\limits_{x_{i}\in R_{m}}y_{i}}{|N_{m}|} cm=NmxiRmyi,其中 ∣ N m ∣ |N_{m}| Nm表示训练集数据落在 R m R_{m} Rm中的记录条数。

  其次说一下如何找到合适的分割单元 R m R_{m} Rm。我们要分割输入空间,需要知道用于分割的特征 x ( j ) , j = 1 , 2 … J , J x^{(j)},j=1,2 \dots J,J x(j),j=1,2J,J为输入训练集数据总的特征数,以及在该特征上的切分点s,把按(j,s)切分后的数据集分别记为 R 1 = { ( x i , y i ) ∣ x i ( j ) ≤ s } R_{1}=\{(x_{i},y_{i})|x_{i}^{(j)} \leq s\} R1={(xi,yi)xi(j)s}以及 R 2 = { ( x i , y i ) ∣ x i ( j ) > s } R_{2}=\{(x_{i},y_{i})|x_{i}^{(j)} > s\} R2={(xi,yi)xi(j)>s},这里采用一种启发式的方法去找到j和s:
min ⁡ j , s ( min ⁡ c 1 ∑ x 1 ∈ R 1 ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x 1 ∈ R 2 ( y i − c 2 ) 2 ) \min\limits_{j,s}(\min\limits_{c_{1}}\sum\limits_{x_{1}\in R_{1}}(y_{i}-c_{1})^{2}+\min\limits_{c_{2}}\sum\limits_{x_{1}\in R_{2}}(y_{i}-c_{2})^{2}) j,smin(c1minx1R1(yic1)2+c2minx1R2(yic2)2)

  第一重循环遍历j,第二重循环遍历s,找到在这两重循环中 ( min ⁡ c 1 ∑ x 1 ∈ R 1 ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x 1 ∈ R 2 ( y i − c 2 ) 2 ) (\min\limits_{c_{1}}\sum\limits_{x_{1}\in R_{1}}(y_{i}-c_{1})^{2}+\min\limits_{c_{2}}\sum\limits_{x_{1}\in R_{2}}(y_{i}-c_{2})^{2}) (c1minx1R1(yic1)2+c2minx1R2(yic2)2)最小的一对(j,s),同求 c m c_{m} cm类似的是, min ⁡ c 1 ∑ x 1 ∈ R 1 ( y i − c 1 ) 2 \min\limits_{c_{1}}\sum\limits_{x_{1}\in R_{1}}(y_{i}-c_{1})^{2} c1minx1R1(yic1)2中的 c 1 c_{1} c1也可按照求平均的方法求,不同的是这里要得不是 c 1 c_{1} c1,而是最小平方误差,求 c 2 c_{2} c2类似。这样我们就有了分割输入空间的方法,只需递归调用该方法,就能不断地对输入空间进行分割。

算法流程

输入:训练集D,停止条件;
输出:CART回归树;
执行流程:

  1. 找到最优的切分特征 x ( j ) , j = 1 , 2 … J x^{(j)},j=1,2 \dots J x(j),j=1,2J以及切分点s;
  2. 按(j,s)分割数据集D到两个子集合 R 1 R_{1} R1以及 R 2 R_{2} R2
  3. R 1 R_{1} R1以及 R 2 R_{2} R2对应的输出值 c 1 = ∑ x i ∈ R 1 y i ∣ N 1 ∣ c_{1}=\frac{\sum\limits_{x_{i}\in R_{1}}y_{i}}{|N_{1}|} c1=N1xiR1yi c 2 = ∑ x i ∈ R 2 y i ∣ N 2 ∣ c_{2}=\frac{\sum\limits_{x_{i}\in R_{2}}y_{i}}{|N_{2}|} c2=N2xiR2yi
  4. 递归对 R 1 R_{1} R1以及 R 2 R_{2} R2执行步骤1,2,3,直到达到停止条件;
  5. 返回决策树 f ( x ) = ∑ m = 1 M c m I ( x i ∈ R m ) f(x)=\sum\limits_{m=1}^{M}c_{m}I(x_{i}\in R_{m}) f(x)=m=1McmI(xiRm) I ( ⋅ ) I(·) I()为指示函数。

CART分类树生成

  分类的类别个数有无穷多个,就是回归问题,所以CART分类树与CART回归树本质都是对特征空间的分割。这里介绍CART分类树的生成,同样CART分类树也要考虑如何选择特征,以及特征的最适分割值,CART分类树使用基尼指数完成这一重要操作。
  分类问题中,样本点x有K种分类可能,对应的取值概率为 p k , k = 1 , 2 … K p_{k},k=1,2\dots K pk,k=1,2K,则基尼指数定义如下:
G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(p)=\sum\limits_{k=1}^{K}p_{k}(1-p{_k})=1-\sum\limits_{k=1}^{K}p_{k}^{2} Gini(p)=k=1Kpk(1pk)=1k=1Kpk2

  可见基尼指数的定义只和 p k p_{k} pk有关,这一点和熵的定义很像,后面会看到基尼指数在很多方面都和熵很像,其意义和熵也一样,表示随机变量的不确定性。对于二分类问题, p ( k = 1 ) = p p(k=1)=p p(k=1)=p,基尼指数定义如下:
G i n i ( p ) = p ( 1 − p ) + ( 1 − p ) p = 2 p ( 1 − p ) Gini(p)=p(1-p)+(1-p)p=2p(1-p) Gini(p)=p(1p)+(1p)p=2p(1p)

  利用极大似然估计来得到 p k p_{k} pk,我们得到数据集D的基尼指数定义如下:
G i n i ( D ) = 1 − ∑ k = 1 K p k 2 = 1 − ∑ k = 1 K ( ∣ D k ∣ ∣ D ∣ ) 2 Gini(D)=1-\sum\limits_{k=1}^{K}p_{k}^{2}=1-\sum\limits_{k=1}^{K}(\frac{|D_{k}|}{|D|})^{2} Gini(D)=1k=1Kpk2=1k=1K(DDk)2

  其中, ∣ D ∣ |D| D表示训练集总的训练条数, ∣ D k ∣ |D_{k}| Dk表示训练集中分类为k的数据的条数。类似条件熵的定义,我们定义在某一特征A给定情况下的基尼指数如下:
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)=DD1Gini(D1)+DD2Gini(D2)

  和熵不同的是,我们对特征A的选择是非此即彼形式的,若 D 1 = { x i ∣ x i ( A ) = A 1 } D_{1}=\{x_{i}|x_{i}^{(A)}=A_{1}\} D1={xixi(A)=A1},那么 D 2 = { x i ∣ x i ( A ) ≠ A 1 } D_{2}=\{x_{i}|x_{i}^{(A)} \neq A_{1}\} D2={xixi(A)=A1},不管特征A的可能取值有多少个,这一点保证了CART分类树一定是二叉树。 G i n i ( D , A ) Gini(D,A) Gini(D,A)表示特征A取定某一值时,数据集D的分类不确定性, G i n i ( D , A ) Gini(D,A) Gini(D,A)越小,表示A给定该值对数据集D的限定越大,D的不确定性越低,所以用 G i n i ( D , A ) Gini(D,A) Gini(D,A)完全就可以选择出最合适的特征(这点其实和熵是一样的,别看信息增益是 H ( D ) − H ( D ∣ A ) H(D)-H(D|A) H(D)H(DA),但对所有特征, H ( D ) H(D) H(D)其实一样,所以信息增益最大,等价于条件熵 H ( D ∣ A ) H(D|A) H(DA)最小)以及最合适的该特征取值,此时A就是最适特征和其最适取值。

  具体就是,一重循环遍历特征j,二重循环遍历每个特征的可能取值s,找到 G i n i ( D , x ( j ) = s ) Gini(D,x^{(j)}=s) Gini(D,x(j)=s)取最小的一对(j,s),即是当前最优的分割,递归调用该方法,就能不断延伸CART分类树。

算法流程

输入:训练集D,停止条件。
输出:CART分类树
执行流程:

  1. 遍历特征j和每个特征的所有取值,找到基尼指数最小的一对(j,s);
  2. 利用(j,s)分割现有数据集,得到 D 1 D_{1} D1 D 2 D_{2} D2,同时意味着CART决策树一结点延伸到两个子结点;
  3. D 1 D_{1} D1 D 2 D_{2} D2递归调用步骤1,2,直到满足停止条件。

  对于CART分类树,停止条件一般是结点中样本个数小于阈值,或样本集基尼指数小于阈值,或没有更多的特征和特征的取值。

CART决策树剪枝

  在李航老师的《统计学习方法》这一章节中,我一直觉得李航老师没有交代清楚"子树"这个概念,如下图所示树结构

  我们一般把从某一结点断开后,该结点包括该结点的子子孙孙形成的树叫做子树,例如上图中,断开AB连接,BEFG四个结点就构成了一个子树;但在《统计学习方法》中,把断开AB连接后,剩余的ACDHIJ六个结点构成的剩余树也叫子树,这就引起一种阅读上的歧义。为了消除这种歧义,我把剩余的树数据结构叫做剩余树

  CART决策树剪枝的基本思路就是递归地裁剪生成算法得到的"完全生成"决策树 T 0 T_{0} T0,得到剩余树集合 { T 0 , T 1 … T n } \{T_{0},T_{1} \dots T_{n}\} {T0,T1Tn},利用验证集交叉验证得到最优的剩余树 T α T_{\alpha} Tα

  我们利用结构风险最小原则进行剪枝,根据(1)式,整个树的结构风险是其子树的结构风险的和,例如根节点有左右子树,整个树的结构风险就是左右子树结构风险之和,所以某一子树被剪枝成一个结点后,如果该子树的结构风险降低,而剩余树的结构风险不变,那么整个树的结构风险也会降低,因此我们单独考虑待剪掉的目标子树,在剪枝前后的结构风险变化就可以了,即子树结构风险降低,整个树的结构风险也会降低。我们对子树 T T T,定义如下的结构风险函数:
C α ( T ) = C ( T ) + α ∣ T ∣ C_{\alpha}(T)=C(T)+\alpha |T| Cα(T)=C(T)+αT

  其中, ∣ T ∣ |T| T表示子树的叶结点个数,也指子树的复杂程度, α \alpha α为正则化系数, α ∣ T ∣ \alpha |T| αT就是正则化项, C ( T ) C(T) C(T)表示子树 T T T对训练数据的预测误差,若是CART回归树,就是子树T的叶结点的最小平法误差和,若是CART分类树,就是子树T的基尼指数(这里的疑问是,子树T的基尼指数是否为T的叶结点的基尼指数 G i n i ( D i ) Gini(D_{i}) Gini(Di)之和,个人觉得参考前面的C4.5剪枝过程,这里应该是这样的)。这样我们对树 T 0 T_{0} T0中某一内部结点t,定义其子树 T t T_{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

  若对t进行剪枝,t子树的叶结点中的数据就会回到结点t(树生成过程的逆),则剪枝后的子树的结构风险为:
C α ( t ) = C ( t ) + α C_{\alpha}(t)=C(t)+\alpha Cα(t)=C(t)+α

  其中, C ( t ) C(t) C(t)表示对内部结点t剪枝后,结点t聚集数据的预测误差,若是分类问题,结点t的类别为结点t聚集数据中的多数类,求其基尼指数;若是回归问题,求结点t聚集数据的最小平方和误差。
  和C4.5决策树剪枝算法相比较,CART的剪枝结构风险函数考虑子树,C4.5考虑整个决策树。
  不难看出, C ( T t ) < C ( t ) C(T_{t})<C(t) C(Tt)<C(t)(树越复杂,对训练数据的拟合越高),而 α ∣ T t ∣ > α \alpha |T_{t}|>\alpha αTt>α,所以随着 α \alpha α从零开始增大到 + ∞ +\infty +,存在一个 α 1 ∗ \alpha_{1}^{*} α1使得 C α ( T t ) = C α ( t ) C_{\alpha}(T_{t})=C_{\alpha}(t) Cα(Tt)=Cα(t),当 α < α 1 ∗ \alpha<\alpha_{1}^{*} α<α1 C α ( T t ) < C α ( t ) C_{\alpha}(T_{t})<C_{\alpha}(t) Cα(Tt)<Cα(t),当 α > α 1 ∗ \alpha>\alpha_{1}^{*} α>α1 C α ( T t ) > C α ( t ) C_{\alpha}(T_{t})>C_{\alpha}(t) Cα(Tt)>Cα(t),而
α 1 ∗ = C α ( t ) − C α ( T t ) ∣ T t ∣ − 1 (1) \alpha_{1}^{*}=\frac{C_{\alpha}(t)-C_{\alpha}(T_{t})}{|T_{t}|-1} \tag{1} α1=Tt1Cα(t)Cα(Tt)(1)

  对每一个内部结点,都有 C ( t ) C(t) C(t) C α ( t ) C_{\alpha}(t) Cα(t),所以每一个内部结点都可以计算一个 α 1 ∗ \alpha_{1}^{*} α1,这些个 α 1 ∗ \alpha_{1}^{*} α1会有一个大小顺序,当给定的正则化因子 α ≥ α 1 ∗ \alpha\geq \alpha_{1}^{*} αα1,对对应结点的剪枝操作是成功的,因为 C α ( T t ) ≥ C α ( t ) C_{\alpha}(T_{t})\geq C_{\alpha}(t) Cα(Tt)Cα(t),剪枝后,子树结构风险降低(或不变,若不变,树整体结构变简单了,也是可取的),整个树的结构风险也会降低。

  若是按照《统计学习方法》书的步骤,取最小的 α 1 ∗ \alpha_{1}^{*} α1为最终的 α 1 \alpha_{1} α1,按 α = α 1 \alpha=\alpha_{1} α=α1剪枝后的剩余树称作 T 1 T_{1} T1(最小的 α 1 ∗ \alpha_{1}^{*} α1意味着只有一个内部结点可以被剪枝,且Breiman等人证明,该结点是当前树中远离根结点的内部结点),对剩余树继续递归执行上面操作,就得到了剩余树集合 { T 0 , T 1 … T n } \{T_{0},T_{1} \dots T_{n}\} {T0,T1Tn},用验证集交叉验证,取平方误差或基尼系数最小的剩余树为最优剩余树 T α T_{\alpha} Tα

  若是按照刘建平老师的blog,我们会计算所有内部结点的 α ∗ \alpha^{*} α,构成集合A,从大到小取出A中的值 α k \alpha_{k} αk按照 α k \alpha_{k} αk T 0 T_{0} T0进行剪枝,得到剩余树集合,用验证集交叉验证得到最优剩余树 T α T_{\alpha} Tα。比较《统计学习方法》和刘建平老师的方法,《统计学习方法》中每次迭代的剪枝对象是上一次迭代结束的剩余树,在每次迭代过程中都会计算剩余树中的内部结点的 α ∗ \alpha^{*} α值,每次迭代选取最小,迭代过程是从下到上 (书上这么写的,但我觉得应该还是计算的整个树的,具体要看Breiman的证明具体是在证明什么);刘建平老师blog中,每次迭代的剪枝对象是 T 0 T_{0} T0,所以只需计算一次 T 0 T_{0} T0中的内部结点的 α ∗ \alpha^{*} α即可,每次迭代选取最大,迭代过程是从上到下。
  下面的算法流程按照刘建平老师的blog编写(个人觉得刘建平老师的方法更容易理解)。

算法流程

输入:"完全生成"的CART决策树。
输出:最优决策树。
执行流程:

  1. 对当前剩余树(第一次迭代,就是"完全生成"的CART决策树),计算其所有内部结点的 C ( t ) C(t) C(t) C α ( t ) C_{\alpha}(t) Cα(t),同时计算 α ∗ = C α ( t ) − C α ( T t ) ∣ T t ∣ − 1 \alpha^{*}=\frac{C_{\alpha}(t)-C_{\alpha}(T_{t})}{|T_{t}|-1} α=Tt1Cα(t)Cα(Tt),构成集合 A A A
  2. 令剩余树集合 T = { T 0 } T=\{T_{0}\} T={T0}
  3. 取集合A中最大的 α ∗ \alpha^{*} α,令 α k = α ∗ \alpha_{k}=\alpha^{*} αk=α,并自上而下地对 T 0 T_{0} T0进行剪枝,即当 α k ≥ C α ( t ) − C α ( T t ) ∣ T t ∣ − 1 \alpha_{k} \geq \frac{C_{\alpha}(t)-C_{\alpha}(T_{t})}{|T_{t}|-1} αkTt1Cα(t)Cα(Tt),对 T 0 T_{0} T0的内部结点t进行剪枝,得到剩余树 T k T_{k} Tk
  4. T = T ∪ { T k } T=T \cup \{T_{k}\} T=T{Tk}
  5. A = A − { α } A=A-\{\alpha\} A=A{α}
  6. A ≠ ∅ A \neq \varnothing A=,递归执行3-5;
  7. 用交叉验证方法,找到剩余树集合T中,结构风险最小的 T k T_{k} Tk,记为 T α T_{\alpha} Tα,返回 T α T_{\alpha} Tα

参考书籍:
《统计学习方法》
决策树算法原理(下) 刘建平

  • 9
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
决策树是一种常见的机器学习算法,其中ID3C4.5和CART是三种常见的决策树分类算法。下面是它们的Python代码介绍: 1. ID3算法代码: ``` def ID3(data, labels): # 计算数据集的信息熵 entropy = calcEntropy(data) # 如果数据集的信息熵为0,则直接返回该数据集的类别 if entropy == 0: return data[0][-1] # 如果特征集为空,则返回数据集中出现次数最多的类别 if len(labels) == 0: return majorityClass(data) # 选择最优划分特征 bestFeature = chooseBestFeature(data, labels) # 根据最优特征生成决策树 decisionTree = {bestFeature: {}} # 从特征集中删除已经使用的特征 labels.remove(bestFeature) # 获取最优特征的所有取值 featureValues = set([example[bestFeature] for example in data]) # 遍历最优特征的所有取值,生成子树 for value in featureValues: subLabels = labels[:] decisionTree[bestFeature][value] = ID3(splitData(data, bestFeature, value), subLabels) return decisionTree ``` 2. C4.5算法代码: ``` def C45(data, labels): # 计算数据集的信息熵 entropy = calcEntropy(data) # 如果数据集的信息熵为0,则直接返回该数据集的类别 if entropy == 0: return data[0][-1] # 如果特征集为空,则返回数据集中出现次数最多的类别 if len(labels) == 0: return majorityClass(data) # 选择最优划分特征 bestFeature = chooseBestFeature(data, labels) # 根据最优特征生成决策树 decisionTree = {bestFeature: {}} # 从特征集中删除已经使用的特征 labels.remove(bestFeature) # 获取最优特征的所有取值 featureValues = set([example[bestFeature] for example in data]) # 遍历最优特征的所有取值,生成子树 for value in featureValues: subLabels = labels[:] # 计算每个取值的信息增益率 subData = splitData(data, bestFeature, value) ratio = calcRatio(subData, entropy) # 如果信息增益率高于平均水平,则生成子树 if ratio >= averageRatio(data, bestFeature): decisionTree[bestFeature][value] = C45(subData, subLabels) # 否则返回数据集中出现次数最多的类别 else: decisionTree[bestFeature][value] = majorityClass(subData) return decisionTree ``` 3. CART算法代码: ``` def CART(data, labels): # 如果数据集中只有一个类别,则直接返回该类别 if len(set([example[-1] for example in data])) == 1: return data[0][-1] # 如果特征集为空,则返回数据集中出现次数最多的类别 if len(labels) == 0: return majorityClass(data) # 选择最优划分特征 bestFeature, bestValue, bestScore = chooseBestSplit(data) # 根据最优特征生成决策树 decisionTree = {bestFeature: {}} # 从特征集中删除已经使用的特征 labels.remove(bestFeature) # 生成左子树和右子树 leftData = [example for example in data if example[bestFeature] <= bestValue] rightData = [example for example in data if example[bestFeature] > bestValue] decisionTree[bestFeature]['left'] = CART(leftData, labels) decisionTree[bestFeature]['right'] = CART(rightData, labels) return decisionTree ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值