本文总结决策树。知识点包含:决策树概述、ID3、C4.5、CART回归和分类、信息熵、Gini系数、决策树剪枝。
决策树概述
从根节点开始,对实例某一特征进行测试,根据结果将其分配到子节点。即产生一个决策函数。然后从所有子接点开始,一直迭代,直到达到叶节点。这就是决策树的基本形式。如西瓜书里面的决策树示例图:
决策树是一个概率模型
每一条从根节点到子节点的路径就是一连串的决策函数,他们共同构成的复合函数定义了一条规则。这个规则是完备的。可能有些小伙伴不清楚完备是啥意思,人话就是:每一个实例都会在一条路径上,且只能在一条路径上。
如果我们把特征空间画出来,会发现那些路径上的决策函数把特征空间划分为一个个互不相交的超矩形。每一个单元格就代表一条路径,如果我们把所分类的条件概率定义为该矩形的概率,则定义了一个条件概率分布。故决策树也是一种概率模型。
决策树的学习过程
决策树的学习本质上就是从训练集中归纳出一组分类规则。与训练集不矛盾的决策树可能不存在,也可能存在多个。我们希望得到
E
i
n
、
E
o
u
t
E_{in}、E_{out}
Ein、Eout均较小的树。
决策树的损失函数通常为正则化的极大似然函数。我们只需要以损失函数为目标函数,并极小化,从而选择最优决策树。
由于从所有可能的决策树中选择最优是一个NP问题,一般我们通过启发式方法来近似求解。得到一个次最优决策函数。
算法:
- 从根节点开始,选择一个最优特征,然后将所有数据分类成子集,并将子集作为一个子节点。
- 如果子节点中的类都分类正确,就将此节点作为叶子结点。
- 如果不能都被分类正确,则选择剩余特征中的最优特征,分类,判断。一直迭代直到所有数据分类正确或者遍历了所有的特征。
- 上述步骤获得的决策树往往对训练集有很好的分类能力,但是泛化能力差。我们需要对其剪枝。具体做法就是减掉一些对于提升模型能力差的叶节点,并将数据子集回缩到父节点。
综上,决策树主要包含三步骤:特征选择、决策树的生成和剪枝。
决策树的生成只考虑当前局部最优,剪枝考虑全局最优。
决策树优缺点:
特征选择的常用准则
决策树进程的第一步就是选择最优特征。我们希望每一次选择特征并生成树,都能尽可能提高分类的准确率,即都能降低子节点中样本标签的不纯度。这样我们可以得到一个次最优的树。通常我们有三个常用准则来辅助选择:信息增益、信息增益比、基尼系数。
https://www.cnblogs.com/wxquare/p/5379970.html
信息增益
熵:表示随机变量不确定性的度量
设X是一个取有限值的随机变量,对应的概率分布为
P
(
X
=
x
i
)
=
p
i
P(X=x_i)=p_i
P(X=xi)=pi,则熵定义为
H
(
X
)
=
−
∑
i
p
i
log
p
i
H(X)=-\sum_ip_i\log p_i
H(X)=−i∑pilogpi
若
p
i
=
0
p_i=0
pi=0,定义
0
log
0
=
0
0\log0=0
0log0=0。由式子可知熵具有性质:
- 至于分布有关,与X的取值无关。可将X的熵记为 H ( p ) H(p) H(p)
- 熵越大,随机变量的不确定性越大
- 0 ≤ H ( p ) ≤ log n 0\leq H(p)\leq\log n 0≤H(p)≤logn。 ( H ( p ) = log ∏ i p i − p i (H(p)=\log \prod_i p_i^{-p_i} (H(p)=log∏ipi−pi为凸函数,值最大时当且仅对当 ∀ i , j , p i = p j \forall i,j,p_i=p_j ∀i,j,pi=pj)。从这里可知当熵最大时,是一个均匀分布,随机变量各个值的概率一样大,这时数据无偏向某一个可能值的倾向,不确定性最大。如随机变量是二值分布,则此时的概率是0.5。
条件熵
在随机变量X给定的条件下随机变量Y的条件熵
H
(
Y
∣
X
)
H(Y|X)
H(Y∣X)定义为X给定条件下Y的条件概率分布的熵对X的数学期望。表示已知条件下Y的不确定性。公式如下:
H
(
Y
∣
X
)
=
∑
i
p
i
H
(
Y
∣
X
=
x
i
)
,
p
i
=
P
(
X
=
x
i
)
H(Y|X)=\sum_ip_iH(Y|X=x_i)\ ,p_i=P( X=x_i)
H(Y∣X)=i∑piH(Y∣X=xi) ,pi=P(X=xi)
信息增益
信息增益:得知特征X的信息而使得类Y的信息不确定性减少的程度。
特征A对数据集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)
熵和条件熵的差也称为互信息。
对于数据集D有K个分类
C
k
C_k
Ck和特征A,信息增益计算如下:
H
(
D
)
=
−
∑
k
∣
C
k
∣
∣
D
∣
log
∣
C
k
∣
∣
D
∣
H(D)=-\sum_k\frac{|C_k|}{|D|}\log\frac{|C_k|}{|D|}
H(D)=−k∑∣D∣∣Ck∣log∣D∣∣Ck∣
H
(
D
∣
A
)
=
∑
i
∣
D
i
∣
∣
D
∣
H
(
D
i
)
=
−
∑
i
∣
D
i
∣
∣
D
∣
∑
k
∣
C
i
k
∣
∣
D
i
∣
log
∣
C
i
k
∣
∣
D
i
∣
H(D|A)=\sum_i\frac{|D_i|}{|D|}H(D_i)=-\sum_i\frac{|D_i|}{|D|}\sum_k\frac{|C_{ik}|}{|D_i|}\log\frac{|C_{ik}|}{|D_i|}
H(D∣A)=i∑∣D∣∣Di∣H(Di)=−i∑∣D∣∣Di∣k∑∣Di∣∣Cik∣log∣Di∣∣Cik∣
g
(
D
,
A
)
=
H
(
D
)
−
H
(
D
∣
A
)
g(D,A)=H(D)-H(D|A)
g(D,A)=H(D)−H(D∣A)
信息增益比
信息增益值的大小受到数据集影响,并无实际意义。如果数据集的熵大,则信息增益一般都较大;反之较小。故我们希望使用比值——信息增益比。公式如下:
g
R
(
D
,
A
)
=
H
(
D
∣
A
)
H
(
D
)
g_R(D,A)=\frac{H(D|A)}{H(D)}
gR(D,A)=H(D)H(D∣A)
解决了信息增益量级不同的偏差影响。
基尼系数
基尼系数定义为:
G
i
n
i
(
p
)
=
∑
k
p
k
(
1
−
p
k
)
=
1
−
∑
k
p
k
2
Gini(p)=\sum_kp_k(1-p_k)=1-\sum_kp_k^2
Gini(p)=k∑pk(1−pk)=1−k∑pk2
计算如下:
G
i
n
i
(
D
)
=
1
−
∑
∣
C
k
∣
∣
D
∣
Gini(D)=1-\sum\frac{|C_k|}{|D|}
Gini(D)=1−∑∣D∣∣Ck∣
cart为二叉树,数据集被特征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)=∣D∣∣D1∣Gini(D1)+∣D∣∣D2∣Gini(D2)
具有性质:
- 只与数据集分布有关,与数据取值无关
- Gini系数越大,不确定性越大
- Gin系数和熵之半都可以近似表示分类误差。二分类问题中他们的关系如下图:
几个常用的树模型
上面我们已经介绍了特征选择,那我们就能生成树了。常用的分类树模型有:ID3、C4.5、CART分类树。除了特征选择不同、CART是二叉树外,他们的生成基本一致。故我只介绍一般流程。
输入:训练集、特征集A,阈值
ϵ
\epsilon
ϵ
输出:决策树T
- 若D中所有的样本实例都是同一类 C k C_k Ck,则T为单节点树,节点类别为 C k C_k Ck,返回T
- 若 A = ∅ A=\varnothing A=∅,则无其他特征可以选择,T为单节点树,把D中出现最多的类标记作为节点的类标记,返回T
- 否则,计算特征选择准则g(三种准则中的任一个都可以)。选择最优的特征 A g A_g Ag
- 若 g < ϵ g<\epsilon g<ϵ,则T为单节点树,把D中出现最多的类标记作为节点的类标记,返回T
- 否则,根据 A g A_g Ag的每一可能值把数据集划分为若干个非空子集 D i D_i Di,对每一个子集构建子节点,出现最多的类标记作为对应子节点的类标记,返回T。(cart是二叉树,在这里不同:再次计算 A g A_g Ag所有可能值的特征选择准则 g i g_i gi,选择出最优取值,划分为一个子集,其余的为另一个子集)
- 对每一个子节点,以 D i D_i Di为训练集、 A − A g A-{A_g} A−Ag为特征集,循环迭代1-5步。
- 如果是CART和C4.5还要剪枝。
ID3:
- 使用信息增益来选择特征
- 信息增益无绝对意义,往往特征值多的特征信息增益较大,增加了不确定性,偏向于选择此类特征作为最优特征
- 只有树的生成,无剪枝,容易过拟合。
- 不能对连续数据进行处理,可以对连续数据做离散化来解决
- 没有剪枝过程,容易过拟合
- 缺失值不容易处理
C4.5:
- 使用信息增益比来选择特征,准确率较ID3高
- 能处理连续数据
- 增加了剪枝,相对不容易过拟合
- 能自动处理缺失值的情形
- 生成树的过程中,需要对数据集进行多次的顺序扫描和排序,导致算法低效
- 需要把所有的数据都读入内存,不适合大量样本
CART分类:
-使用Gini系数来选择特征。 ID3、C4.5计算熵时都需要对数计算,计算慢、适合小样本。Gini系数只涉及到平方,运算速度相对快得多
- 非常灵活,允许错分样本、可以指定先验分布
- 能处理缺失值
- 能自动剪枝,不容易过拟合
三个模型的对比可以参考文章:
https://blog.youkuaiyun.com/choven_meng/article/details/82878018
https://blog.youkuaiyun.com/yoggieCDA/article/details/88998974
https://www.jianshu.com/p/80bc09e8e5e8
https://blog.youkuaiyun.com/u012328159/article/details/79413610
决策树的剪枝
决策树是一个概率模型,我们从朴素贝叶斯的那篇文章知经验最小化等于后验概率最大化。所以选择目标损失函数为最大似然函数,为了抑制过拟合,故需要对似然函数做惩罚。假设|T|为叶节点个数,则损失函数的公式如下:
C
α
(
T
)
=
∑
t
=
1
∣
T
∣
N
t
H
t
(
T
)
+
α
∣
T
∣
  
,
α
≥
0
C_\alpha(T)=\sum_{t=1}^{|T|}N_tH_t(T)+\alpha|T|\;,\alpha \geq0
Cα(T)=t=1∑∣T∣NtHt(T)+α∣T∣,α≥0
H
t
(
T
)
=
−
∑
k
N
t
k
N
t
log
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
)
=
∑
t
∑
k
N
t
k
log
N
t
k
N
t
-C(T)=-\sum_{t=1}^{|T|}N_tH_t(T)=\sum_t\sum_kN_{tk}\log\frac{N_{tk}}{N_t}
−C(T)=−t=1∑∣T∣NtHt(T)=t∑k∑NtklogNtNtk
=
∑
t
∑
k
log
(
N
t
k
N
t
)
N
t
k
=\sum_t\sum_k\log(\frac{N_{tk}}{N_t})^{N_{tk}}
=t∑k∑log(NtNtk)Ntk
=
log
(
∏
t
∏
k
(
N
t
k
N
t
)
N
t
k
)
=\log(\prod_t\prod_k(\frac{N_{tk}}{N_t})^{N_{tk}})
=log(t∏k∏(NtNtk)Ntk)
这就是极大似然函数,意义即要求每一个节点内分类正确的概率最大,然后要求树的整体分类正确概率最大。也符合了决策树先生存后剪枝的顺序。
C
(
T
)
C(T)
C(T)代表了模型的拟合度,
∣
T
∣
|T|
∣T∣代表了树的模型复杂度,
α
\alpha
α就是调节因子。
剪枝算法流程:
- 计算每个节点的经验熵
- 递归地回缩到父节点,如果某个点回缩后的损失函数未出现增大,则剪枝,蒋父节点作为叶子结点。
- 迭代,直到不能减小或者我们满意为止。
剪枝分为预剪枝和后剪枝。
预剪枝:是在树的每一次生成时都要验证一下能否减小损失函数。如果能减小就绩效生成子节点。如果不能则不分裂。
- 有很多分支没有散开,降低了过拟合的风险、降低了时间和内存空间的开销
- 当前节点不能增加泛化能力,但是后续很可能增加泛化能力。例如最开始的那几层的节点,很可能某一个节点不能增加泛化能力,但是他之后的节点却能很好的提升泛化能力。增加了欠拟合的风险。
后剪枝:树尽可能的生成。然后从叶节点开始,一步一步的往回缩、验证、判断是否剪枝。
- 先生成一个完整的树再剪枝增加了时间和空间成本
- 通常留下的节点和分支都比预剪枝多,欠拟合风险很小。
参考文章
预剪枝和后剪枝的具体例子
理解损失函数是极大似然法参考文章1
理解损失函数是极大似然法参考文章2
CART回归树
CART不仅能做分类,还能做回归!树怎么能做回归呢?是不是写错了。你没看错,树能做回归。
如果目标Y是连续变量,D为给定数据集。假设特征空间被树划分为M个单元,每个单元上只有一个输出值
c
m
c_m
cm。则树模型表示为
f
(
x
)
=
c
m
∑
I
(
x
∈
R
)
f(x)=c_m\sum I(x\in R)
f(x)=cm∑I(x∈R)
如果每个空间单元如果小,
c
m
c_m
cm就是对应空间上y的近似。通常我们可以用空间单元上的Y值的平均值来近似代替
c
m
c_m
cm。
最小二乘回归树
我们希望单元上的点都离这个点足够近,当划分确定时,我们可以用平方误差来
∑
(
y
i
−
f
(
x
i
)
)
2
\sum(y_i-f(x_i))^2
∑(yi−f(xi))2作为回归树的目标函数。通过这个目标函数也可知,空间单元上的输出可以的最优值是空间单元上的所有
y
i
y_i
yi的平均值。
最小二乘回归树采用启发式的方法来划分空间。
- 选择特征遍历 x ( j ) x^{(j)} x(j)及其值s。构造两个区域 R 1 ( j , s ) = { x ∣ x ≤ s }      R 2 ( j , s ) = { x ∣ x > s } R_1(j,s)=\{x|x\leq s\}\;\;R_2(j,s)=\{x|x> s\} R1(j,s)={x∣x≤s}R2(j,s)={x∣x>s}
- 求解最优化问题,得到最优对(j,s) min j , s { min c 1 ∑ x i ∈ R 1 ( y i − c i ) 2 + min c 1 ∑ x i ∈ R 2 ( y i − c i ) 2 } \min_{j,s}\{\min_{c_1}\sum_{x_i\in R_1}(y_i-c_i)^2+\min_{c_1}\sum_{x_i\in R_2}(y_i-c_i)^2\} j,smin{c1minxi∈R1∑(yi−ci)2+c1minxi∈R2∑(yi−ci)2}
- 以上两步和cart分类树的特征选择是相似的。记下来就是迭代,剪枝了。
CART的剪枝
CART的剪枝的剪枝算法:
- 从决策树的底端开始对树进行剪枝,直到跟节点。得到一子树序列。
- 通过在验证集上进行交叉验证,选择最优子树。
具体的做法之一:将
α
\alpha
α从0开始逐渐增大,从
T
0
T_0
T0开始剪枝。若t为树上的任一节点,则以t为单节点的子树的损失函数为
C
α
(
t
)
=
C
(
t
)
+
α
C_\alpha(t)=C(t)+\alpha
Cα(t)=C(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∣
当
α
=
0
\alpha=0
α=0或者足够小时,
C
α
(
T
t
)
<
C
α
(
t
)
C_\alpha(T_t)< C_\alpha(t)
Cα(Tt)<Cα(t)
当
α
\alpha
α足够大时,
C
α
(
T
t
)
>
C
α
(
t
)
C_\alpha(T_t)> C_\alpha(t)
Cα(Tt)>Cα(t)
故存在某个
α
\alpha
α,s.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
\Longrightarrow \alpha=\frac{C(t)-C_\alpha(T_t)}{|T_t|-1}
⟹α=∣Tt∣−1C(t)−Cα(Tt)
故我们只需要对每一个节点计算
g
(
t
)
=
C
(
t
)
−
C
α
(
T
t
)
∣
T
t
∣
−
1
g(t)=\frac{C(t)-C_\alpha(T_t)}{|T_t|-1}
g(t)=∣Tt∣−1C(t)−Cα(Tt)代表了剪枝后损失函数的减少程度。每次都减去g(t)最小的子树
T
t
T_t
Tt,把得到的子树作为
T
1
T_1
T1。迭代之后得到一个嵌套的子树序列。之后再次交叉验证选出最优子树。
参考书籍:《统计学习》——李航