决策树与随机森林理论与实现(一)
决策树
决策树是一种依据多种特征依次进行划分以达到对训练数据的分类。
特点
- 与线性模型相比,树形结构可对数据进行非线性分割
- 接近人的思维,有可视化的划分规则,具有可解释性
- 适合处理离散数据
结构
- 树状结构,根节点,若干内部节点以及若干叶节点
- 根节点代表全集,叶节点代表决策结果,内部节点代表一个属性测试
- 父子节点之间的关系表示为父节点对应的样本集合根据自身的属性测试划分到子节点中
概念
以西瓜质量好坏(甜 or 不甜)与西瓜的色泽,纹理,响声等因素的关系为例
- 样本的类别:决策的最终结果(甜 or 不甜)
- 样本的属性:决策的判断条件(色泽,纹理,响声等)
- 属性值:某一个属性包含的元素(清晰的纹理,清脆的响声等)
总体流程
- 采用递归分治的策略
- 基本思想是寻找信息熵下降最快的树结构
流程伪代码
输入:
训练集
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
d
}
;
A=\{a_1,a_2,...,a_d\};
A={a1,a2,...,ad};
过程: TreeGenerate(D,A)
对于当前的集合生成结点node
if D 中样本属于同一类别 //(1)
将 node 标记为叶结点,按照样本类别标记叶结点
else if A中没有多余的特征 or D 在 A 划分一致 //(2)
将 node 标记为叶结点,按照D中样本数最多的类别标记叶结点
else
从 A 中选择最优的划分属性 a* //(3)
for a* 属性中的每一种属性值ai
在node基础上产生子结点,Di表示D中对于属性a取值为ai的子集
if Di 为空 //(4)
标记叶结点,按照D中样本数最多的类别标记叶结点
else //(5)
递归分支 TreeGenerate(Di,A-{a})
- (1) 当前结点内样本都是同一类别,无需继续划分
- (2) 当前属性已经无法对当前部分样本进行更细的划分了,以D中的大多数样本的类别对D的类别进行概括
- (3) 根据不同的算法找到最优的划分属性,后面会详细介绍
- (4) 当前训练集合没有这部分划分的相关样本,故以D中的大多数样本的类别对该子节点的类别进行概括
- (5) 当前的子集还可以继续向下划分,将当前选中属性抛去
划分选择
对于划分标准的选择,唯一的标准就是,通过划分,使得样本尽快划分至同一类别,即划分后纯度提升越快越好。
- 首先,需要对当前样本集合的纯度进行定义,可通过信息熵或基尼值的方式定量描述样本纯度。
- 选择一种方式判定纯度的提升程度
信息熵与信息增益
信息熵的定义:
E
n
t
(
D
)
=
−
∑
k
=
1
∣
y
∣
p
k
log
2
p
k
Ent(D)=-\sum_{k=1}^{|y|}p_k\log_2p_k
Ent(D)=−k=1∑∣y∣pklog2pk
表示对于样本集合D,
p
k
p_k
pk代表不同类别的所占比例,
E
n
t
(
D
)
Ent(D)
Ent(D)越小,纯度越高,叶结点的
E
n
t
(
D
)
Ent(D)
Ent(D)为0
信息增益引入的目的是为了表示纯度提升的效果,即信息熵的下降程度,划分前与划分后信息熵的差值。
假设属性a有V个属性值
{
a
1
,
a
2
,
.
.
.
,
a
V
}
\{a^1,a^2,...,a^V\}
{a1,a2,...,aV},依据V个属性对D进行分类,对于划分后的每一个子集,有自己的信息熵。根据划分子集的大小,分配一个权重
∣
D
v
∣
∣
D
∣
\frac{|D^v|}{|D|}
∣D∣∣Dv∣。
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\frac{|D^v|}{|D|}Ent(D^v)
Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
由上面的定义,以信息增益为基准选择属性a*时,
a
∗
=
arg
max
a
∈
A
G
a
i
n
(
D
,
a
)
a_*=\mathop{\arg\max}\limits_{a\in A} Gain(D,a)
a∗=a∈AargmaxGain(D,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)=\frac{Gain(D,a)}{IV(a)}
Gainratio(D,a)=IV(a)Gain(D,a)
I
V
(
a
)
=
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
log
2
∣
D
v
∣
∣
D
∣
IV(a)=-\sum_{v=1}^V\frac{|D^v|}{|D|}\log_2\frac{|D^v|}{|D|}
IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
I
V
(
a
)
IV(a)
IV(a)的含义即为属性a本身的信息熵,属性包含的属性值越多,
I
V
(
a
)
IV(a)
IV(a)越大
但相对于信息增益,增益率相反会偏好取值数目较少的属性。
故在使用增益率的算法,C4.5决策树算法中,先从候选划分属性中找出信息增益高于平均水平的属性,在从中选择增益率最高的。
基尼指数
引入概念基尼值来度量样本的纯度
G
i
n
i
(
D
)
=
∑
k
=
1
∣
y
∣
∑
k
′
≠
k
p
k
p
k
′
=
1
−
∑
k
=
1
∣
y
∣
p
k
2
Gini(D)=\sum_{k=1}^{|y|}\sum_{k'\ne k}p_kp_{k'}=1-\sum_{k=1}^{|y|}p_k^2
Gini(D)=k=1∑∣y∣k′̸=k∑pkpk′=1−k=1∑∣y∣pk2
基尼值直观上讲是连续抽取两次样本,其类别不一致的概率
根据划分的子集给出基尼系数
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\frac{|D^v|}{|D|}Gini(D^v)
Giniindex(D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
选择划分后基尼系数最小的属性
a
∗
=
arg
min
a
∈
A
G
i
n
i
i
n
d
e
x
(
D
,
a
)
a_*=\mathop{\arg\min}\limits_{a\in A} Gini_index(D,a)
a∗=a∈AargminGiniindex(D,a)
剪枝
为了防止决策树过拟合,需要减去一些分支以提高其泛化能力。
泛化能力的评价方法:当前模型对测试集的类别判定准确率
预剪枝
在决策树产生时,对于每个结点,分别计算其作为叶结点和内部结点的泛化能力,通过对比,判断是否在该结点的基础上继续增加子树。若其作为内部结点时,泛化能力提升,则将其子树保留。
泛化能力的计算与比较:
对于一个结点,如果将其作为叶结点,则以样本中占多数的类别作为自身的类别;如果为内部结点,则将子树作为叶结点做相同操作。将测试集数据放在当前决策树中,在该节点处,分别计算其作为叶结点和内部结点对于样本的判定准确率。
- 预剪枝的优点:降低过拟合的风险,同时由于很多分支没有过多展开,节省大量开销
- 预剪枝的缺点:基于“贪心”的策略导致一些当前划分使性能降低,但后续划分会使性能提升的结点被忽略,导致欠拟合
后剪枝
与预剪枝做法类似。首先生成一棵完整的决策树,从当前倒数第一层的内部结点开始,依次计算其作为叶结点和内部结点的泛化性能,判断其是否需要剪枝。
- 优点:欠拟合可能性小
- 缺点:开销大
连续值处理
前面对于属性的讨论都是离散的属性值,当属性变为连续值时,可以采用二分法将连续属性划分为一个含有两个属性值的属性,详细操作如下。
对于一个连续属性a,在样本集合D中出现了n个不同的值,从小到大
{
a
1
,
a
2
,
.
.
.
,
a
n
}
\{a^1,a^2,...,a^n\}
{a1,a2,...,an},找到合适的划分点t将D分为
D
t
+
D_t^+
Dt+和
D
t
−
D_t^-
Dt−,分别代表大于t的子集与不大于t的子集,对于n个不同的属性值
a
∗
a^*
a∗显然有n-1个区间供t选择(即每个
a
t
a^t
at和
a
t
+
1
a^{t+1}
at+1之间),由于由于t在某一个区间内部大小变化对整体分类效果没有影响,所以t取区间中点,故t的取值集合:
T
a
=
{
a
i
+
a
i
+
1
2
∣
1
≤
i
≤
n
−
1
}
T_a=\{\frac{a^i+a^{i+1}}2|1\le i\le n-1\}
Ta={2ai+ai+1∣1≤i≤n−1}
接下来需要在t的取值集合中找到最优的t,作为二分法的属性分类条件,而选择最优t的准则依旧是选择纯度提升最快时对应的t
G
a
i
n
(
D
,
a
)
=
max
t
∈
T
a
G
a
i
n
(
D
,
a
,
t
)
=
max
t
∈
T
a
E
n
t
(
D
)
−
∑
λ
∈
{
−
,
+
}
∣
D
t
λ
∣
∣
D
∣
E
n
t
(
D
t
λ
)
Gain(D,a)=\max\limits_{t\in T_a} Gain(D,a,t)=\max\limits_{t\in T_a}Ent(D)-\sum_{\lambda\in\{-,+\}}\frac{|D_t^\lambda|}{|D|}Ent(D_t^\lambda)
Gain(D,a)=t∈TamaxGain(D,a,t)=t∈TamaxEnt(D)−λ∈{−,+}∑∣D∣∣Dtλ∣Ent(Dtλ)
在选择划分的属性是将此类连续值属性的信息增益与其他离散属性放在一起选择出合适的划分属性
缺失值处理
对于现实数据中经常出现的问题,采集样本时可能存在部分数据缺失的现象。为了最大限度的使用这些不完整的数据,需要采取措施提取其剩余有用的信息。
含缺失值的处理有两个问题:
- (1) 如何在有缺失值的情况下进行划分选择?
- 对于不同的属性,存在对于该属性未缺失值的完整样本集合(对于属性a,该集合中的样本的特点是:全部属性上数据可能存在缺失,但对于属性a,数据是完整的)
- 对于每个属性,利用各自的完整样本集合计算出各自信息增益,再根据自身集合相对于全集的大小给定权值。
- 根据各自的信息增益进行选择
- (2) 划分选择完毕后,对于划分选择属性缺失的数据,如何根据划分归属到各自的子集中?
- 将无法明确划分入子集中的元素,划分至所有子集
- 根据其所在的子集的大小,对于问题 (1) 中的权值会有一定影响
- 相当于将该部分样本按照比例拆分为几部分分至不同子集
对于样本集合D和属性集合a,
D
~
\tilde{D}
D~表示对于属性a没有缺失值的集合。
由于问题 (2) 中缺失值的样本进入子集时并非全部划分至某一子集,为了计算这部分集合,为每一样本x加入了权值
ω
x
\omega_x
ωx的概念(最开始所有样本的权值均为1,当出现缺失值进入集合时,才会对缺失样本的权值进行处理)
接下来是计算信息增益,即计算根据a进行划分前后的信息熵,由于权值概念的引入,不能再将样本数量作为划分后的信息熵的参数加入计算。因此引入下面一些集合名称,用于计算。
属性a有V个可取值
{
a
1
,
a
2
,
.
.
.
,
a
V
}
\{a^1,a^2,...,a^V\}
{a1,a2,...,aV},用
D
~
v
\tilde{D}^v
D~v表示
D
~
\tilde{D}
D~中属性值为
a
v
a^v
av的集合;样本类别有k类(k=1,2,…,|y|),用
D
~
k
\tilde{D}_k
D~k表示
D
~
\tilde{D}
D~中第k类样本集合
定义以下变量:
ρ
\rho
ρ用于问题(1)中计算出属性a对于部分集合的信息增益后,相对于全集的权值加成
ρ
=
∑
x
∈
D
~
ω
x
∑
x
∈
D
ω
x
\rho=\frac{\sum_{x\in\tilde{D}}\omega_x}{\sum_{x\in D}\omega_x}
ρ=∑x∈Dωx∑x∈D~ωx
p
k
~
\tilde{p_k}
pk~用于计算信息熵
p
k
~
=
∑
x
∈
D
~
k
ω
x
∑
x
∈
D
~
ω
x
\tilde{p_k}=\frac{\sum_{x\in\tilde{D}_k}\omega_x}{\sum_{x\in\tilde{D}}\omega_x}
pk~=∑x∈D~ωx∑x∈D~kωx
r
v
~
\tilde{r_v}
rv~用于计算划分后的各子集信息熵汇总后的权值
r
v
~
=
∑
x
∈
D
~
v
ω
x
∑
x
∈
D
~
ω
x
\tilde{r_v}=\frac{\sum_{x\in\tilde{D}^v}\omega_x}{\sum_{x\in\tilde{D}}\omega_x}
rv~=∑x∈D~ωx∑x∈D~vωx
下面是计算过程:
G
a
i
n
(
D
,
a
)
=
ρ
×
G
a
i
n
(
D
~
,
a
)
Gain(D,a)=\rho\times Gain(\tilde{D},a)
Gain(D,a)=ρ×Gain(D~,a)
G
a
i
n
(
D
~
,
a
)
=
E
n
t
(
D
~
)
−
∑
v
=
1
V
r
v
~
E
n
t
(
D
~
v
)
Gain(\tilde{D},a)=Ent(\tilde{D})-\sum_{v=1}^V\tilde{r_v}Ent(\tilde{D}^v)
Gain(D~,a)=Ent(D~)−v=1∑Vrv~Ent(D~v)
E
n
t
(
D
~
)
=
−
∑
k
=
1
∣
y
∣
p
k
~
log
2
p
k
~
Ent(\tilde{D})=-\sum_{k=1}^{|y|}\tilde{p_k}\log_2\tilde{p_k}
Ent(D~)=−k=1∑∣y∣pk~log2pk~
对于问题(2)中的权值改变,假设最终被选中的划分属性为a,根据
{
a
1
,
a
2
,
.
.
.
,
a
V
}
\{a^1,a^2,...,a^V\}
{a1,a2,...,aV}将
D
~
\tilde{D}
D~集合划分为
D
~
v
\tilde{D}^v
D~v。最后将缺失值放入所有子集,对于加入的每个
D
~
v
\tilde{D}^v
D~v,设缺失值加入前的权值
ω
x
′
\omega_x'
ωx′则该缺失值的权值
ω
x
\omega_x
ωx
ω
x
=
ω
x
′
×
∣
D
~
v
∣
∣
D
~
∣
\omega_x=\omega_x'\times\frac{|\tilde{D}^v|}{|\tilde{D}|}
ωx=ωx′×∣D~∣∣D~v∣
多变量决策树
当前决策树存在的缺陷:划分相对于属性是一种对坐标轴的简单分段。所有划分均具有轴平行的特点。
因此,将目前的内部结点仅仅为某一属性的特点,换为结点为属性的线性组合,达到分类效果更佳的目的。
参考文献:
- 《机器学习》周志华