决策树
背景:规则
table1:
X 1 X_1 X1 | X 2 X_2 X2 | … | X n X_n Xn | y y y |
---|---|---|---|---|
1 | 3 | … | 3 | 0 |
2 | 4 | … | 1 | 0 |
3 | 5 | … | 5 | 0 |
4 | 2 | … | 2 | 1 |
3 | 3 | … | 7 | 1 |
3 | 5 | … | 2 | 1 |
2 | 4 | … | 3 | 0 |
1 | 1 | … | 8 | 0 |
其中 X 1 X_1 X1, X 2 X_2 X2, …, X n X_n Xn是特征,y是标签。
- 假设 y = f ( x ) + r ( x ) y=f(x)+r(x) y=f(x)+r(x),其中 f ( x ) f(x) f(x)为一函数, r ( x ) r(x) r(x)为一与x相关的随机变量。
a) 假设
y
y
y的值只与
X
1
X_1
X1的值相关
规则选定为根据阈值划分数据,即模型为
y
=
I
(
X
1
∈
R
)
y=I(X_1 \in R)
y=I(X1∈R),其中
R
R
R为
X
1
X_1
X1取值全集的一个子集,比如
y
=
I
(
X
1
∈
{
3
,
4
}
)
y=I(X_1 \in \{3,4\})
y=I(X1∈{3,4})。
b) 假设
y
y
y的值与
X
1
,
X
2
,
.
.
.
,
X
n
X_1,X_2,...,X_n
X1,X2,...,Xn相关
规则选定为根据阈值划分数据,即模型为
y
=
I
(
(
X
1
,
X
2
,
.
.
.
,
X
n
)
∈
R
)
y=I((X_1,X_2,...,X_n) \in R)
y=I((X1,X2,...,Xn)∈R),其中
R
R
R为
X
1
,
X
2
,
.
.
.
X
n
X_1,X_2,...X_n
X1,X2,...Xn取值全集
R
1
∗
R
2
∗
.
.
.
∗
R
n
R_1*R_2*...*R_n
R1∗R2∗...∗Rn的一个子集,比如
y
=
I
(
(
X
1
,
X
2
,
.
.
.
,
X
n
)
∈
{
(
4
,
2
,
.
.
.
,
2
)
,
(
3
,
3
,
.
.
.
,
7
)
,
(
3
,
5
,
.
.
.
,
2
)
}
)
y=I((X_1,X_2,...,X_n) \in \{(4,2,...,2), (3,3,...,7),(3,5,...,2)\})
y=I((X1,X2,...,Xn)∈{(4,2,...,2),(3,3,...,7),(3,5,...,2)})。
单纯使用规则的思路会有如下的问题:
- 当n的数值很大时,难以罗列所有的可能性(假设所有的特征都是离散的,特征1,2…n的取值分别有 a 1 , a 2 . . . a n a_1,a_2...a_n a1,a2...an种,则所有的可能的特征组合有 ∏ i = 1 n a i \prod_{i=1}^na_i ∏i=1nai种);
- 当 r ( x ) ≠ 0 r(x) \neq 0 r(x)=0时,无法确定合适的使得 y = 1 y=1 y=1的X的集合。
决策树
决策树对以上两个问题提供了一种解决方法。
既然当n很大,无法罗列所有的可能性,那么干脆不去罗列所有的可能性,决策树采取求取局部最优,一步一步来求解得到全局最优的近似解。决策树的思想是每次只选择一个特征划分数据,决策是“一步”最优的优化算法,它并不能保证“两步”最优,“多步”最优。。
对于
r
(
x
)
≠
0
r(x) \neq 0
r(x)=0的情况,选择
{
y
∣
x
}
\{y|x\}
{y∣x}中占比最高的类别作为模型的预测值。
算法流程
决策树算法的流程如下(《机器学习》p74):
输入:
训练集
D
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
.
,
(
x
m
,
y
m
)
}
D=\{(x_1,y_1),(x_2,y_2),...,(x_m,y_m)\}
D={(x1,y1),(x2,y2),...,(xm,ym)};
属性集
A
=
{
a
1
,
a
2
,
.
.
.
,
a
n
}
A=\{a_1,a_2,...,a_n\}
A={a1,a2,...,an}.
过程:
函数
T
r
e
e
G
e
n
e
r
a
t
e
(
D
,
A
)
TreeGenerate(D,A)
TreeGenerate(D,A)
- 生成节点node;
- If D中样本全属于同一类别C Then
- 将node标记为C类叶节点;return
- end if
- if A = ∅ A=\emptyset A=∅ or D中样本在A上取值相同 then
- 将node标记为叶节点,其类别标记为D中样本数最多的一类;return
- end if
- 从A中选择最优划分属性 a ∗ a_* a∗;
- for a ∗ a_* a∗的每一个值 a ∗ v a_*^v a∗v do
- 为node生成一个分支;另 D v D_v Dv表示D中在 a ∗ a_* a∗上取值为 a ∗ v a_*^v a∗v的样本子集;
- if D v D_v Dv为空 then
- 将分支节点标记为叶节点,其类别标记为D中样本最多的类;return
- else
- 以 T r e e G e n e r a t e ( D v , A − { a ∗ } ) TreeGenerate(D_v,A-\{a_*\}) TreeGenerate(Dv,A−{a∗})为分支节点
- end if
- end for
最优属性选择方法
最优划分属性的选择是决策树算法的重点。最优划分属性的选择基本要求是希望划分后的分支节点包含的样本尽可能属于同一个类别。所以最小分类误差、方差、信息熵、基尼系数等都可以作为最有属性的选择依据。
假设样本集合 D D D中第 k k k类样本所占比例为 p k p_k pk。
信息熵
信息论概念。
E
n
t
(
D
)
=
−
∑
k
=
1
∣
y
∣
p
k
l
o
g
2
p
k
Ent(D)=-\sum_{k=1}^{|y|}p_klog_2p_k
Ent(D)=−k=1∑∣y∣pklog2pk
信息增益
假设离散属性a的取值有V种,D中样本属性a上取值为v的样本集为
D
v
D_v
Dv,则样本集D在属性a上的信息增益为:
G
a
i
n
(
D
,
a
)
=
E
n
t
(
D
)
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
E
n
t
(
D
v
)
Gain(D,a)=Ent(D)-\sum_{v=1}^V {{|D_v|} \over {|D|}}Ent(D^v)
Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
一般而言,信息增益越大,意味着使用属性a来进行划分越好,但是信息增益会偏向于选择类别数较多的属性。ID3算法使用信息增益作为最优属性的选择方法。
信息增益率
G
a
i
n
_
r
a
t
i
o
(
D
,
a
)
=
G
a
i
n
(
D
,
a
)
I
V
(
a
)
Gain\_ratio(D,a)={Gain(D,a) \over IV(a)}
Gain_ratio(D,a)=IV(a)Gain(D,a)
其中
I
V
(
a
)
=
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
l
o
g
2
∣
D
v
∣
∣
D
∣
IV(a)=-\sum_{v=1}^V{|D^v| \over |D|}log_2{|D^v| \over |D|}
IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
一般而言,信息增益率越大,意味着使用属性a来进行划分越好,但是信息增益会偏向于选择类别数较少的属性。
基尼系数
经济学概念
G
i
n
i
(
D
)
=
∑
k
=
1
∣
y
∣
∑
k
′
≠
k
p
k
p
k
′
Gini(D)=\sum_{k=1}^{|y|}\sum_{k^{\\'} \neq k}p_kp_{k^{\\'}}
Gini(D)=k=1∑∣y∣k′=k∑pkpk′
基尼指数
G
i
n
i
_
i
n
d
e
x
(
D
,
a
)
=
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
G
i
n
i
(
D
v
)
Gini\_index(D,a)=\sum_{v=1}^V{|D^v| \over |D|}Gini(D^v)
Gini_index(D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
一般而言,基尼指数越小,意味着使用属性a来进行划分越好。CART算法使用基尼指数作为最优属性的选择方法。
最优属性的选择方法还可以有很多,只要满足基本的要求:希望划分后的分支节点包含的样本尽可能属于同一个类别就行。经典的Xgboost就不是直接使用上述的最优属性选择方法。
正则
一方面,训练集难以覆盖所有的特征组合,另一方面,
y
=
f
(
x
)
+
r
(
x
)
y=f(x)+r(x)
y=f(x)+r(x)中的随机项
r
(
x
)
r(x)
r(x)并不等于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∣其中
α
\alpha
α是模型对子树生长后的惩罚因子。为了使得
C
α
(
T
t
)
=
C
α
(
t
)
C_\alpha(T_t)=C_\alpha(t)
Cα(Tt)=Cα(t)惩罚因子需要满足
α
(
t
)
=
C
(
t
)
−
C
(
T
t
)
∣
T
t
∣
−
1
\alpha(t)={C(t)-C(T_t) \over |T_t| - 1}
α(t)=∣Tt∣−1C(t)−C(Tt)以此得到每一个内部节点的惩罚因子
α
(
t
)
\alpha(t)
α(t),作为一个模型,需要有惩罚因子,但是当外在条件相同时,惩罚因子越小的模型越好。令惩罚因子最小的节点t为剪枝节点,对节点t剪枝得到新的决策树,重复以上过程直到决策树无法剪枝为止。对比剪枝过程成生成的所有的决策树在验证集上的模型效果,选择效果最好的模型作为最终模型。
预剪枝与后剪枝对比
- 后剪枝的决策树一般较深;
- 后剪枝的决策树欠拟合的风险比较小,也就是说后剪枝的决策树在训练集上的效果往往比预剪枝的模型好;
- 相比较于预剪枝模型的欠拟合风险,后剪枝模型在过拟合上的风险并不大,所以后剪枝的模型泛化性能往往比预剪枝的模型好;
- 后剪枝的模型比预剪枝的模型和未剪枝的模型计算开销都大很多。
缺失值处理
决策树的缺失值处理方法很多,一般比较简单。训练集上的属性缺失,可以降低样本权重,即将样本原有的权重1等比例的复制给所有可能的缺失属性取值。测试集上的属性缺失,可以搜索缺失属性的所有训练样本的最大可能类别作为预测类别
连续值处理
决策树本身并不能处理连续值,所以需要对连续值做处理。不过决策树对连续值的处理方式很简单、往往效果不错。决策树的连续值处理有几种方式:
- 预处理的方式将连续值转化为类别值,预处理的方法可以根据中位数(均值)二分,也可以选择最佳的划分阈值二分;可以根据经验多分;可以根据分位数分桶等等;预处理的方式只需要处理一次。
- 树生成过程中将数据二分,计算不同划分阈值下模型分类增益,选择最大的分类增益作为该连续属性的增益,并以此划分数据。树生成过程中划分连续数据,那么在每次生成节点的时候都需要判断一次。根据需要,也可以根据属性选择完以后,可以选择将该属性放回候选属性池,此时一个连续的属性可能多次出现在决策树的节点上。
模型优缺点
优点
- 数据预处理简单;
- 能够处理离散和连续数据;
- 对缺失值不敏感,对异常值不敏感;
- 可以处理多分类数据;
- 模型计算量小;
- 模型容易理解,容易评估每个特征对模型贡献;
- 模型容易理解,决策树模型与常用的规则判断模型一致;
- 模型简单,需要人为设定的模型超参较少,而且超参对模型的影响也容易评估。
缺点
- 模型拟合能力差,对连续数值的拟合能力不够强;
- 模型难以平衡过拟合与欠拟合,当提高训练集上的拟合能力时,由于过多叶子节点样本数量小,模型很容易过拟合;
- 当特征关联性比较强时,模型效果不好保证;
- 贪婪算法,可能找不到全局最优;
- 决策树本身是不稳定的,较小的样本变化,可能生成完全不同的决策树。
思考
信息增益与信息增益率
信息增益和信息增益率之间的差别就是
I
V
(
a
)
,
其
中
的
D
v
IV(a),其中的D^v
IV(a),其中的Dv只跟数据按照属性的取值划分以后,每个取值对应的样本数相关。它可以认为是针对信息增益的一个惩罚因子。既然,信息增益偏向于选择类别数较多的属性,加上惩罚因子后的信息增益率偏向于选择类别数较少的属性,很自然的问题就是能不能添加合适的惩罚因子使得完全没有偏向呢?
我没见过,如果谁想到了,我觉得会是一篇很好的贡献。实际中,信息增益率的提出者是同时使用了信息熵和信息增益率来选择最后划分属性的:C4.5算法先从候选属性中选择信息增益大于平均值的属性,然后再从中选择信息增益率最大的属性作为最优属性。
属性选择方法与损失函数
为什么决策树的属性选择标准是划分后的分支节点包含的样本尽可能属于同一个类别就行?这个标准跟机器学习算法中常见的“损失函数”有什么区别呢?
其实它跟损失函数的思想是一致的,只是因为在决策树这种特殊算法的情况下,对损失函数做的一个更加直白的解释。决策树算法的一大特点就是:相同叶子节点的预测结果必须是相同的。当分支节点包含的样本属于同一个类别,那使用这个类别作为该节点的预测值得到的损失就会最小,当分支节点包含的样本属于多种类别,那么无论对该节点使用何种类别作为预测结果,损失值都会很大。换句话说,能作为损失函数的函数都可以作为最优属性的评估方法,不过哪种方法更优,需要理论和实践的验证。