决策树有多种可选的形态,那么如何确定哪种决策树是更好的呢?有两种指标可以使用:
基尼系数是一种评估决策树好坏的指标。他反映了决策树对样本分类的离散情况。假设样本集合为T,分为了若干个类别,每个类别在样本集合T中占的比例为
p
i
p_i
pi。它的计算公式如下:
gini
(
T
)
=
1
−
∑
p
i
2
\operatorname{gini}(T)=1-\sum p_{i}^{2}
gini(T)=1−∑pi2
举个例子,假设某个员工的样本集合里都是离职员工,所以该集合只有"离职员工"一个类别,其出现的频率是100%。所以该系统的基尼系数为 1 − 1 2 = 0 1-1^2=0 1−12=0,表示该系统没有混乱,或者说该系统的“纯度”很高。而如果样本中一半是离职员工,另一半是未离职员工,那么类别个数为2,每个类别出现的频率都为50%,所以其基尼系数为 1 − ( 0. 5 2 + 0. 5 2 ) = 0.5 1-(0.5^2+0.5^2)=0.5 1−(0.52+0.52)=0.5,其混乱程度很高。
如何理解这个公式的含义?我们举个例子,假设有个贷款人员的样本集合,有贷款人员是否违约的二分类问题,1表示违约,0表示不违约。现在问:任取两个样本,它们属于同一类别的概率是多少?两个样本同属第一个类别的概率为
P
1
=
p
1
2
P_1=p_1^2
P1=p12,同属第二个类别的概率为
P
2
=
p
2
2
P_2=p_2^2
P2=p22。所以,两个样本同属一个类别的概率如下:
P
r
(
P
1
∪
P
2
)
=
P
r
(
P
1
)
+
P
r
(
P
2
)
−
P
r
(
P
1
∩
P
2
)
=
P
r
(
P
1
)
+
P
r
(
P
2
)
两个样本不可能同时都属于多个类别
=
p
1
2
+
p
2
2
所以,两个样本不属于同一类别的概率为
1
−
P
r
(
P
1
∪
P
2
)
=
1
−
p
1
2
−
p
2
2
=
g
i
n
i
(
T
)
1-Pr(P_1 \cup P_2)=1-p_1^2-p_2^2=gini(T)
1−Pr(P1∪P2)=1−p12−p22=gini(T)。在二分类问题中,基尼系数的含义就是随机采样的两个样本不属于同一类别的概率。
该说法在多分类问题中一样成立。参考【概率论】1-4:事件的的并集(Union of Events and Statical Swindles)给出的公式:

图中的并集元素项都等于0,所以任取两个样本,都属于同一类别的概率为
Pr
(
⋃
i
=
1
n
A
i
)
=
∑
i
=
1
n
Pr
(
A
i
)
=
∑
i
=
1
n
p
i
2
\operatorname{Pr}\left(\bigcup_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{A}_{\mathrm{i}}\right)=\sum_{\mathrm{i}=1}^{\mathrm{n}} \operatorname{Pr}\left(\mathrm{A}_{\mathrm{i}}\right)=\sum_{\mathrm{i}=1}^{\mathrm{n}}p_i^2
Pr(⋃i=1nAi)=∑i=1nPr(Ai)=∑i=1npi2。所以任取两个样本,不属于同一类别的概率为
1
−
∑
i
=
1
n
p
i
2
1-\sum_{\mathrm{i}=1}^{\mathrm{n}}p_i^2
1−∑i=1npi2,该说法得证。在多分类问题中,基尼系数的含义也是同样的。
当引入某个用于划分样本空间的条件(如“满意度<5”)时,分类后的基尼系数公式如下,其中S1、S2为划分后的两类各自的样本量, g i n i ( T 1 ) gini(T_1) gini(T1)、 g i n i ( T 2 ) gini(T_2) gini(T2)为两类各自的基尼系数。
gini ( T ) = S 1 S 1 + S 2 gini ( T 1 ) + S 2 S 1 + S 2 gini ( T 2 ) \operatorname{gini}(T)=\frac{S_{1}}{S_{1}+S_{2}} \operatorname{gini}\left(T_{1}\right)+\frac{S_{2}}{S_{1}+S_{2}} \operatorname{gini}\left(T_{2}\right) gini(T)=S1+S2S1gini(T1)+S1+S2S2gini(T2)
举个例子,一个初始样本中有1000个员工,其中已知有400人离职,600人不离职,划分前该系统的基尼系数为
1
−
(
0.
4
2
+
0.
6
2
)
=
0.48
1-(0.4^2+0.6^2)=0.48
1−(0.42+0.62)=0.48。
下面采用两种方式决定根节点:一是根据“满意度<5”进行分类;二是根据“收入<10000元”进行分类。
划分方式1:以“满意度<5”为根节点进行划分,如下图所示,1000个员工中,200个人是满意度<5的,另外有800个人满意度>=5。计算过程如下。

划分方式2:以“收入<10000元”为根节点进行划分,如下图所示,1000个员工中,有400个人收入小于10000元,另外600人收入>=10000元计算过程如下。

T1的基尼系数:
g
i
n
i
(
T
1
)
=
1
−
(
0.2
5
2
+
0.7
5
2
)
=
0.375
gini(T1)=1-(0.25^2+0.75^2)=0.375
gini(T1)=1−(0.252+0.752)=0.375
T2的基尼系数:
g
i
n
i
(
T
2
)
=
1
−
(
0.
5
2
+
0.
5
2
)
=
0.5
gini(T2)=1-(0.5^2+0.5^2)=0.5
gini(T2)=1−(0.52+0.52)=0.5
可以看到,划分前的基尼系数为0.48,以“满意度<5”为根节点进行划分后的基尼系数为0.3,而以“收入<10000元”为根节点进行划分后的基尼系数为0.45。基尼系数越低表示系统的混乱程度越低(纯度越高),区分度越高,越适合用于分类预测,因此这里选择“满意度<5”作为根节点。
如何理解划分后的基尼系数公式?在划分前,样本空间是全集。划分将决策树的分为了若干个树节点,每个树节点相当于一个样本空间子集。所以公式中将各个划分样本计算基尼系数后,按权重相加的方式,相当于计算每个划分样本空间基尼系数的加权和。
这里建议阅读原文决策树模型及案例(Python),对某个样本空间X计算信息熵的公式为:
H
(
X
)
=
−
∑
p
i
log
2
(
p
i
)
(
i
=
1
,
2
…
…
n
)
H(X)=-\sum p_{i} \log _{2}\left(p_{i}\right) \quad\left(i=1,2 \ldots \ldots{ }{\text n}\right)
H(X)=−∑pilog2(pi)(i=1,2……n)
进行某种变量A划分后(比如“满意度<5”),信息熵的计算公式如下。则根据变量A划分后的信息熵又称为条件熵。
H
A
(
X
)
=
S
1
S
1
+
S
2
H
(
X
1
)
+
S
2
S
1
+
S
2
H
(
X
2
)
H_{A}(X)=\frac{S_{1}}{S_{1}+S_{2}} H\left(X_{1}\right)+\frac{S_{2}}{S_{1}+S_{2}} H\left(X_{2}\right)
HA(X)=S1+S2S1H(X1)+S1+S2S2H(X2)
什么是信息增益?为了衡量不同划分方式降低信息熵的效果,还需要计算分类后信息熵的减少值(原系统的信息熵与分类后系统的信息熵之差),该减少值称为熵增益或信息增益,其值越大,说明分类后的系统混乱程度越低,即分类越准确。
假设某样本的初始信息熵为 H ( X ) = 0.97 H(X)=0.97 H(X)=0.97。
有从需求出发解释的,Intuitive explanation of entropy回答者认为,这是为了定义一种指标,能否符合给定的需要,最终选中了对数函数。
有从事件的意外性(suprise值)与信息含量解释的,越低发生的事件通常包含越高的信息量,反之亦然。但这种解释只能是抽象的,并不严格。
我的理解是,在通信场景中,你需要为各种符号(A、B、C等等符号)作编码,通常使用二进制编码。各种符号的出现频率不一样,有的符号出现频繁,其它的符号出现得较少。为了让总编码数较低,你可以为出现频繁的符号分配较少的编码,再为出现稀少的符号分配较多的编码,就可以达到更少的平均编码长度。
那么最优编码时,根据6.信息论(一):信息量、熵和最优编码:
经过上面的证明可知,小明只需要用前缀编码,且码长满足 l o g r 1 p i log_r{\frac{1}{pi}} logrpi1便可获得最优的编码长度。
可知,某符号的最优编码长度其实就是suprise值,而他们的概率加权和=最优平均编码长度=信息熵的公式。
基尼系数涉及平方运算,而信息熵涉及相对复杂的对数函数运算,因此,目前决策树模型默认使用基尼系数作为建树依据,运算速度会较快。
有一些常见的策略,可以用来生成决策树,比如ID3, c4.5 and CART。接下来本章会逐个介绍这三个算法。
ID3是相对容易理解的策略,它使用信息熵来衡量决策树的划分好坏,并根据信息增益来找出最佳的划分方式。ID3全称为Iterative Dichotomiser 3,翻译成中文就是"迭代二叉树第3代",可见这个算法是有迭代过程的。那么读者可以思考:
本节总结自 决策树算法–ID3算法。
首先了解该迭代算法的定义。假设有一个数据集D,包含了若干样本,每个样本有若干个属性 { A , B , C . . . } \left\{ A,B,C... \right\} {A,B,C...},以及标签值。那么,我们首先能计算出数据集D的信息熵 E n t r o p y ( D ) Entropy(D) Entropy(D)。
接下来,我们要尝试从所有属性中找出一个属性,对数据集D作划分,并选择能带来最大信息增益的那个属性。
我们先看向属性A(A有k个值,
[
a
1
,
a
2
,
.
.
.
,
a
k
]
[a_1, a_2, ..., a_k]
[a1,a2,...,ak]),属性A能将数据集D划分为若干个子集,我们去计算划分后的信息增益:
g
a
i
n
(
D
∣
A
)
=
E
n
t
r
o
p
y
(
D
)
−
E
n
t
r
o
p
y
(
D
∣
A
)
gain(D|A)=Entropy(D)-Entropy(D|A)
gain(D∣A)=Entropy(D)−Entropy(D∣A)
这样,就能知道使用属性A划分数据集能够降低多少信息熵,减少"不确定性"。依次所有属性的信息增益
g
a
i
n
(
D
∣
A
)
,
g
a
i
n
(
D
∣
B
)
,
.
.
.
gain(D|A),gain(D|B),...
gain(D∣A),gain(D∣B),...然后选择最大值的那个属性,便是这轮迭代的划分最优选。
然后,对每个子集继续迭代,直到没有特征选择,或者标签完全一样了为止,这边是迭代的终止条件了。
用更结构化的语言来描述算法
接下来用示例进一步解释ID3算法。假设数据集有一批西瓜样本,每个西瓜有属性{色泽, 根蒂, 敲声, …},标签为"好瓜"(取值是或否)。如下图所示,分割线上半部分的样本,其标签"好瓜"都为是,分割线下半部分的样本,其标签"好瓜"都为否。

正例(好瓜)占 8/17,反例占 9/17 ,根结点的信息熵为。
Ent
(
D
)
=
−
∑
k
=
1
2
p
k
log
2
p
k
=
−
(
8
17
log
2
8
17
+
9
17
log
2
9
17
)
=
0.998
\operatorname{Ent}(D)=-\sum_{k=1}^{2} p_{k} \log _{2} p_{k}=-\left(\frac{8}{17} \log _{2} \frac{8}{17}+\frac{9}{17} \log _{2} \frac{9}{17}\right)=0.998
Ent(D)=−k=1∑2pklog2pk=−(178log2178+179log2179)=0.998
接下来,计算当前属性集合{色泽,根蒂,敲声,纹理,脐部,触感}中每个属性的信息增益。
先选择色泽属性计算信息增益。色泽有3个可能的取值:{青绿,乌黑,浅白}
3 个分支结点的信息熵
Ent
(
D
1
)
=
−
(
3
6
log
2
3
6
+
3
6
log
2
3
6
)
=
1.000
Ent
(
D
2
)
=
−
(
4
6
log
2
4
6
+
2
6
log
2
2
6
)
=
0.918
Ent
(
D
3
)
=
−
(
1
5
log
2
1
5
+
4
5
log
2
4
5
)
=
0.722
那么我们可以知道属性色泽的信息增益是:
Gain
(
D
,
色泽
)
=
Ent
(
D
)
−
∑
v
=
1
3
∣
D
v
∣
∣
D
∣
Ent
(
D
v
)
=
0.998
−
(
6
17
×
1.000
+
6
17
×
0.918
+
5
17
×
0.722
)
=
0.109.
同理,我们可以求出其它属性的信息增益,分别如下:
Gain
(
D
,
根蒂
)
=
0.143
;
Gain
(
D
,
敲声
)
=
0.141
;
Gain
(
D
,
纹理
)
=
0.381
;
Gain
(
D
,
脐部
)
=
0.289
;
Gain
(
D
,
触感
)
=
0.006.
于是我们找到了信息增益最大的属性纹理,它的Gain(D,纹理) = 0.381最大。
于是我们选择的划分属性为“纹理”,根据"纹理"可以将原数据集划分为3个子集,如图,根节点下有三个子结点:

对于这三个子节点,我们可以递归的使用刚刚找信息增益最大的方法进行选择特征属性,
比如对于第一个子节点,D1(纹理=清晰) = {1, 2, 3, 4, 5, 6, 8, 10, 15},第一个分支结点可用属性集合{色泽、根蒂、敲声、脐部、触感},基于 D1各属性的信息增益,分别求得如下:
Gain
(
D
1
, 色泽
)
=
0.043
;
Gain
(
D
1
, 根蒂
)
=
0.458
;
Gain
(
D
1
, 敲声
)
=
0.331
;
Gain
(
D
1
, 脐部
)
=
0.458
;
Gain
(
D
1
, 触感
)
=
0.458.
其中根蒂,脐部,触感三个特征属性的信息增益相等并且最大,于是我们可以选择其中的任意一个。
其它俩个子结点同理,然后得到新一层的结点,再递归的由信息增益进行构建树即可
我们最终的决策树如下:

从上面求解信息增益的公式中,其实可以看出,信息增益准则其实是对可取值数目较多的属性有所偏好。
什么意思呢?假如我们把数据集中的“编号”也作为一个候选划分属性。我们可以算出“编号”的信息增益是0.998。因为每一个样本的编号都是不同的,信息熵为0。也就是说,来了一个预测样本,你只要告诉我编号,其它特征就没有用了,这样生成的决策树显然不具有泛化能力。
于是,我们就引入了信息增益率来选择最优划分属性,接下来要介绍C4.5算法了。
这次我们每次进行选取特征属性的时候,不仅会考虑ID3算法的信息增益,还会考虑信息增益率这个指标。
先看信息增益率的公式如下。可以看出,信息增益率=信息增益/IV(a),其中IV(a)称为属性a的固定值。
Gain
ratio
(
D
,
a
)
=
Gain
(
D
,
a
)
IV
(
a
)
\operatorname{Gain} \operatorname{ratio}(D, a)=\frac{\operatorname{Gain}(D, a)}{\operatorname{IV}(a)}
Gainratio(D,a)=IV(a)Gain(D,a)
而固定值的公式如下,该特征的形式和信息熵相似,所以读者可将其视作“特征熵”。
IV
(
a
)
=
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
log
2
∣
D
v
∣
∣
D
∣
\operatorname{IV}(a)=-\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \log _{2} \frac{\left|D^{v}\right|}{|D|}
IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
这个函数的递增性有如下特点:
举个例子,在上文的西瓜样本案例中,三种属性的固定值分别如下:
可以看出,属性"编号"会将集合划分成很多个子集,其特征熵很大。而属性"触感"只是将集合划分为两份,其特征熵很小。由此读者能感受到,当选取该属性时,分成的V类别数越大,IV(a)就越大。
信息增益率指标受到固定值的影响,会对可取值较少的特征有所偏好,而这在一定程度上会削减对增益率的偏好。比如某种属性的增益率较低,但它的固定值也很小,使其在增益率排序中靠前,从而被选中。我们虽然会关注固定值,但不应该过于关注它。虽然你可以引入超参数权重,去平衡两者的影响,但实际上你难以确定权重多大才合适。
所以,C4.5并不会直接选择信息增益率最高的属性,而是使用一个启发式方法:先从候选划分特征中找到信息增益高于平均值的特征,这样保证好的特征被选中。再从中选择增益率最高的。这样避免出现编号特征这种极端的情况。
C4.5规避了ID3的一些缺点,但自己也并不是完美的。
本节参考决策树学习笔记、决策树-CART回归树、决策树(上)-ID3、C4.5、CART、决策树算法–CART分类树算法
ID3 和 C4.5 虽然在对训练样本集的学习中可以尽可能多地挖掘信息,但是其生成的决策树分支、规模都比较大。相比之下,CART算法能规避这些缺点:
在学习CART前,请记住以下几个关键点:
CART分类树的算法步骤与前两者类似。算法从根节点开始,用训练集递归建立CART分类树。然后迭代完成以下步骤:
对生成的CART分类树做预测时,假如测试集里的样本落到了某个叶子节点,而该节点里有多个训练样本。则该测试样本的类别为这个叶子节点里概率最大的类别。
CART树使用基尼系数类评估划分的好坏,基尼系数作为一种评价指标,在上一章已经阐述过原理,这里再列出一次公式。基尼指数反映的是从样本集D中随机抽取两个样本,其类别标记不一致的概率,因此Gini(D)越小越好。
Gini
(
D
)
=
∑
k
=
1
∣
Y
∣
∑
k
′
≠
k
p
k
p
k
′
=
1
−
∑
k
=
1
∣
Y
∣
p
k
2
进而,使用属性α划分后的基尼指数如下公式,意思是各个子集基尼系数的加权和。
GiniIndex
(
D
,
a
)
=
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
Gini
(
D
v
)
\text { GiniIndex }(D, a)=\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \operatorname{Gini}\left(D^{v}\right)
GiniIndex (D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
下面我们举例来进一步说明分类树的步骤。

在上述图中,共10条数据,拖欠贷款者属于"标签",是离散值。而属性有3个,分别是:
那么,对于这些属性该如何进行Gini系数的计算以及划分呢?
首先来看有房情况这个属性,因为该属性只有“是”“否”两种取值,所以其Gini系数比较容易计算,那么按照它划分后的Gini指数计算如下:

接下来对婚姻状况进行计算,我们发现婚姻状况一共有三种取值:单身、已婚、离异,又因为Cart分类树只能是二叉树,所以我们只能对多种取值的属性进行组合。

最后对年收入属性进行计算。年收入属性为连续值,Cart分类树又是如何对连续值属性进行处理的呢?
做法是:将连续特征离散化,假设 n 个样本的连续特征 A 有 m 个取值,C4.5/Cart 将其排序并取相邻两样本值的平均数共 m-1 个划分点,分别计算以该划分点作为二元分类点时的信息增益/Gini系数,并选择信息增益最大/Gini系数最小的点作为该连续特征的二元离散分类点。
以下图为例

Cart分类树对于连续值的处理其实和C4.5算法对于连续值的处理类似,只不过Cart使用Gini指数,C4.5使用信息增益率
当构建回归树时,使用样本方差最小值作为评估指标。回归方差计算公式如下,样本方差公式应该是很熟悉的了,就是计算每个样本与平均值的平方,再求和。方差越大,表示该节点的数据越分散,预测的效果就越差。
S
S
=
σ
2
=
∑
i
∈
I
(
x
i
−
μ
)
2
=
∑
i
∈
I
x
i
−
n
μ
2
SS=\sigma^{2}=\sum_{i \in I}\left(x_{i}-\mu\right)^{2}=\sum_{i \in I} x_{i}-n \mu^{2}
SS=σ2=i∈I∑(xi−μ)2=i∈I∑xi−nμ2
那么如何计算某属性的划分增益呢?由根节点的方差和减去左右节点的方差和,公式如下。其中
S
S
T
=
∑
i
∈
I
(
x
i
−
μ
)
2
S S_{T}=\sum_{i \in I}\left(x_{i}-\mu\right)^{2}
SST=∑i∈I(xi−μ)2是根节点的方差和,
S
S
L
S S_{L}
SSL和
S
S
R
S S_{R}
SSR是左右节点的方差和。
Gain
=
S
S
T
−
(
S
S
L
+
S
S
R
)
\text { Gain }=S S_{T}-\left(S S_{L}+S S_{R}\right)
Gain =SST−(SSL+SSR)
举个例子,对于数据集如下,如何计算它的增益?
密度
含糖率
0.697
0.460
0.774
0.376
0.634
0.264
0.608
0.318
0.556
0.215
0.403
0.237
0.481
0.149
0.437
0.211
0.666
0.091
首先计算“含糖率”的方差和
S
S
T
S S_{T}
SST,然后依次选取“密度”各属性值作为分割点计算左右节点的方差和,当
G
a
i
n
Gain
Gain达到最大时,得到最优分割点。
通常情况下在依次分割中 S S T S S_{T} SST的值是固定的,所以只要找 S S L + S S R S S_{L}+S S_{R} SSL+SSR的最小值即可。
决策树节点停止分裂的一般性条件:
为了限制树的规模,可以使用剪枝策略。它分为预剪枝和后剪枝。
预剪枝就是在节点划分之前先进行估计,如果当前节点的划分不能带来决策树泛化性能的提升则停止划分并将当前节点标记为叶节点。
后剪枝是先从训练集中生成一颗完整的决策树,然后自底向上的对非叶节点进行考察,然后根据一定的规则决定是否应将该节点变为叶节点。后剪枝一般需要用到验证集。
有三种后剪枝算法,代价复杂度剪枝、代价复杂度剪枝、悲观剪枝。第一种较为经典,是在CART树中提出的。建议还是看原文决策树学习笔记的“3.2 后剪枝”一章
3种决策树的比较如下,可见CART树的能力是比较全面的,不仅支持连续值、缺失值、剪枝算法,还能构建分类树和回归树。

本文先讲解了决策树的评估指标,再循序渐进地介绍了3种决策树。对于每种决策树,不仅介绍了算法过程,还举例说明。本文每一章都引用了其它参考文献,并按照笔者的理解进行拼凑,以便读者更顺利地学习。虽然本文篇幅较长,实际上3种决策树的创新点并不很多,只要记住关键点就能理解。
其实算法面试基本不会考吧?可是反正我也失业了,就随着性子学知识吧。这辈子就这样了。