注:文本是学习完《统计学习方法》后的回顾总结,且决策树的思想都比较简单,因此本文只讲做法
一般来说,ID3与C4.5生成的决策树只用于分类,CART决策树则分类和回归问题都能使用
1. ID3算法
ID3算法中最关键的一点就是如何选择特征去划分子集:答案就是信息增益,具体如下:
-
计算划分之前,数据集D的熵H(D):
H ( D ) = − ∑ k = 1 K ∣ D k ∣ ∣ D ∣ l o g ∣ D k ∣ ∣ D ∣ , k 表 示 数 据 集 的 类 别 数 H(D)=-\sum_{k=1}^{K}\frac{|D_k|}{|D|}log\frac{|D_k|}{|D|},k表示数据集的类别数 H(D)=−k=1∑K∣D∣∣Dk∣log∣D∣∣Dk∣,k表示数据集的类别数 -
遍历所有特征,计算按该特征划分之后,数据集D的条件熵H(D|A):
H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H ( D i ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ ∑ k = 1 K ∣ D k ∣ ∣ D ∣ l o g ∣ D k ∣ ∣ D ∣ , n 表 示 特 征 A 不 同 的 取 值 数 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_k|}{|D|}log\frac{|D_k|}{|D|},n表示特征A不同的取值数 H(D∣A)=i=1∑n∣D∣∣Di∣H(Di)=−i=1∑n∣D∣∣Di∣k=1∑K∣D∣∣Dk∣log∣D∣∣Dk∣,n表示特征A不同的取值数 -
计算每个特征的信息增益,选择信息增益最大的特征作为分裂结点:
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)−H(D∣A)
注意,ID3算法生成的决策树不一定是二叉树
2. C4.5算法
在ID3算法中,用信息增益作为选择特征的依据,存在偏向于选择特征取值较多的特征的问题,因此在C4.5中,采用信息增益率对这一问题进行校正:其实质就是在信息增益的基础上,除以数据集关于所选特征的熵
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)
其他步骤与ID3算法一致,不再重复
3. ID3与C4.5算法的剪枝
在使用ID3算法或者C4.5算法生成了决策树后,往往利用剪枝简化树的结构以避免出现过拟合的现象。
那么如何衡量决策树在剪枝后是否表现得更好呢,我们定义了如下的损失函数:
C
α
(
T
)
=
∑
t
=
1
T
N
t
H
t
(
T
)
+
α
∣
T
∣
,
T
是
叶
节
点
的
数
量
,
N
t
是
第
t
个
叶
节
点
上
的
样
本
数
,
H
t
(
T
)
是
第
t
个
叶
节
点
的
熵
C_\alpha(T)=\sum_{t=1}^TN_tH_t(T)+\alpha|T|,\\T是叶节点的数量,N_t是第t个叶节点上的样本数,H_t(T)是第t个叶节点的熵
Cα(T)=t=1∑TNtHt(T)+α∣T∣,T是叶节点的数量,Nt是第t个叶节点上的样本数,Ht(T)是第t个叶节点的熵
其中,右边的第一部分表示决策树的预测误差,第二部分表示决策树的复杂度,
α
\alpha
α调整这两部分对最终损失的影响权重关系,当
α
\alpha
α较大时,模型对复杂度敏感,因此最终生成的决策树结构比较简单;当
α
\alpha
α比较小时,模型对复杂度不敏感,因此最终生成的决策树结构比较复杂。
因此,ID3与C4.5算法的剪枝操作非常简单,自底向上对每一个叶节点进行剪枝,若剪枝后,整棵树的损失降低了,则剪掉该叶节点;否则保留该叶节点。
值得注意的是,在ID3与C4.5算法的剪枝操作中, α \alpha α是提前指定的,这是与CART算法剪枝操作的一个区别。
4. CART算法
简单来说,CART算法即能基于平方误差最小化构造回归树,也能基于基尼指数最小化构造分类树,且注意CART算法生成的决策树一定是二叉树。
4.1 回归树
CART回归树选择平方误差最小的特征作为划分特征,将小于等于选择特征所选特征值的数据集划分为一类,将大于选择特征所选特征值的数据集划分为一类。具体算法过程如下:
4.2 分类树
CART分类树选择基尼指数最小的特征作为划分特征,将等于选择特征所选特征值的数据集划分为一类,将不等于选择特征所选特征值的数据集划分为一类。具体算法过程如下:
上述过程中提到的式5.25如下:
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)
其中,
G
i
n
i
(
D
)
=
∑
k
=
1
K
p
k
(
1
−
p
k
)
=
1
−
∑
k
=
1
K
(
∣
D
k
∣
∣
D
∣
)
2
,
对
于
二
分
类
问
题
,
G
i
n
i
(
D
)
=
2
p
(
1
−
p
)
Gini(D)=\sum_{k=1}^{K}p_k(1-p_k)=1-\sum_{k=1}^{K}(\frac{|D_k|}{|D|})^2,\\对于二分类问题,Gini(D)=2p(1-p)
Gini(D)=k=1∑Kpk(1−pk)=1−k=1∑K(∣D∣∣Dk∣)2,对于二分类问题,Gini(D)=2p(1−p)
综上所示,决策树有ID3,C4.5,CART三种生成算法:
- ID3,C4.5,CART都能生成分类树,采用各自的标准选择划分特征。当遇到连续型特征时,将其离散化后依旧用自己的标准去选择切分的值;当遇到离散型特征时,ID3和C4.5无需特殊处理,而CART算法则必须先对特征进行二值化
- CART也能生成回归树,对于连续型特征,采用平方误差最小选择划分特征;对于离散型特征,笔者暂时还没搞清楚,待补充。
5. CART的剪枝
这里的损失函数和ID3,C4.5算法的损失函数一致:
C
α
(
T
)
=
C
(
T
)
+
α
∣
T
∣
C_\alpha(T)=C(T)+\alpha|T|
Cα(T)=C(T)+α∣T∣
在进行下面的步骤之前,先引入一个前提:
对于一个固定的 α \alpha α,有且仅有一棵最优子树与其对应。
当 α \alpha α比较小时,模型对复杂度不敏感,因此最优子树的结构比较复杂;当 α \alpha α较大时,模型对复杂度敏感,因此该最优子树的结构比较简单。即是说,随着 α \alpha α的增大,最优子树的结构越来越简单,又由于对于一个固定的 α \alpha α,有且仅有一棵最优子树与其对应,因此可以简单地认为:**某些子树分支在 α \alpha α设置为某一特定值的时候,必须剪掉。**那么如何计算每个子树分支必须剪掉的时刻,对应的 α \alpha α值是多少呢?这个后文再提。
CART剪枝主要分为以下两步:
- 从决策树T0底端开始不断剪枝,直到T0的根节点,形成一个子树序列{T0,T1,…Tn}
- 通过在验证集上交叉验证,从子树序列中选择最优子树
还记得我们引入的前提吗?对于一个固定的 α \alpha α,有且仅有一棵最优子树与其对应。因此第一步的目的可由寻找子树序列{T0,T1,…Tn}转化为寻找 α \alpha α序列{ α 0 \alpha0 α0, α 1 \alpha1 α1,…, α n \alpha n αn},注意 α 0 \alpha0 α0到 α \alpha αn是逐渐增大的
那对于每一个子树分支,如何计算它必须剪掉时对应的 α \alpha α呢:
简单翻译一下上述的公式的意思:
- 当 a < C ( t ) − C ( T t ) ∣ T t ∣ − 1 a<\frac{C(t)-C(T_t)}{|T_t|-1} a<∣Tt∣−1C(t)−C(Tt)时, C α ( T t ) < C α ( t ) C_{\alpha}(T_t)<C_{\alpha}(t) Cα(Tt)<Cα(t),即保留该子树分支的损失小于剪去该子树分支的损失,因此不进行剪枝;
- 当 a > C ( t ) − C ( T t ) ∣ T t ∣ − 1 a>\frac{C(t)-C(T_t)}{|T_t|-1} a>∣Tt∣−1C(t)−C(Tt)时, C α ( T t ) > C α ( t ) C_{\alpha}(T_t)>C_{\alpha}(t) Cα(Tt)>Cα(t),即保留该子树分支的损失大于剪去该子树分支的损失,因此需要进行剪枝;
因此,当 a = C ( t ) − C ( T t ) ∣ T t ∣ − 1 a=\frac{C(t)-C(T_t)}{|T_t|-1} a=∣Tt∣−1C(t)−C(Tt),就是该子树分支应当剪去的时刻。
注意,在ID3和C4.5的剪枝算法里, α \alpha α是已知的;而在CART剪枝算法中, α \alpha α是需要计算的。
到这里文章也就结束了。但是笔者还有一个问题,CART回归树是基于平方误差损失选择特征切分点的,那如果遇到了离散型特征,平方误差损失就失效了,这时应该怎么处理呢?请路过的大佬解答。