(四)统计学习方法 | 决策树


1. 决策树

1.1 简介与定义

决策树是一种基本的分类和回归方法,本文主要讨论其在分类上的作用。决策树模型呈树形结构,在分类问题中,表示基于特征对实例进行分类的过程。其主要优点是模型的可读性分类速度快。在模型学习时,利用训练数据,根据损失函数最小化的原则建立决策树模型。预测时,对于新的数据,利用决策树模型进行分类。决策树的学习包含三个过程:特征选择决策树的生成决策树的修剪

决策树模型 分类决策模型是一种描述对实例进行分类的树形结构。决策树由结点有向边组成。结点有两种类型:内部结点和叶结点。内部结点表示一个特征或属性,叶结点表示一个类。相应地,用决策树模型分类时,从根结点开始,对实例的某一特征进行测试,根据测试结果,将实例分配到其子结点;这时,每一个子结点对应着该特征的一个取值。如此递归地对实例进行测试并分配,直到到达叶结点。最后将实例分到叶结点对应的类中。

1.2 决策树学习

给定训练集 D = { ( x 1 , y 2 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } D=\{(x_1,y_2),(x_2,y_2),...,(x_N,y_N)\} D={(x1,y2),(x2,y2),...,(xN,yN)}

其中, x i = ( x i ( 1 ) , x i ( 2 ) , . . . , x i ( n ) ) T x_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(n)})^{\rm T} xi=(xi(1),xi(2),...,xi(n))T为输入实例的特征向量, n n n为特征个数, y i ∈ { 1 , 2 , . . . , K } y_i\in\{1,2,...,K\} yi{1,2,...,K}为类标记, i = 1 , 2 , . . . , N i=1,2,...,N i=1,2,...,N N N N为样本容量。决策树学习的目标时根据给定的训练数据集构造一个决策树模型,使它能够对实例进行正确的分类。 其本质是从训练集上归纳出一组分类规则,与训练数据集不相矛盾的决策树模型可能有多个,也可能一个也没有。

1.3 特征选择

特征选择在于选取对训练数据具有分类能力的特征,这样可以提高决策树学习的效率。如果利用一个特征进行分类的结果与随机分类的结果没有很大的区别,则称这个特征是没有分类能力的。经验上扔掉这样的特征对最终决策树学习的影响不大。通常的特征选择的准则是信息增益信息增益比

例题 训练数据如下,由 15 15 15个样本组成的贷款申请训练数据:

ID年龄有工作有自己的房子信贷情况类别
1青年一般
2青年
3青年
4青年一般
5青年一般
6中年一般
7中年
8中年
9中年非常好
10中年非常好
11老年非常好
12老年
13老年
14老年非常好
15老年一般

现在通过所给的训练数据数据学习一个贷款申请的决策树,用以对未来的贷款申请进行分类,即当新的客户提出贷款申请时,根据申请人的特征利用决策树决定是否批准贷款申请。训练数据给出了年龄有工作有自己的房子信贷情况共四个特征,究竟选择哪个特征更好些?直观上,如果一个特征具有更好的分类能力,那么就更应该选择这个特征。而下面介绍的细信息增益就能够很好地表示这一直观的准则。

1.3.1 信息增益

是随机变量不确定性的度量。设 X X X是一个取有限个值的离散随机变量,其概率分布为: P ( X = x i ) = p i ,   i = 1 , 2 , . . . , n P(X=x_i)=p_i,\ i=1,2,...,n P(X=xi)=pi, i=1,2,...,n

则随机变量的熵定义为: H ( X ) = − ∑ i = 1 n p i log ⁡ p i (1) H(X)=-\sum_{i=1}^np_i\log p_i\tag{1} H(X)=i=1npilogpi(1)

由定义可知,熵只依赖于 X X X的分布,而与 X X X的取值无关,所以也可将 X X X的熵记作 H ( p ) H(p) H(p),即: H ( p ) = − ∑ i = 1 n p i log ⁡ p i H(p)=-\sum_{i=1}^np_i\log p_i H(p)=i=1npilogpi

熵越大,随机变量的额不确定性就越大。从熵的定义可知: 0 ≤ H ( p ) ≤ log ⁡ n 0\leq H(p)\leq \log n 0H(p)logn

然后来看条件熵的定义,设有随机变量 ( X , Y ) (X,Y) (X,Y),其联合概率分布为: P ( X = x i , Y = y i ) = p i j ,   i = 1 , 2 , . . . , n ;   j = 1 , 2 , . . . , m P(X=x_i,Y=y_i)=p_{ij},\ i=1,2,...,n;\ j=1,2,...,m P(X=xi,Y=yi)=pij, i=1,2,...,n; j=1,2,...,m

条件熵 H ( Y ∣ X ) H(Y|X) H(YX)表示在已知随机变量 X X X的条件下随机变量 Y Y Y的不确定性。随机变量 X X X给定的条件下随机变量 Y Y Y的条件熵 H ( Y ∣ X ) H(Y|X) H(YX),定义为 X X X给定条件下 Y Y Y的条件概率分布的熵对 X X X的数学期望: H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) ,   p i = P ( X = x i ) ,   i = 1 , 2 , . . . , n (2) H(Y|X)=\sum_{i=1}^np_iH(Y|X=x_i),\ p_i=P(X=x_i),\ i=1,2,...,n\tag{2} H(YX)=i=1npiH(YX=xi), pi=P(X=xi), i=1,2,...,n(2)

当熵和条件熵中的概率由数据估计得到时,所对应的熵与条件熵分别成为经验熵和条件经验熵。 而信息增益表示得知特征 X X X的信息而使 Y Y Y的信息的不确定性减少的程度。

信息增益 特征 A A A对训练数据集 D D D的信息增益 g ( D , A ) g(D,A) g(D,A),定义为集合 D D D的经验熵 H ( D ) H(D) H(D)与特征 A A A给定条件下 D D D的经验条件熵 H ( D ∣ A ) H(D|A) H(DA)之差,即: g ( D , A ) = H ( D ) − H ( D ∣ A ) (3) g(D,A)=H(D)-H(D|A)\tag{3} g(D,A)=H(D)H(DA)(3)

一般地,熵 H ( Y ) H(Y) H(Y)与条件熵 H ( Y ∣ X ) H(Y|X) H(YX)之差称为互信息。决策树学习中的信息增益等价于训练数据集中类与特征的互信息。根据信息增益标准的特征选择方法是:对于训练数据集(或子集) D D D,计算其每个特征的信息增益,并比较它们的大小,选择信息增益最大的特征。

设训练数据集为 D D D ∣ D ∣ |D| D表示其样本容量。设有 K K K个类 C k , k = 1 , 2 , . . . , K C_k,k=1,2,...,K Ck,k=1,2,...,K ∣ C k ∣ |C_k| Ck为属于类 C k C_k Ck的样本个数, ∑ k = 1 K ∣ C k ∣ = ∣ D ∣ \sum \limits_{k=1}^K|C_k|=|D| k=1KCk=D。设特征 A A A n n n个不同的取值 { a 1 , a 2 , . . . , a n } \{a_1,a_2,...,a_n\} {a1,a2,...,an},根据特征 A A A的取值将 D D D划分为 n n n个子集 D 1 , D 2 , . . . , D n D_1,D_2,...,D_n D1,D2,...,Dn ∣ D i ∣ |D_i| Di D i D_i Di的样本个数, ∑ i = 1 n ∣ D i ∣ = ∣ D ∣ \sum \limits_{i=1}^n|D_i|=|D| i=1nDi=D。记子集 D i D_i Di中属于类 C k C_k Ck的样本的集合为 D i k D_{ik} Dik,即 D i k = D i ∩ C k D_{ik}=D_i\cap C_k Dik=DiCk ∣ D i k ∣ |D_{ik}| Dik D i k D_{ik} Dik的样本个数。得到信息增益的算法如下:

信息增益的算法

输入 训练数据集 D D D和特征 A A A

输出 特征 A A A对训练数据集 D D D的信息增益 g ( D , A ) g(D,A) g(D,A)

(1)计算数据集 D D D的经验熵 H ( D ) H(D) H(D) H ( D ) = − ∑ k = 1 K ∣ C k ∣ ∣ D ∣ log ⁡ 2 ∣ C k ∣ ∣ D ∣ (4) H(D)=-\sum_{k=1}^K\frac{|C_k|}{|D|}\log_{2}\frac{|C_k|}{|D|}\tag{4} H(D)=k=1KDCklog2DCk(4)

(2)计算特征 A A A对数据集 D D D的经验条件熵 H ( D ∣ A ) H(D|A) H(DA) H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H ( D i ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ ∑ k = 1 K ∣ D i k ∣ ∣ D i ∣ log ⁡ 2 ∣ D i k ∣ ∣ D i ∣ (5) H(D|A)=\sum_{i=1}^n\frac{|D_i|}{|D|}H(D_i)=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}\log_2\frac{|D_{ik}|}{|D_i|}\tag{5} H(DA)=i=1nDDiH(Di)=i=1nDDik=1KDiDiklog2DiDik(5)

(3)计算信息增益: g ( D , A ) = H ( D ) − H ( D ∣ A ) (6) g(D,A)=H(D)-H(D|A)\tag{6} g(D,A)=H(D)H(DA)(6)

解例题

(1)计算经验熵 H ( D ) H(D) H(D)(数据集共包含是和否两个类): H ( D ) = − 9 15 log ⁡ 2 9 15 − 6 15 log ⁡ 2 6 15 = 0.971 H(D)=-\frac{9}{15}\log_2\frac{9}{15}-\frac{6}{15}\log_2\frac{6}{15}=0.971 H(D)=159log2159156log2156=0.971

(2)分别对特征年龄 A 1 A_1 A1、有工作 A 2 A_2 A2、有自己的房子 A 3 A_3 A3和信贷情况 A 4 A_4 A4计算条件经验熵和信息增益: g ( D , A 1 ) = H ( D ) − [ 5 15 H ( D 1 ) + 5 15 H ( D 2 ) + 5 15 H ( D 3 ) ] = 0.971 − 0.888 = 0.083 g(D,A_1)=H(D)-\left[\frac{5}{15}H(D_1)+\frac{5}{15}H(D_2)+\frac{5}{15}H(D_3)\right]=0.971-0.888=0.083 g(D,A1)=H(D)[155H(D1)+155H(D2)+155H(D3)]=0.9710.888=0.083

其中, D 1 D_1 D1 D 2 D_2 D2 D 3 D_3 D3分别表示年龄取值为青年、中年和老年,下同。
g ( D , A 2 ) = H ( D ) − [ 5 15 H ( D 1 ) + 10 15 H ( D 2 ) ] = 0.971 − 0.647 = 0.324 g(D,A_2)=H(D)-\left[\frac{5}{15}H(D_1)+\frac{10}{15}H(D_2)\right]=0.971-0.647=0.324 g(D,A2)=H(D)[155H(D1)+1510H(D2)]=0.9710.647=0.324

g ( D , A 3 ) = H ( D ) − [ 6 15 H ( D 1 ) + 9 15 H ( D 2 ) ] = 0.971 − 0.551 = 0.420 g(D,A_3)=H(D)-\left[\frac{6}{15}H(D_1)+\frac{9}{15}H(D_2)\right]=0.971-0.551=0.420 g(D,A3)=H(D)[156H(D1)+159H(D2)]=0.9710.551=0.420

g ( D , A 4 ) = H ( D ) − [ 5 15 H ( D 1 ) + 6 15 H ( D 2 ) + 4 15 H ( D 3 ) ] = 0.971 − 0.608 = 0.363 g(D,A_4)=H(D)-\left[\frac{5}{15}H(D_1)+\frac{6}{15}H(D_2)+\frac{4}{15}H(D_3)\right]=0.971-0.608=0.363 g(D,A4)=H(D)[155H(D1)+156H(D2)+154H(D3)]=0.9710.608=0.363

最后,比较各特征的信息增益值。由于特征有自己的房子 A 3 A_3 A3的信息增益最大,所以选择特征 A 3 A_3 A3作为最优特征。

1.3.2 信息增益比

由信息增益的算法可以看到,以信息增益作为划分训练数据集的特征,存在偏向于选择取值较多的特征的问题。使用信息增益比可以对这一问题进行校正,这也是特征选择的又一准则。

信息增益比 特征 A A A对训练数据集 D D D的信息增益比 g R ( D , A ) g_R(D,A) gR(D,A)定义为其信息增益 g ( D , A ) g(D,A) g(D,A)与训练数据集 D D D关于特征 A A A的值的熵 H A ( D ) H_A(D) HA(D)之比: 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 n ∣ D i ∣ ∣ D ∣ log ⁡ 2 ∣ D i ∣ ∣ D ∣ {H_A(D)}=-\sum_{i=1}^n\frac{|D_i|}{|D|}\log_2\frac{|D_i|}{|D|} HA(D)=i=1nDDilog2DDi

其中, n n n是特征 A A A取值的个数。

1.4 决策树的生成

1.4.1 ID3算法

I D 3 {\rm ID3} ID3算法的核心是在决策树各个结点上应用信息增益准则选择特征,递归地构建决策树。具体的过程是:从根结点开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子结点;再对子结点递归地调用以上方法,构建决策树;直到所有特征的信息增益均很小或没有特征可以选择为止。

ID3算法

输入 训练数据集 D D D,特征集 A A A阈值 ε \varepsilon ε

输出 决策树 T T T

(1)若 D D D中所有实例属于同一类 C k C_k Ck,则 T T T为单结点树,并将类 C k C_k Ck作为该结点的类标记,返回 T T T

(2)若 A = ∅ A=\varnothing A=,则 T T T为单结点树,并将 D D D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回 T T T

(3)否则,计算 A A A中各特征对训练数据集 D D D的信息增益,选择信息增益最大的特征 A g A_g Ag

(4)如果 A g A_g Ag的信息增益小于阈值 ε \varepsilon ε,则置 T T T为单结点树,并将 D D D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回 T T T

(5)否则,对 A g A_g Ag的每一可能值 a i a_i ai,依 A g = a i A_g=a_i Ag=ai D D D分割为若干非空子集 D i D_i Di,将 D i D_i Di中实例数最大的类作为标记,构建子结点,由结点及其子结点构成树 T T T,返回 T T T

(6)对第 i i i个子结点,以 D i D_i Di为训练集,以 A − { A g } A-\{A_g\} A{Ag}为特征集,递归地调用步(1)~(5),得到子树 T i T_i Ti,返回 T T T

解例题

根据上面计算结果,特征有自己的房子 A 3 A_3 A3的信息增益值最大,所以选择 A 3 A_3 A3作为根结点特征。该结点将训练数据集 D D D划分为两个子集有自己的房子 D 1 D_1 D1和没有自己的房子 D 2 D_2 D2。由于 D 1 D_1 D1只有同一类样本点,所以它称为一个叶结点,结点的类标记为是。现在我们来处理数据集 D 2 D_2 D2,计算信息增益: g ( D 2 , A 1 ) = H ( D 2 ) − H ( D 2 ∣ A 1 ) = 0.918 − 0.667 = 0.251 g(D_2,A_1)=H(D_2)-H(D_2|A_1)=0.918-0.667=0.251 g(D2,A1)=H(D2)H(D2A1)=0.9180.667=0.251

g ( D 2 , A 2 ) = H ( D 2 ) − H ( D 2 ∣ A 2 ) = 0.918 − 0 = 0.918 g(D_2,A_2)=H(D_2)-H(D_2|A_2)=0.918-0=0.918 g(D2,A2)=H(D2)H(D2A2)=0.9180=0.918

g ( D 2 , A 4 ) = H ( D 2 ) − H ( D 2 ∣ A 4 ) = 0.918 − 0.444 = 0.474 g(D_2,A_4)=H(D_2)-H(D_2|A_4)=0.918-0.444=0.474 g(D2,A4)=H(D2)H(D2A4)=0.9180.444=0.474

选择信息增益值最大对应的特征有工作 A 2 A_2 A2作为结点的特征, A 2 A_2 A2有两个可能的取值,从这一结点引出两个结点:一个对应于有工作,一个对应于没有工作。同时我们发现,对于有工作而言,结果均为是;对于没有工作而言,结果均为否,所以这里得到两个叶结点。最终得到的决策树如下:

在这里插入图片描述

1.4.2 C4.5算法

C 4.5 {\rm C4.5} C4.5算法是对 I D 3 {\rm ID3} ID3算法的改进,使用信息增益比代替信息增益来选择特征,其他步骤同。

1.5 决策树的剪枝

决策树生成算法递归地产生决策树,直到不能继续下去为止。这样产生的树往往对训练数据的分类很准确,但对未知的测试数据的分类却没有那么准确,即出现过拟合效应。出现过拟合的主要原因是基于训练数据集构建的决策树模型过于复杂,所以通常我们需要对决策树剪枝以减弱过拟合效应。而决策树的剪枝往往通过极小化决策树整体的损失函数来实现。设 T T T的叶结点个数为 ∣ T ∣ |T| T t t t是树 T T T的叶结点,该叶结点有 N t N_t Nt个样本点,其中 k k k类的样本点有 N t k N_{tk} Ntk个, k = 1 , 2 , . . . , K k=1,2,...,K k=1,2,...,K H t ( T ) H_t(T) Ht(T)为叶结点 t t t上的经验熵, α ≥ 0 \alpha\geq0 α0为参数,则决策树学习的损失函数可以定义为: C α ( T ) = ∑ t = 1 ∣ T ∣ N t H t ( T ) + α ∣ T ∣ (7) C_{\alpha}(T)=\sum_{t=1}^{|T|}N_tH_t(T)+\alpha|T|\tag{7} Cα(T)=t=1TNtHt(T)+αT(7)

其中经验熵定义为: H t ( T ) = − ∑ k N t k N t log ⁡ N t k N t (8) H_t(T)=-\sum_{k}\frac{N_{tk}}{N_t}\log\frac{N_{tk}}{N_t}\tag{8} Ht(T)=kNtNtklogNtNtk(8)

在损失函数中,将式(7)有段的第一项记作: C ( T ) = ∑ t = 1 ∣ T ∣ N t H t ( T ) = − ∑ t = 1 T ∑ k = 1 K N t k log ⁡ N t k N t (9) C(T)=\sum_{t=1}^{|T|}N_tH_t(T)=-\sum_{t=1}^T\sum_{k=1}^KN_{tk}\log\frac{N_{tk}}{N_t}\tag{9} C(T)=t=1TNtHt(T)=t=1Tk=1KNtklogNtNtk(9)

这时有: C α ( T ) = C ( T ) + α ∣ T ∣ (10) C_{\alpha}(T)=C(T)+\alpha|T|\tag{10} Cα(T)=C(T)+αT(10)

上式中, C ( T ) C(T) C(T)表示模型对训练数据的预测误差,即模型与训练数据的拟合程度, ∣ T ∣ |T| T表示模型复杂度,参数 α ≥ 0 \alpha\geq0 α0控制两者之间的影响。较大的 α \alpha α促使选择较简单的模型,较小的 α \alpha α促使选择较复杂的模型, α = 0 \alpha=0 α=0表示只考虑模型与训练数据的拟合程度,不考虑模型的复杂度。

剪枝,就是当 α \alpha α确定时,选择损失函数最小时的模型,即损失函数最小的子树。当 α \alpha α值确定时,子树越大,往往与训练数据的拟合越好,但是模型的复杂度就越高;相反,子树越小,模型的复杂度就越低,但是往往与训练数据的拟合不好。损失函数正好表示了对两者的平衡。总之,决策树生成学习局部的模型,而决策树剪枝学习整体的模型

树的剪枝算法

输入 生成算法产生的整个树 T T T,参数 α \alpha α

输出 修建后的子树 T α T_{\alpha} Tα

(1)计算每个结点的经验熵;

(2)递归地从树的叶结点向上回缩。

设一组叶结点回缩到其父结点之前之后的整体树分别为 T B T_B TB T A T_A TA,其对应的损失函数值分别是 C α ( T B ) C_{\alpha}(T_B) Cα(TB) C α ( T A ) C_{\alpha}(T_A) Cα(TA),如果满足: C α ( T A ) ≤ C α ( T B ) C_{\alpha}(T_A)\leq C_{\alpha}(T_B) Cα(TA)Cα(TB)

则进行剪枝,即将父结点变为新的叶结点


2. CART算法

分类与回归树CART模型是应用广泛的决策树学习方法,同样由特征选择树的生成剪枝组成,既可以用于分类也可以用于回归。 C A R T {\rm CART} CART是在给定输入变量 X X X条件下输出随机变量 Y Y Y的条件概率分布的学习方法。 C A R T {\rm CART} CART假设决策树是二叉树,左子树表示取值为,右子树表示取值为。这样的决策树等价于递归地二分每个特征,将输入空间即特征空间划分为有限个单元,并在这些单元上确定预测的概率分布,也就是在输入给定的条件下输出的条件概率分布。 C A R T {\rm CART} CART算法由以下两个步骤组成:决策树生成,基于训练数据集生成决策树,生成的决策树要尽量大;决策树剪枝,用验证数据集对已生成的树进行剪枝并选择最优子树,这时用损失函数最小作为剪枝的标准。

2.1 CART生成

2.1.1 回归树的生成

假设 X X X Y Y Y分别为输入和输出变量,并且 Y Y Y是连续变量,给定训练数据集 D = { ( x 1 , y 2 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } D=\{(x_1,y_2),(x_2,y_2),...,(x_N,y_N)\} D={(x1,y2),(x2,y2),...,(xN,yN)}

现假设将输入空间划分为 M M M个单元 R 1 , R 2 , . . . , R M R_1,R_2,...,R_M R1,R2,...,RM,并且在每个单元 R m R_m Rm上又一个固定的输出值 c m c_m cm,于是回归树模型可以表示为: f ( x ) = ∑ m = 1 M c m I ( x ∈ R m ) (11) f(x)=\sum_{m=1}^Mc_mI(x\in R_m)\tag{11} f(x)=m=1McmI(xRm)(11)

当输入空间的划分确定时,可以用平方误差 ∑ x i ∈ R m ( y i − f ( x i ) ) 2 \sum \limits_{x_i\in R_m}(y_i-f(x_i))^2 xiRm(yif(xi))2来表示回归树对于训练数据的预测误差,用平方误差最小准确地求解每个单元上的最优输出值。易知,单元 R m R_m Rm上的 c m c_m cm的最优值 c ^ m \hat{c}_m c^m R m R_m Rm上的所有输入实例 x i x_i xi对应的输出 y i y_i yi的均值,即: c ^ m = a v e ( y i ∣ x i ∈ R m ) (12) \hat{c}_m={\rm ave}(y_i|x_i\in R_m)\tag{12} c^m=ave(yixiRm)(12)

这时采用启发式的方法来划分空间,选择第 j j j个变量 x ( j ) x^{(j)} x(j)和它的取值 s s s作为切分变量和切分点,并定义两个区域: R 1 ( j , s ) = { x ∣ x ( j ) ≤ s } ,   R 2 ( j , s ) = { x ∣ x ( j ) > s } (13) R_1(j,s)=\{x|x^{(j)}\leq s\},\ R_2(j,s)=\{x|x^{(j)}> s\}\tag{13} R1(j,s)={xx(j)s}, R2(j,s)={xx(j)>s}(13)

然后寻找最优切分变量 j j j和最优切分点 s s s。具体地,求解: min ⁡ j , s [ min ⁡ c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] (14) \min_{j,s}\left[\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\right]\tag{14} j,sminc1minxiR1(j,s)(yic1)2+c2minxiR2(j,s)(yic2)2(14)

对固定输入变量 j j j可以找到最优切分点 s s s c ^ 1 = a v e ( y i ∣ x i ∈ R 1 ( j , s ) ) ,   c ^ 2 = a v e ( y i ∣ x i ∈ R 2 ( j , s ) ) (15) \hat{c}_1={\rm ave}(y_i|x_i\in R_1(j,s)),\ \hat{c}_2={\rm ave}(y_i|x_i\in R_2(j,s))\tag{15} c^1=ave(yixiR1(j,s)), c^2=ave(yixiR2(j,s))(15)

遍历所有输入变量,找到最优的切分变量 j j j,构成一个对 ( j , s ) (j,s) (j,s)。以此将输入空间划分成两个区域,然后对每个区域重复上述的划分过程,直到满足终止条件为止。这样的回归树称为最小二乘回归树

最小二乘回归树生成算法

输入 训练数据集 D D D

输出 回归树 f ( x ) f(x) f(x)

(1)选择最优切分变量 j j j于切分点 s s s,求解: min ⁡ j , s [ min ⁡ c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] \min_{j,s}\left[\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\right] j,sminc1minxiR1(j,s)(yic1)2+c2minxiR2(j,s)(yic2)2

(2)用选定的对 ( j , s ) (j,s) (j,s)划分区域并决定相应的输出值: R 1 ( j , s ) = { x ∣ x ( j ) ≤ s } ,   R 2 ( j , s ) = { x ∣ x ( j ) > s } R_1(j,s)=\{x|x^{(j)}\leq s\},\ R_2(j,s)=\{x|x^{(j)}> s\} R1(j,s)={xx(j)s}, R2(j,s)={xx(j)>s}

c ^ m = 1 N m ∑ x i ∈ R m ( j , s ) y i ,   x ∈ R m ,   m = 1 , 2 \hat{c}_m=\frac{1}{N_m}\sum_{x_i\in R_m(j,s)}y_i,\ x\in R_m,\ m=1,2 c^m=Nm1xiRm(j,s)yi, xRm, m=1,2

(3)继续对两个子区域调用步骤(1)和(2),直至满足停止条件;

(4)将输入空间划分为 M M M个区域 R 1 , R 2 , . . . , R M R_1,R_2,...,R_M R1,R2,...,RM,生成决策树: f ( x ) = ∑ m = 1 M c m I ( x ∈ R m ) . f(x)=\sum_{m=1}^Mc_mI(x\in R_m). f(x)=m=1McmI(xRm).

2.1.2 分类树的生成

分类树用基尼指数选择最优特征,同时决定该特征的最优二值切分点。基尼指数的定义如下:分类问题中,假设有 K K K个类,样本点属于第 k 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 (16) {\rm Gini}(p)=\sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp_k^2\tag{16} Gini(p)=k=1Kpk(1pk)=1k=1Kpk2(16)

对于给定的样本集合 D D D,其基尼指数为: G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 (17) {\rm Gini}(D)=1-\sum_{k=1}^K\left(\frac{|C_k|}{|D|}\right)^2\tag{17} Gini(D)=1k=1K(DCk)2(17)

这里, C k C_k Ck D D D中属于第 k k k类的样本子集, K K K是类的个数。如果样本集合 D D D根据特征 A A A是否取某一可能值 a a a被分割称 D 1 D_1 D1 D 2 D_2 D2两部分,即: D 1 = { ( x , y ) ∈ D ∣ A ( x ) = a } ,   D 2 = D − D 1 D_1=\{(x,y)\in D|A(x)=a\},\ D_2=D-D_1 D1={(x,y)DA(x)=a}, D2=DD1

则在特征 A A A的条件下,集合 D D 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 ) (18) {\rm Gini}(D,A)=\frac{|D_1|}{|D|}{\rm Gini}(D_1)+\frac{|D_2|}{|D|}{\rm Gini}(D_2)\tag{18} Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)(18)

基尼指数 G i n i ( D ) {\rm Gini}(D) Gini(D)表示集合 D D D的不确定性,基尼指数 G i n i ( D , A ) {\rm Gini}(D,A) Gini(D,A)表示经过 A = a A=a A=a分割后的集合的不确定性。基尼指数越大,样本集合的不确定性也就越大,这一点与熵类似。

CART生成算法

输入 训练数据集 D D D,停止计算的条件;

输出 C A R T {\rm CART} CART决策树。

(1)设训练数据集为 D D D,计算现有特征对该数据集的基尼指数;

(2)对所有可能的特征 A A A以及它们可能所有可能的切分点 a a a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点;

(3)对两个子结点递归地调用(1)和(2),直至满足停止条件;

(4)生成 C A R T {\rm CART} CART决策树。

解例题

首先计算各特征的基尼指数,选择最优特征以及其最优切分点。特征表示符号同上,则首先求特征 A 1 A_1 A1的基尼指数:
G i n i ( D , A 1 = 1 ) = 5 15 × ( 2 × 2 5 × ( 1 − 2 5 ) ) + 10 15 × ( 2 × 7 10 × ( 1 − 7 10 ) ) = 0.44 {\rm Gini}(D,A_1=1)=\frac{5}{15}×\left(2×\frac{2}{5}×\left(1-\frac{2}{5}\right)\right)+\frac{10}{15}×\left(2×\frac{7}{10}×\left(1-\frac{7}{10}\right)\right)=0.44 Gini(D,A1=1)=155×(2×52×(152))+1510×(2×107×(1107))=0.44

G i n i ( D , A 1 = 2 ) = 5 15 × ( 2 × 3 5 × ( 1 − 3 5 ) ) + 10 15 × ( 2 × 6 10 × ( 1 − 6 10 ) ) = 0.48 {\rm Gini}(D,A_1=2)=\frac{5}{15}×\left(2×\frac{3}{5}×\left(1-\frac{3}{5}\right)\right)+\frac{10}{15}×\left(2×\frac{6}{10}×\left(1-\frac{6}{10}\right)\right)=0.48 Gini(D,A1=2)=155×(2×53×(153))+1510×(2×106×(1106))=0.48

G i n i ( D , A 1 = 3 ) = 5 15 × ( 2 × 4 5 × ( 1 − 4 5 ) ) + 10 15 × ( 2 × 5 10 × ( 1 − 5 10 ) ) = 0.44 {\rm Gini}(D,A_1=3)=\frac{5}{15}×\left(2×\frac{4}{5}×\left(1-\frac{4}{5}\right)\right)+\frac{10}{15}×\left(2×\frac{5}{10}×\left(1-\frac{5}{10}\right)\right)=0.44 Gini(D,A1=3)=155×(2×54×(154))+1510×(2×105×(1105))=0.44

综上, A 1 = 1 A_1=1 A1=1 A 1 = 3 A_1=3 A1=3可以作为特征 A 1 A_1 A1的最优切分点。同理计算其他特征的基尼指数:
G i n i ( D , A 2 = 1 ) = 5 15 × ( 2 × 5 5 × ( 1 − 5 5 ) ) + 10 15 × ( 2 × 4 10 × ( 1 − 4 10 ) ) = 0.32 {\rm Gini}(D,A_2=1)=\frac{5}{15}×\left(2×\frac{5}{5}×\left(1-\frac{5}{5}\right)\right)+\frac{10}{15}×\left(2×\frac{4}{10}×\left(1-\frac{4}{10}\right)\right)=0.32 Gini(D,A2=1)=155×(2×55×(155))+1510×(2×104×(1104))=0.32

G i n i ( D , A 3 = 1 ) = 6 15 × ( 2 × 0 5 × ( 1 − 0 5 ) ) + 9 15 × ( 2 × 3 9 × ( 1 − 3 9 ) ) = 0.27 {\rm Gini}(D,A_3=1)=\frac{6}{15}×\left(2×\frac{0}{5}×\left(1-\frac{0}{5}\right)\right)+\frac{9}{15}×\left(2×\frac{3}{9}×\left(1-\frac{3}{9}\right)\right)=0.27 Gini(D,A3=1)=156×(2×50×(150))+159×(2×93×(193))=0.27

由于 A 2 A_2 A2 A 3 A_3 A3均只有一个切分点,所以它们就是最优切分点。
G i n i ( D , A 4 = 1 ) = 4 15 × ( 2 × 5 5 × ( 1 − 5 5 ) ) + 11 15 × ( 2 × 5 11 × ( 1 − 5 11 ) ) = 0.36 {\rm Gini}(D,A_4=1)=\frac{4}{15}×\left(2×\frac{5}{5}×\left(1-\frac{5}{5}\right)\right)+\frac{11}{15}×\left(2×\frac{5}{11}×\left(1-\frac{5}{11}\right)\right)=0.36 Gini(D,A4=1)=154×(2×55×(155))+1511×(2×115×(1115))=0.36

G i n i ( D , A 4 = 2 ) = 6 15 × ( 2 × 4 6 × ( 1 − 4 6 ) ) + 9 15 × ( 2 × 5 9 × ( 1 − 5 9 ) ) = 0.47 {\rm Gini}(D,A_4=2)=\frac{6}{15}×\left(2×\frac{4}{6}×\left(1-\frac{4}{6}\right)\right)+\frac{9}{15}×\left(2×\frac{5}{9}×\left(1-\frac{5}{9}\right)\right)=0.47 Gini(D,A4=2)=156×(2×64×(164))+159×(2×95×(195))=0.47

G i n i ( D , A 4 = 3 ) = 5 15 × ( 2 × 1 5 × ( 1 − 1 5 ) ) + 10 15 × ( 2 × 8 10 × ( 1 − 8 10 ) ) = 0.32 {\rm Gini}(D,A_4=3)=\frac{5}{15}×\left(2×\frac{1}{5}×\left(1-\frac{1}{5}\right)\right)+\frac{10}{15}×\left(2×\frac{8}{10}×\left(1-\frac{8}{10}\right)\right)=0.32 Gini(D,A4=3)=155×(2×51×(151))+1510×(2×108×(1108))=0.32

综上, A 4 = 3 A_4=3 A4=3可以作为特征 A 3 A_3 A3的最优切分点。在几个特征中, G i n i ( D , A 3 = 1 ) = 0.27 {\rm Gini}(D,A_3=1)=0.27 Gini(D,A3=1)=0.27最小,所以选择 A 3 A_3 A3为最优特征, A 3 = 1 A_3=1 A3=1为最优切分点。于是根结点生成两个子结点,一个是叶结点。对另一个结点继续使用上述方法,直到所有结点均为叶结点。

2.2 CART剪枝

2.2.1 剪枝,形成一个子序列

同决策树的剪枝过程类似,在剪枝过程中,首先计算子树的损失函数: C α ( T ) = C ( T ) + α ∣ T ∣ (19) C_{\alpha}(T)=C(T)+\alpha|T|\tag{19} Cα(T)=C(T)+αT(19)

具体地,从整体树 T 0 T_0 T0开始剪枝。对 T 0 T_0 T0的任意内部结点 t t t,以 t t t为单结点树的损失函数是: C α ( t ) = C ( T ) + α (20) C_{\alpha}(t)=C(T)+\alpha\tag{20} Cα(t)=C(T)+α(20)

t t t为根结点的子树 T t T_t Tt的损失函数是: C α ( T t ) = C ( T t ) + α ∣ T t ∣ (21) C_{\alpha}(T_t)=C(T_t)+\alpha|T_t|\tag{21} Cα(Tt)=C(Tt)+αTt(21)

α = 0 \alpha=0 α=0 α \alpha α充分小时,有不等式: C α ( T t ) < C α ( t ) (22) C_{\alpha}(T_t)<C_{\alpha}(t)\tag{22} Cα(Tt)<Cα(t)(22)

α \alpha α增大时,在某一 α \alpha α有: C α ( T t ) = C α ( t ) (23) C_{\alpha}(T_t)=C_{\alpha}(t)\tag{23} Cα(Tt)=Cα(t)(23)

α \alpha α再增大时,式子(22)反向。只要满足 α = C ( t ) − C ( T t ) ∣ T t ∣ − 1 \alpha=\frac{C(t)-C(T_t)}{|T_t|-1} α=Tt1C(t)C(Tt) T t T_t Tt t t t有相同的损失函数,而 t t t的结点少,因此 t t t更好,继续对 T t T_t Tt剪枝。为此,对 T 0 T_0 T0中每一个内部节点 t t t,计算: g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1 (24) g(t)=\frac{C(t)-C(T_t)}{|T_t|-1}\tag{24} g(t)=Tt1C(t)C(Tt)(24)

该式子表示剪枝后整体损失函数减少的程度。在 T 0 T_0 T0中剪去 g ( t ) g(t) g(t)最小的 T t T_t Tt,将得到的子树作为 T 1 T_1 T1,同时将最小的 g ( t ) g(t) g(t)设为 α 1 \alpha_1 α1 T 1 T_1 T1为区间 [ α 1 , α 2 ) [\alpha_1,\alpha_2) [α1,α2)的最优子树。如此剪枝下去,直到得到根结点。在这一过程中,不断增大 α \alpha α的值,产生新的区间。

2.2.2 在剪枝得到的子树序列 T 0 , T 1 , . . . , T n T_0,T_1,...,T_n T0,T1,...,Tn中通过交叉验证选取最优子树 T α T_{\alpha} Tα

具体地,利用独立的验证数据集,测试子树序列 T 0 , T 1 , . . . , T n T_0,T_1,...,T_n T0,T1,...,Tn中各棵子树的平方误差或基尼指数。在子树序列中,每棵子树 T 0 , T 1 , . . . , T n T_0,T_1,...,T_n T0,T1,...,Tn都对应于一个参数 α 0 , α 1 , . . . , α n \alpha_0,\alpha_1,...,\alpha_n α0,α1,...,αn

CART剪枝算法

输入 C A R T {\rm CART} CART算法生成的决策树 T 0 T_0 T0

输出 最优决策树 T α T_{\alpha} Tα

(1)设 k = 0 k=0 k=0 T = T 0 T=T_0 T=T0

(2)设 α = + ∞ \alpha=+\infty α=+

(3)自下而上地对各内部结点 t t t计算 C ( T t ) C(T_t) C(Tt) ∣ T t ∣ |T_t| Tt以及 g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1 g(t)=\frac{C(t)-C(T_t)}{|T_t|-1} g(t)=Tt1C(t)C(Tt)

α = min ⁡ ( α , g ( t ) ) \alpha=\min(\alpha,g(t)) α=min(α,g(t))

(4)对 g ( t ) = α g(t)=\alpha g(t)=α的内部结点 t t t进行剪枝,并对叶结点 t t t以多数表决法决定其类,得到树 T T T

(5)设 k = k + 1 k=k+1 k=k+1 α k = α \alpha_k=\alpha αk=α T k = T T_k=T Tk=T

(6)如果 T k T_k Tk不是由根结点及两个叶结点构成的树,则返回到步骤(2);否则令 T k = T n T_k=T_n Tk=Tn

(7)采用交叉验证法在子树序列 T 0 , T 1 , . . . , T n T_0,T_1,...,T_n T0,T1,...,Tn中选取最优子树 T α T_{\alpha} Tα


3. Python实现决策树

与前一节相同,首先加载数据集:

def load_data(file):
    # 定义空列表
    dataArr = []
    labelArr = []
    # 打开并处理文件
    with open(file, "r") as f:
        lines = f.readlines()
        for line in lines:
            # 针对csv文件格式,使用','分割数据
            curLine = line.strip().split(',')
            # csv文件第一列存放着具体类别
            labelArr.append(int(line[0]))
            # 处理具体数据,为了简化计算量,将像素取值限制在01两个部分
            # 如果不简化,处理的数据量是10×784×256,现在是10×784×2
            dataArr.append([int(int(num) > 128) for num in curLine[1:]])
        # 返回
        return dataArr, labelArr

然后定义函数计算数据集的经验熵,即公式(4):

def cal_h_d(labels):
    # 计算训练数据集的经验熵
    h_d = 0
    # 训练标签集合,使用set避免出现对数真数为零的情况
    # https://github.com/Dod-o/Statistical-Learning-Method_Code/blob/master/DecisionTree/DecisionTree.py#L76
    trainLabelSet = set([label for label in labels])
    for i in trainLabelSet:
        # |Ck|/|D|,labels[labels==i].size相当于一个指示函数
        p = labels[labels == i].size / labels.size
        # 求和
        h_d += -1 * p * np.log2(p)
    return h_d

然后定义函数计算对应特征的条件经验熵,即公式(5):

def cal_a_d(data_dev_features, labels):
    # 计算条件经验熵
    a_d = 0
    # 将特征取值放入集合内
    trainDataSet = set([label for label in data_dev_features])
    for i in trainDataSet:
        # 根据公式计算条件经验熵
        a_d += data_dev_features[data_dev_features == i].size / data_dev_features.size \
               * cal_h_d(labels[data_dev_features == i])
    return a_d

然后定义函数实现功能:基于信息增益完成最优特征的选取:

def major_class(labels):
    # 找到最大的标签数
    classDict = {}
    for i in range(len(labels)):
        if labels[i] in classDict.keys():
            classDict[labels[i]] += 1
        else:
            classDict[labels[i]] = 1
    # 对结果逆序排序
    classSort = sorted(classDict.items(), key=lambda x: x[1], reverse=True)
    return classSort[0][0]

def sel_best_feature(train_data, train_label):
    # 基于信息增益选择最优特征
    # 转换格式
    train_data = np.array(train_data)
    train_label = np.array(train_label)
    # 特征数目,784
    num_features = train_data.shape[1]
    # 初始化最大信息增益及对应的特征
    max_g_d_a = -1
    max_feature = -1
    # 信息增益算法,计算经验熵
    h_d = cal_h_d(train_label)
    # 遍历特征
    for i in range(num_features):
        # 由于每次计算特征仅针对特征参与运算,其他特征我们不关心,这些将待计算特征切分下来并展开
        # https://github.com/Dod-o/Statistical-Learning-Method_Code/blob/master/DecisionTree/DecisionTree.py#L148
        train_data_arr_dev_feature = np.array(train_data[:, i].flat)
        # 计算信息增益
        g_d_a = h_d - cal_a_d(train_data_arr_dev_feature, train_label)
        # 更新
        if g_d_a > max_g_d_a:
            max_g_d_a = g_d_a
            max_feature = i
    return max_feature, max_g_d_a

提取数据集中的某一列特征:

def get_sub_data(train_data, train_label, A, a):
    # 定义返回值
    re_data = []
    re_label = []
    for i in range(len(train_data)):
        # 当前样本特征为指定特征
        if train_data[i][A] == a:
            # 将样本的第A个特征切掉
            re_data.append(train_data[i][0: A] + train_data[i][A + 1:])
            re_label.append(train_label[i])
    return re_data, re_label

最后,使用递归的方式建立决策树:

def create_tree(*dataset):
    # 以递归的方式创建决策树
    # 设置阈值
    epsilon = 0.1
    # 训练数据集
    train_data_list = dataset[0][0]
    train_label_list = dataset[0][1]
    # 打印信息
    print("start a node", len(train_data_list[0]), len(train_label_list))
    # 将标签放入字典
    classDict = {i for i in train_label_list}
    # 只有一个类别,则会产生叶结点
    if len(classDict) == 1:
        return train_label_list[0]
    # 空字典,选择特征完成
    if len(train_data_list[0]) == 0:
        return major_class(train_label_list)
    # 计算信息增益,并选择最大信息增益的特征
    g_d_a, feature = sel_best_feature(train_data_list, train_label_list)
    # 与阈值比较
    if feature < epsilon:
        return major_class(train_label_list)
    # 递归建立决策树
    treeDict = {g_d_a: {}}
    treeDict[g_d_a][0] = create_tree(get_sub_data(train_data_list, train_label_list, g_d_a, 0))
    treeDict[g_d_a][1] = create_tree(get_sub_data(train_data_list, train_label_list, g_d_a, 1))
    # 返回
    return treeDict

测试集上的表现:

def predict(test_data, tree):
    # 定义死循环,直到找到一个合适的分类
    while 1:
        # 读取字典
        (key, value), = tree.items()
        # 如果当前的value是字典,还需要继续遍历下去
        if type(tree[key]).__name__ == "dict":
            # 获得当前特征并删除
            data_value = test_data[key]
            del test_data[key]
            # 将tree更新为其子结点的字典
            tree = value[data_value]
            # 返回分类
            if type(tree).__name__ == "int":
                return tree
        # 当前value不是字典,直接返回类别
        else:
            return value

def test(test_data_list, test_label_list, tree):
    # 记录错误个数
    errorCnt = 0
    # 遍历测试集数据
    for i in range(len(test_label_list)):
        # 错误数加一
        if test_label_list[i] != predict(test_data_list[i], tree):
            errorCnt += 1
    # 计算正确率
    return 1 - (errorCnt / len(test_data_list))

4. 决策树总结

分类决策树模型是表示基于特征对实例进行分类的树形结构。决策树可以转化成一个if-else规则的集合,也可以看作是定义在特征空间划分上的类的条件概率分布。建立决策树模型的过程主要包括:特征选择树的生成树的剪枝。首先,通常使用信息增益、信息增益比或基尼指数为准则来选择最优特征;然后以递归的方式生成决策树;最后,由于生成的决策树存在过拟合问题,需要对它进行剪枝,以简化学习到的决策树。


参考

  1. 统计学习方法/李航著。—2版。—北京:清华大学出版社,2019(2019.6重印).
  2. https://github.com/Dod-o/Statistical-Learning-Method_Code(决策树代码).


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值