决策树 - ID3、C4.5、CART
对于决策树的学习,无论是ID3、C4.5和CART分类树还是CART回归树,其实都需要重点关注几个点:
- 数据集确定性的评价指标(信息增益、信息增益比、基尼指数、平方误差)
- 递归构造决策树过程中,基于数据集确定性的评价指标选择最优特征和最优切分点以构造子树的过程(ID3和C4.5算法生成f分类决策树的过程中生成的是多叉树,只需要重点关注特征选择过程即可,然后根据选择的最优特征的取值对数据集进行划分,特征有几个取值就会得到几个子集,每个子集对应一棵子树。而CART回归树和分类树都是二叉树,这就使得我们不仅要考虑如何得到当前数据集的最优特征,还要重点考虑如何得到当前特征的最优切分点,以对数据集进行二分,构造两棵子树)
- 决策树的剪枝过程也是需要重点关注的一点。由决策树生成算法得到的生成树可能存在过拟合问题,为了得到泛化性能最优的决策树,一般都得对决策树进行剪枝。可以简单理解决策树的生成过程得到是局部最优的决策树,而对决策树进行剪枝后得到的才是全局最优的决策树。所以,决策树的剪枝是一定要考虑的一个问题。预剪枝的思想是在生成过程中剪枝,思路很简单。而后剪枝的一般思想是,首先给定一个损失函数,然后基于损失函数计算剪枝后的树和剪枝前的树的损失函数值,如果损失减小,则进行剪枝,否则不进行。
1. 决策树模型
决策树是一种基本的分类和回归方法。分类决策树模型是一种描述对实例进行分类的树形结构。决策树由节点和有向边组成。节点有两种类型:内部节点和叶节点。内部节点表示一个特征或属性,叶节点表示一个类。
学习时,利用训练数据,根据损失函数最小化的原则建立决策树模型。预测时,对新的数据,利用决策树模型进行分类。
对决策树模型的理解可以通过两个角度:
- 把决策树看成一个互斥且完备的if-then规则的集合:由决策树的根节点到叶节点的每一条路径构建一条规则,路径上内部节点的特征对应着规则的条件,而叶节点的类对应着规则的结论。
- 决策树也可以表示给定特征条件下类的条件概率分布:这一条件概率分布定义在特征空间的一个划分上。将特征空间划分为互不相交的单元或区域,并在每个单元定义一个类的概率分布就构成了一个条件概率分布。
2. 决策树的学习
决策树在学习时,利用训练数据,根据损失函数最小化的原则建立决策树模型。决策树学习通常包括3个步骤:特征选择、决策树的生成__和__决策树的剪枝。
-
特征选择:特征选择是决定用哪个特征来划分特征空间的过程。在构建决策树时,我们需要根据当前的数据集选择出具有最大分类能力的特征(分类能力的度量可以用信息增益、信息增益比或是基尼指数等指标)作为当前节点,再将这个特征作为分类标准,对当前数据集进行划分,在划分得到的各个子数据集中分别构建新的子树。如果利用一个特征进行分类与随机分类的结果没有很大区别,则称这个特征是没有分类能力的。很显然,选择没有分类能力的特征构建决策树是不可取的,所以这也是在每一步构建子树时都需要找到当前分类能力最强的特征作为节点的原因。
-
决策树的生成:决策树的生成通常是一个递归的选择最优特征,并根据该特征对训练数据进行分割,使得对各个子数据集有一个最好的分类的过程。每次根据当前子数据集选择最优特征(这个最优特征应该是决策树中祖先节点没有用过的特征)作为子树的根节点,并根据这个最优特征对子数据集进行划分,对划分的各个更小的子数据集再递归的进行特征选择和数据集划分的过程,直到生成一棵最终的决策树。决策树的生成直到没有更优的特征可以被选择即停止,生成的决策树在当前的训练集上表现效果会非常好。
-
决策树的剪枝:决策树的生成过程生成的决策树虽然在训练集上表现很出色,但在测试集上可能效果极差,这是因为过拟合现象的发生。为了避免过拟合,我们需要考虑基于一定策略对当前生成的决策树进行剪枝,以保证决策树具有足够的准确性的同时提高决策树的泛化性能。具体过程,其实就是去掉过于细分的叶节点,使其回退到父节点,甚至更高的节点,然后将父节点或更高的节点作为新的叶节点。决策树的剪枝策略有两种:
-
预剪枝:在构造决策树的过程中进行剪枝,一般通过设置阈值的方式来做预剪枝,比如设置信息增益、信息增益比和基尼指数的阈值或者设置当前子节点中包含的最少样本数的阈值,当样本数少于这个阈值时,停止构造新的子树。也可以设置决策树的最大层数,如果超过最大层数,则决策树停止增长。
-
后剪枝:后剪枝是在决策树生长完成之后,对树进行剪枝,得到简化版的决策树。剪枝的过程是对拥有同样父节点的一组节点进行检查,判断如果将这一组节点回缩到其父节点,熵的增加量是否小于某一阈值。如果确实小,则这一组节点回缩到父节点后,其父节点成为新的叶节点,其中的样本为所有孩子节点的合集。叶节点的类别为其中包含的样本最多的类别。
-
决策树的生成对应于模型的局部选择,决策树的剪枝对应于模型的全局选择。决策树的生成只考虑局部最优,相对的,决策树的剪枝则考虑全局最优。
接下来分别介绍ID3、C4.5和CART算法中的特征选择、决策树生成和决策树的剪枝过程。
3. ID3算法生成决策树
3.1 ID3算法中的特征选择标准——信息增益
ID3算法中选择当前数据集中具有最大分类能力的特征是基于信息增益来做的。具体过程是,计算当前数据集中所有可选特征的信息增益,选择信息增益最大的特征作为节点的特征,并由该节点的不同取值对数据集进行划分,并对划分得到的字数据集建立新的子节点。这里需要注意,当前节点的祖先节点中已经选用过的特征不能再复用。
下面来说下信息增益的计算过程。
首先来说__熵__,熵是表示随机变量不确定性的度量,熵越大,随机变量的不确定性就越大。设 X X X是一个取有限个值的离散随机变量,其中每一个取值的概率分布为 P ( X = x i ) = p i , i = 1 , 2 , ⋯ , n P(X=x_{i})=p_{i}, \quad i=1,2,\cdots,n P(X=xi)=pi,i=1,2,⋯,n,则随机变量 X X X的熵定义为:
H ( X ) = − ∑ i = 1 n p i l o g p i H(X)=-\sum_{i=1}^{n}p_{i}\ logp_{i} H(X)=−i=1∑npi logpi
熵的性质中,大概有几条需要注意一下:
- 0 ≤ H ( p ) ≤ l o g n 0\leq H(p)\leq logn 0≤H(p)≤logn
- 当随机变量只取两个值时:当 p = 0.5 p=0.5 p=0.5, H ( p ) = 1 H(p)=1 H(p)=1,熵取值最大,随机变量不确定最大;当 p = 0 p=0 p=0或 p = 1 p=1 p=1, H ( p ) = 0 H(p)=0 H(p)=0,此时随机变量完全没有不确定性。
- 熵只依赖于 X X X的分布,而与 X X X的取值无关
接下来,从单变量的熵推广到两个随机变量 ( X , Y ) (X,Y) (X,Y)的__条件熵__,设其概率分布为
P ( X = x i , Y = y i ) = p i j P(X=x_{i},Y=y_{i})=p_{ij} P(X=xi,Y=yi)=pij
则随机变量 X X X给定条件下随机变量 Y Y Y的条件熵 H ( Y ∣ X ) H(Y|X) H(Y∣X)为:
H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) , p i = P ( X = x i ) H(Y|X)=\sum_{i=1}^{n}p_{i}H(Y|X=x_{i}), \quad\quad p_{i}=P(X=x_{i}) H(Y∣X)=i=1∑npiH(Y∣X=xi),pi=P(X=xi)
条件熵的计算过程可以表示为:设数据集 Y Y Y中有 K K K个类别,第 k k k个类别表示为 C k C_{k} Ck,第 k k k个类别的样本数目为 ∣ C k ∣ |C_{k}| ∣Ck∣;特征 X X X有 n n n个不同的取值 { a 1 , a 2 , ⋯ , a n } \{ a_{1},a_{2},\cdots,a_{n} \} {a1,a2,⋯,an},根据特征 X X X的不同取值可以将数据集 Y Y Y划分成 n n n个子数据集 D 1 , D 2 , ⋯ , D n D_{1},D_{2},\cdots,D_{n} D1,D2,⋯,Dn,第 i i i个子集的样布数目为 ∣ D i ∣ |D_{i}| ∣Di∣,记子集 D i D_{i} Di中属于类别 C k C_{k} Ck的样本的集合为 D i k D_{ik} Dik。则条件熵的计算过程,可以简单阐述为先算每个子集 D i D_{i} Di的熵,再对每个子集 D i D_{i} Di乘以一个权重 ∣ D i ∣ D \frac{|D_{i}|}{D} D∣Di∣进行加和,得到的最终结果即为条件熵 H ( Y ∣ X ) H(Y|X) H(Y∣X),公式为:
H ( Y ∣ X ) = ∑ i = 1 n ∣ D i ∣ D H ( D i ) = − ∑ i = 1 n ∣ D i ∣ D ∑ k = 1 K ∣ D i k ∣ ∣ D i ∣ l o g 2 ∣ D i k ∣ ∣ D i ∣ H(Y|X)=\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}|} H(Y∣X)=i=1∑nD∣Di∣H(Di)=−i=1∑nD∣Di∣k=1∑K∣Di∣∣Dik∣log2∣Di∣∣Dik∣
知道了熵和条件熵的定义后,我们就可以定义信息增益了,__信息增益__表示得知特征 X X X的信息而使得类 Y Y Y的信息的不确定性减少的程度,这种不确定性的减少程度是通过熵来定义的.
定义特征 A A A对训练数据集 D D D的信息增益为:
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)−H(D∣A)
显然,对于一个特定数据集而言,信息增益依赖于特征,不同特征往往具有不同的信息增益,信息增益大的特征具有更强的分类能力,也是我们构造决策树时需要优先选择的。
3.2 基于ID3算法的决策树生成
算法流程如下:
其中有几点需要注意:
- 在计算信息增益时,如果某个特征取值包含的样本数为0,则定义 0 l o g 2 0 = 0 0log_{2}0=0 0log20=0
- 为了防止过拟合的发生,这里需要设置一个信息增益的阈值对决策树做预剪枝,只有信息增益值大于这个阈值才能继续构建子树,否则构建过程结束,当前的节点作为叶节点。当然实际中这种方法可能效果并不太好,因为阈值的取值范围过大则基本是基于经验的,数据集的不同阈值也会存在很大差异,这使得提前设置一个阈值变得并不实际。
- 在第(3)步中,当前的候选特征集应该是初始特征集减去当前节点的祖先节点中所选择的特征组成的集合,这与算法流程中的第(6)步是对应的。
4. C4.5算法生成决策树
4.1 C4.5算法中的特征选择标准——信息增益比
以信息增益作为选择具有最高分类能力的特征的标准,存在偏向于选择取值较多的特征的问题。而如果使用使用信息增益比,则可以对这个问题进行校正,这是特征选择的另一个准则,也可以算是对信息增益的一个改进。
为什么取值较多的特征信息增益比就会偏大呢?为什么除以一个 H A ( D ) H_{A}(D) HA(D)就能解决这个问题?在我的理解里,当特征较多时, H ( D ∣ A ) H(D|A) H(D∣A)值会偏小, H ( D H(D H(D是不变的,这样才使得最终的信息增益会偏大。而在特征较多时, H A ( D ) H_{A}(D) HA(D)的值也是偏大的。极端情况下可以考虑如果只有一个特征的话,则 H A ( D ) = 0 H_{A}(D)=0 HA(D)=0,当有多于一个特征时 H A ( D ) > 0 H_{A}(D)>0 HA(D)>0,通过这个极限值大概可以理解到特征多的话 H A ( D ) H_{A}(D) HA(D)的值也会偏大(数学证明我也不会啊,要是有大佬会的话,求指点……)。综上,就可以知道,特征多时信息增益偏大,那么我们再除以一个特征多时也会偏大的值,就可以中和信息增益增大的部分,以此就可以克服偏向于选择取值较多的特征的问题。
信息增益比定义为,特征 A A A对训练数据集 D D D的信息增益 g ( D , A ) g(D,A) g(D,A)与训练数数据集关于特征 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 l o g 2 ∣ D i ∣ D H_{A}(D)=-\sum_{i=1}^{n}\frac{|D_{i}|}{D}log_{2}\frac{|D_{i}|}{D} HA(D)=−i=1∑nD∣Di∣log2D∣Di∣
注意 H A ( D ) H_{A}(D) HA(D)与 H ( D ) H(D) H(D)的区别:
- H A ( D ) H_{A}(D) HA(D)的类别是根据特征 A A A的取值来划分的,其中的 ∣ D i ∣ |D_{i}| ∣Di∣为特征 a a a的取值为 a i a_{i} ai的样本数目
- H ( D ) H(D) H(D)的类别是根据样本的标签来划分的,即样本初始给定的标签 C k C_{k} Ck
4.2 基于C4.5算法的决策树生成
C4.5算法的决策树生成过程和ID3算法大体是一致的,只是特征选择的标准由信息增益变为信息增益比。
5. 决策树的后剪枝
下面总结一下几种最常见的剪枝策略。
5.1 Reduced-Error Pruning (REP,错误率降低剪枝)
这种剪枝策略的思想非常直接,我们需要构造一个测试集,并用这个测试集来对我们每一次的剪枝尝试做测试,如果错误率降低,则进行剪枝。在测试集上错误率降低,意味着剪枝后的决策树拥有更好的泛化能力。剪枝的策略为,以bottom-up的顺序,对决策树中每个非叶节点,将以它为根节点的子树中的所有节点回缩到该节点,使得当前非叶节点变为叶节点,其中包含的样本为原始决策树中以它为根节点的所有子树中的样本,当前叶节点的类别为包含样本最多的类别,这样就得到一颗剪枝后的决策树。将剪枝后的决策树和未剪枝的决策树在测试集上进行测试,如果剪枝后的决策树错误率降低,则进行注册剪枝,否则不进行。
5.2 Cost-Complexity Pruning(CCP,代价复杂度)
这种策略不需要构造新的测试集,而是通过极小化决策树整体的损失函数或代价函数来实现的。
首先给出损失函数的公式:设树的叶节点个数为 ∣ T ∣ |T| ∣T∣, t t t是树 T T T的叶节点,该叶节点有 N t N_{t} Nt个样本点,其中第 k k k类样本点有 N t k N_{tk} Ntk个, H t T H_{t}T HtT为叶节点 t t t上的熵, α ≥ 0 \alpha \geq 0 α≥0为参数,则决策树学习的损失函数可以定义为:
C α ( T ) = ∑ t = 1 ∣ T ∣ N t H t ( T ) + α ∣ T ∣ C_{\alpha}(T)=\sum_{t=1}^{|T|}N_{t}H_{t}(T)+\alpha |T| Cα(T)=t=1∑∣T∣NtHt(T)+α∣T∣
其中的熵 H t ( T ) H_{t}(T) Ht(T)定义为:
H t ( T ) = − ∑ k N t k N t l o g N t k N t H_{t}(T)=-\sum_{k}\frac{N_{tk}}{N_{t}}log\frac{N_{tk}}{N_{t}} Ht(T)=−k∑NtNtklogNtNtk
将损失函数的第一项记为:
C ( T ) = ∑ t = 1 ∣ T ∣ N t H t ( T ) = − ∑ k N t k N t l o g N t k N t C(T)=\sum_{t=1}^{|T|}N_{t}H_{t}(T)=-\sum_{k}\frac{N_{tk}}{N_{t}}log\frac{N_{tk}}{N_{t}} C(T)=t=1∑∣T∣NtHt(T)=−k∑NtNtklogNtNtk
则损失函数可表示为:
C α ( T ) = C ( T ) + α ∣ T ∣ C_{\alpha}(T)=C(T)+\alpha|T| Cα(T)=C(T)+α∣T∣
其中:
- C ( T ) C(T) C(T)表示模型对训练数据的预测误差,即模型的拟合程度。
- ∣ T ∣ |T| ∣T∣表示叶节点的个数,即决策树的复杂度,叶节点越多说明决策树越复杂,决策树越容易发生过拟合。
显然,当对决策树进行剪枝时, C ( T ) C(T) C(T)值会增大,而 ∣ T ∣ |T| ∣T∣值会减小。参数 α ≥ 0 \alpha\geq0 α≥0控制着两者对决策树的复杂度的影响。
- 当 α \alpha α值较大时,则 ∣ T ∣ |T| ∣T∣值对最后损失函数的值影响更大,此时决策树越简单越好,越简单叶节点越少,决策树此时在训练集上准确率不高,但具有更好的泛化性能。
- 当 α \alpha α值较小时,则 ∣ T ∣ |T| ∣T∣值对最后损失函数的值的影响比$C(T) $更小,此时决策树越复杂越好,越复杂叶节点的熵越小,决策树在训练集上准确率越高,但泛化性能不好。
剪枝算法的具体流程如下:
这里需要注意的几点是:
-
ID3和C4.5算法生成的决策树的剪枝是自下而上的,从叶节点往上进行。
-
ID3和C4.5算法生成的决策树的剪枝过程中的 α \alpha α值是人工设定的,根据预先给定的 α \alpha α值对决策树进行剪枝。而后面的CART算法中的 α \alpha α值则是程序自动确定的,这一点需要区分
预先给定 α \alpha α值的剪枝方法很明显不如CART算法中由程序确定的剪枝方法,但预先给定 α \alpha α值能够使人更好的干预决策树的复杂度,取较小的 α \alpha α值进行剪枝后最终会得到较复杂(表现为层数更多、叶节点较多等)的决策树,而较大的 α \alpha α值则会得到较简单的决策树。同时,人为设定$\alpha $进行剪枝的方法很明显计算起来更简单更快,如果数据量非常大的话,CART算法进行剪枝要花费的时间要远比人工设定的方法多得多。
5.3 Pessimistic Error Pruning (PEP,悲观剪枝)
这里先记录下,以后来填坑吧……
6. CART算法
CART的英文全拼是classification and regression tree,从算法的全拼就可以看出,CART算法既可以构建离散变量的分类树也可以构造连续变量的回归树,这和ID3、C4.5算法只能构建离散变量分类树是不一样的。接下来分别总结一下CART算法构造分类树和回归树以及进行剪枝的过程。
6.1 基于CART算法的回归树生成
回归树和决策树的区别,在于回归树中的样本标签是连续值,而决策树中的样本标签是离散值。利用回归树对样本进行预测其实也是用叶节点表示的值来作为样本的预测值,这一点和决策树也是相同的。只是当样本分类是连续值时,ID3和C4.5算法不再适用,我们需要新的评价标准来对当前数据集选择最佳特征和最优切分点。
首先给出回归树的定义:假设 X X X和 Y Y Y分别是输出变量,并且 Y Y Y是连续变量,给定训练数据 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } D=\{ (x_{1},y_{1}),(x_{2},y_{2}),\cdots,(x_{N},y_{N})\} D={(x1,y1),(x2,y2),⋯,(xN,yN)},回归树就是对这种标签值是连续值的样本进行回归预测。
一棵回归树实际上对应着输入空间(也就是特征空间)的一个划分,每个划分的子空间都对应一个输出,如果想回归预测的值尽可能的多,那么需要降低阈值,以加深回归树的深度来增加叶节点的个数,每个叶节点都对应一个子划分的输出值。
假设已将输入空间划分为 M M M个单元 R 1 , R 2 , ⋯ , R M R_{1},R_{2},\cdots,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 ) f(x)=\sum_{m=1}^{M}c_{m}I(x \in R_{m}) f(x)=m=1∑McmI(x∈Rm)
这个表达式中只有 x ∈ R m x \in R_{m} x∈Rm时,才有 I = 1 I=1 I=1,其他时候 I = 0 I=0 I=0。
当输入空间的划分确定后,每个划分的误差可以用__平方误差__ ∑ x i ∈ R m ( y i − f ( x i ) ) 2 \sum_{x_{i} \in R_{m}}(y_{i}-f(x_{i}))^{2} ∑xi∈Rm(yi−f(xi))2来计算。其中, y i y_{i} yi为当前样本的真实标签值, f ( x i ) f(x_{i}) f(xi)为经过回归树预测的样本标签值。
每个叶节点的标签值 c m c_{m} cm(因为其实每个叶节点就对应一个特征空间的划分)我们用该节点中包含的样本的真实标签值的平均值来表示,即一个叶节点的标签值为:
c m = a v e r a g e ( y i ∣ x i ∈ R m ) c_{m}=average(y_{i}|x_{i}\in R_{m}) cm=average(yi∣xi∈Rm)
在构建回归树时,我们分别选取数据的第 j j j个特征 x j x^{j} xj作为切分变量,并选取当前特征 x j x^{j} xj在数据集中的每个取值 s s 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\}, \quad \quad R_{2}(j,s)=\{ x|x^{j} > s\} R1(j,s)={x∣xj≤s},R2(j,s)={x∣xj>s}
在对划分后的两个子集求平方误差和后,对应平方误差之和最小的切分特征和切分点就是当前子数据集构建子树时选择的根节点特征和划分值,用于将数据集二分。具体的目标公式为:
m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] \underset{j,s}{min}\left [ \underset{c_{1}}{min}\sum_{x_{i}\in R_{1}(j,s)}(y_{i}-c_{1})^{2} + \underset{c_{2}}{min}\sum_{x_{i}\in R_{2}(j,s)}(y_{i}-c_{2})^{2}\right ] j,smin⎣⎡c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2⎦⎤
所以总结一下,CART回归树的生成和CART分类树的生成其实是类似的,同样都是根据选择标准选择每次数据集分裂时的最优特征和最优切分点,以递归构建一棵二叉子树。只是CART分类树中采用的是基尼指数来选择最优的特征和切分点,而CART回归树中采用的是平方误差(因为是连续值)来选择最优特征和特征的最佳切分点。
CART分类树构建算法的具体流程如下:
6.2 基于CART算法的分类树生成
基于CART算法的分类树生成过程中,特征选择的标准为基尼指数,决策树的构造过程也与ID3和C4.6存在差异,由ID3和C4.5算法构建的决策树是多叉的,每个节点包含了多少个子节点由这个节点选择的特征的取值情况决定,当前节点中的特征有多少种取值则子结点有多少个。而由CART算法构建的决策树是一棵二叉决策树,与每个特征的具体取值数目是无关的。
首先给出基尼指数的定义:分类问题中,假设有 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 Gini(p)=\sum_{k=1}^{K}p_{k}(1-p_{k})=1-\sum_{k=1}^{K}p_{k}^{2} Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2
对于给定的样本集合 D D 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 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\}, \quad D_{2}=D-D_{1} D1={(x,y)∈D∣A(x)=a},D2=D−D1
则在特征 A A A的条件下,集合 D D D的基尼指数为:
G i n i ( D , A = a ) = ∣ D 1 ∣ D G i n i ( D 1 ) + ∣ D 2 ∣ D G i n i ( D 2 ) Gini(D,A=a)=\frac{|D_{1}|}{D}Gini(D_{1})+\frac{|D_{2}|}{D}Gini(D_{2}) Gini(D,A=a)=D∣D1∣Gini(D1)+D∣D2∣Gini(D2)
基尼指数 G i n i ( D ) Gini(D) Gini(D)表示的是集合 D D D的不确定性,基尼指数 G i n i ( D , A ) Gini(D,A) Gini(D,A)表示的是经过 A = a A=a A=a分割后集合 D D D的不确定性。基尼指数越大,样本集合的不确定性就越大,这一点上和熵是类似的。
在当前子数据集上选择最优特征和最佳切分点时时,直接选则 G i n i ( D , A = a ) Gini(D,A=a) Gini(D,A=a)值最小的特征 A A A以及对应的切分点 A = a A=a A=a来将当前数据集划分成两个节点,再由这两个子集分别递归构建新的子树。那么这里有几个问题其实我们可以考虑的:
- 基于CART算法构建二叉决策树的过程中,不仅仅需要根据当前数据集选择最佳特征,还需要选择出最佳特征的最优切分点,以此来将当前子集分成两部分。而在ID3和C4.5算法中,只需要选择最优特征即可,因为特征的每种取值都会对应一棵子树。
- 通过对比我们还可以发现,CART算法中是直接通过计算特征A条件下的集合 D D D的基尼指数 G i n i ( D , A = a ) Gini(D,A=a) Gini(D,A=a)并选择其中的最小值对应的特征和切分点作为当前数据集的根节点的。而在ID3和C4.5算法中,我们需要计算的是一个差值 g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)−H(D∣A),而不只是通过 H ( D ∣ A ) H(D|A) H(D∣A)的值来确定最优特征。在这一点我有点疑惑,因为对于当前数据集其实 H ( D ) H(D) H(D)是不变的,当选择信息增益最大的特征时其实选择的就是对应条件熵 H ( D ∣ A ) H(D|A) H(D∣A)最小的特征 A A A,那么我们为什么还要多此一举的去计算信息增益呢,直接像CART算法中一样计算在特征A条件下的数据集的不确定性不就可以了吗?
基于基尼指数构造分类树的过程如下:
6.3 CART剪枝
CART剪枝算法是一个从下往上即从叶节点往根节点进行的算法,算法过程由两步构成:
- 生成候选子树序列:首先从生成算法产生的决策树 T 0 T_{0} T0底端开始不断剪枝,直到 T 0 T_{0} T0的根节点,形成一个子树序列 { T 0 , T 1 , ⋯ , T n } \{T_{0},T_{1},\cdots,T_{n}\} {T0,T1,⋯,Tn};
- 通过验证集选择最优子树:然后通过交叉验证法在独立的验证集上对子树序列进行验证,从中选择出最优子树(比如根据准确率)
首先来说如何生成待选子树序列。CART剪枝同样是基于极小化损失函数来进行的,在给定 α \alpha α值时,子树的损失函数为:
C α ( T ) = C ( T ) + α ∣ T ∣ C_{\alpha}(T)=C(T)+\alpha|T| Cα(T)=C(T)+α∣T∣
这和ID3以及C4.5算法中的剪枝过程中所用的损失函数是一样的,所以每一项的含义不再赘述,只重点阐述一下CART算法中的 α \alpha α值的选择过程以及当前最有子树的选择过程。
具体来说,当我们从整体树 T 0 T_{0} T0开始剪枝时,对 T 0 T_{0} T0的任意一个内部节点 t t t,我们定义:
- 以 t t t为单节点树(即 t t t的所有后代节点全部回缩到节点 t t t)的损失函数为: C α ( t ) = C ( t ) + α C_{\alpha}(t)=C(t)+\alpha Cα(t)=C(t)+α
- 以 t t 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∣
则随着 α \alpha α值的变化,有如下规律:
- 当 α = 0 \alpha=0 α=0时,显然有:
C α ( t ) ≥ C α ( T t ) C_{\alpha}(t) \geq C_{\alpha}(T_{t}) Cα(t)≥Cα(Tt)
- 当 α \alpha α持续增大到某个值时,有:
C α ( t ) = C α ( T t ) C_{\alpha}(t) = C_{\alpha}(T_{t}) Cα(t)=Cα(Tt)
可解得此时有:
α = C ( t ) − C ( T t ) ∣ T t ∣ − 1 \alpha=\frac{C(t)-C(T_{t})}{|T_{t}|-1} α=∣Tt∣−1C(t)−C(Tt)
- 当 α \alpha α值继续增大,则有
C α ( t ) ≤ C α ( T t ) C_{\alpha}(t) \leq C_{\alpha}(T_{t}) Cα(t)≤Cα(Tt)
显然,当 C α ( t ) ≤ C α ( T t ) C_{\alpha}(t)\leq C_{\alpha}(T_{t}) Cα(t)≤Cα(Tt)时,剪枝后的损失更小且节点数更少,则应该剪枝。
因此,我们需要对当前树的所有非叶结点的内部节点 t t t,计算
g ( t ) = C ( t ) − C ( T t ) ∣ T t ∣ − 1 g(t)=\frac{C(t)-C(T_{t})}{|T_{t}|-1} g(t)=∣Tt∣−1C(t)−C(Tt)
这里的 g ( t ) g(t) g(t)有两个含义:
- 剪枝后整体损失函数的减小的程度,因为它是 C α ( t ) − C α ( T t ) C_{\alpha}(t)- C_{\alpha}(T_{t}) Cα(t)−Cα(Tt)的结果
- g ( t ) g(t) g(t)同样也是 α \alpha α的阈值,当 α ≤ g ( t ) \alpha \leq g(t) α≤g(t)时,对当前节点做剪枝会使得整体损失增大,当 α ≥ g ( t ) \alpha \geq g(t) α≥g(t)时,对当前节点做剪枝会使得整体损失减小。
选择所有节点中 g ( t ) g(t) g(t)值最小的节点对其进行剪枝,生成一个新的子树 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)的最优子树。
那么这里问题来了,为什么我们要选则最小 g ( t ) g(t) g(t)值对应的节点进行剪枝呢?根据上面总结的随着 α \alpha α值的变化剪枝与不剪枝的损失函数值的变化规律我们可以知道,当我们对每个节点计算 g t g_{t} gt值并取 α \alpha α值为其中的最小值时的某个区间时,剪去最小值对应的节点整体损失值不变或减小,但减去其他节点则整体损失值会增大,这时剪去最小的 g ( t ) g(t) g(t)值对应的节点是最优的,而其他节点不能被剪。即当 α \alpha α从零开始逐渐增大时,在某个区间总能找到树中只有一个节点该剪其他节点不该剪的情况。剪枝的过程就可以描述为,逐渐增大 α \alpha α,当只有一棵子树可以被剪时,则剪去这棵子树,得到当前$\alpha 对 应 的 最 优 子 树 , 再 对 这 棵 子 树 逐 渐 增 大 对应的最优子树,再对这棵子树逐渐增大 对应的最优子树,再对这棵子树逐渐增大\alpha$进行新的剪枝,最终得到我们需要的候选子树序列。
另一个问题是,CART剪枝算法中如何保证 α \alpha α会逐渐增大呢?其实这一点很好验证,如果我们当前子树进行了剪枝,则只有被剪节点的祖先节点的 g ( t ) g(t) g(t)值会发生变化,至于如何变化呢,观察公式可以知道:计算被剪节点的祖先节点的 g ( t ) g(t) g(t)值时, C ( t ) C(t) C(t)不变, C ( T t ) C(T_{t}) C(Tt)不变或者减小(因为当前被剪节点的熵肯定减小或不变,而其他兄弟节点的熵保持不变), ∣ T t ∣ |T_{t}| ∣Tt∣值减小,则最终被剪节点的所有祖先节点的 g ( t ) g(t) g(t)必定不变或者增大,这也证明了在进行一次剪枝后,得到的新子树中所有非叶内部节点的最小 g ( t ) g(t) g(t)值是递增的,而不会减小。随着 α \alpha α的递增,我们每次都能选出一棵子树被剪,最终就可以生成子树序列用于选择。
CART剪枝的具体流程如下: