本文仅提供决策树流程及细节操作,没有例子求解过程供参考,同时也没有编程实现。
一般的,一棵决策树包含一个根节点, 若干内部节点 和 若干叶子节点。 叶子节点 对应决策结果,其他每个节点对应一个 属性测试(即判定一次基于这个属性对现有数据如何分类决策)。每个节点包含的样本集合根据属性测试结果被分到对应节点中。根节点 包含样本全集。
目的: 决策树学习的目的是产生一棵泛化能力强的决策树。
有一个训练集 D D D, 属性集 A A A , a ∈ A a\in A a∈A
若 D D D 中所有样本都属于同一个类 C, 则把这个节点记为C,为子节点。(这个节点不再划分,结束)
如果 A = ∅ A=\empty A=∅ 或者 D D D 在 A A A 上取值都相同:
把这个节点记为叶子节点,类别标为 D D D 中所含样本数最多的类。(例:若 D D D 中 E E E 类3个, F F F 类5个, G G G 类10个,则该叶子节点类别为 G G G 类)。并且这个节点结束不再划分。
D D D 在 A A A 上取值不同,则从 A A A 中选择最优的属性 a ∗ a_* a∗ ,根据这个属性对 D D D 进行划分(比如分辨西瓜好坏的一个属性是根蒂 ,取值可以是 蜷缩 、稍蜷 和硬挺。根据属性的不同相应对西瓜有不同的分类)
对属性 a ∗ a_* a∗ 的每个取值 v v v:
给节点 ξ \xi ξ 生成一个分支 η \eta η , D v D_v Dv 记为 D D D 中根据属性 a ∗ a_* a∗ 取值为 v的样本子集合。
如果 D v = ∅ D_v=\empty Dv=∅: 就把分支记为 叶子节点,赌赢类别标记为 D D D 中类别最多 那个, 参见步骤 2.
如果 D v ≠ ∅ D_v \neq \empty Dv=∅ 此时将这个分支形成的节点 η \eta η 作为 ξ \xi ξ ,返回 ξ \xi ξ 对应位置(即第 1 步)
此时对应样本集为 D v D_v Dv, 属性集 A \ { a ∗ } A \backslash \{a_*\} A\{a∗} 进行接下来的步骤,与上面步骤相同,直至所有新生成的节点称为叶子节点,结束。
输入 : 训练集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } D=\{(\bf{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}
过程: 函数 T r e e G e n e r a t e ( D , A ) TreeGenerate(D, A) TreeGenerate(D,A)
1.生成节点 node;
2. if D D D 中样本完全属于同一类别 C C C then
3. 将 node 标记为 C C C 类叶节点; return
4.endif
5. if A = ∅ A=\empty A=∅ OR D D D 中样本在 A A A 上取值相同 then
6. 将 node 标记为叶子节点,其类别标记为 D D D 中样本最多的类; return
7.endif
8. 从 A A A 中选择最优划分属性 a ∗ a_* a∗;
9. for a ∗ a_* a∗ 的每一个值 a ∗ v a^{v}_{*} a∗v do
10. 为 node 生成一个分支;令 D v D_v Dv表示 D D D 中在 a ∗ a_* a∗ 上取值为 a ∗ v a^{v}_{*} a∗v 的样本子集;
11. if D v D_v Dv 为空,then
12. 将分支节点标记为叶子节点,其类别标记为 D D D 中样本最多的类; return
13. else
14. 以 T r e e G e n e r a t e ( D v , A \ { a ∗ } ) TreeGenerate(D_v, A\backslash \{a_*\}) TreeGenerate(Dv,A\{a∗}) 为分支节点
15. endif
16. endfor
上述算法过程中,第 8 步最重要。随着划分的不断进行,我们希望决策树的分支节点所包含的样本尽可能属于同一类别,即节点的纯度(purity)越来越高。因此我们希望在划分时,根据所选择的属性划分后的样本“纯度”提升最多。
以下介绍几种会用到的 纯度 提升方案
信息熵(information entropy)是度量样本集合纯度最常用的一种指标。假定当前样本集合 D D D 中第 k k k 类样本所占比例为 p k p_k pk( k = 1 , 2 , . . . ∣ y ∣ k=1,2, ...|y| k=1,2,...∣y∣),则 D D D 的信息熵定义为
E n t ( D ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k Ent(D)=-\sum_{k=1}^{|y|}p_klog_2{p_k} Ent(D)=−k=1∑∣y∣pklog2pk
E n t ( D ) Ent(D) Ent(D) 最小值为0,最大值为 l o g x ∣ y ∣ log_x|y| logx∣y∣,证明见文末。
信息熵的改变量 称为 信息增益(information gain)
根据属性 a a 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\frac{|D^v|}{|D|}Ent(D^v) Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
V V V 是属性 a a a 可取值的个数, D v D^v Dv是对应取值所含样本个数。信息增益 越大越好。
实际上,信息增益 对取值数目多的属性比较偏好。比如,根据某一个属性的取值,可将当前样本集划分成一个样本一种划分,此时可以计算得到信息增益最大,但是这样的决策近似枚举,不具备泛化性。
因此,定义 增益率 消除一部分划分数目影响。定义为
G a i n _ r a t e = G a i n ( D , a ) I V ( a ) Gain\_rate=\frac{Gain(D,a)}{IV(a)} Gain_rate=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\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 a a 的固有值, V 越大, I V ( a ) IV(a) IV(a) 一般会越大,这样就消除个数影响了(有个问题,为什么不直接除以 a a a 的取值个数?这取有什么坏处?)
但 增益率 会对取值个数少的有偏好。故一般是先找出 信息增益 中高于平均水平的属性,再从中选择增益率最高的。
G i n i ( D ) = ∑ k = 1 ∣ y ∣ ∑ k ≠ k ′ p k p k ′ = ( ∑ k = 1 ∣ y ∣ p k ) ( ∑ k ′ = 1 ∣ y ∣ p k ′ ) − ∑ k = 1 ∣ y ∣ p k 2 = 1 − ∑ k = 1 ∣ y ∣ p k 2 Gini(D) =\sum_{k=1}^{|y|}\sum_{k\neq k^{'}}p_kp_{k^{'}}=(\sum_{k=1}^{|y|}p_k)(\sum_{k^{'}=1}^{|y|}p_{k^{'}})-\sum_{k=1}^{|y|}p_k^2 \\ =1-\sum_{k=1}^{|y|}p_k^2 Gini(D)=k=1∑∣y∣k=k′∑pkpk′=(k=1∑∣y∣pk)(k′=1∑∣y∣pk′)−k=1∑∣y∣pk2=1−k=1∑∣y∣pk2
直观地说, G i n i ( D ) Gini(D) Gini(D) 反应从数据集 D D D 中随机抽取两个样本,类别不一致的概率,故 G i n i ( D ) Gini(D) Gini(D) 越小, 样本集纯度越高。
一个属性的基尼指数定义为
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) Gini_index(D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
然后按 G i n i i n d e x ( D , a ) Gini_index(D,a) Giniindex(D,a) 最小那个 a a a 作为所选择的划分属性。
为了防止学习到的决策树过拟合,可对树进行剪枝。两种剪枝方式:预剪枝 和 后剪枝
预剪枝 是指在决策树生成过程中,对每个节点在划分前先进行估计,若当前节点的划分 不能 带来决策树 泛化性能的提升 ,则停止划分并将当前节点标记为叶子节点;
后剪枝 是先从训练集生成一棵 完整 的决策树,然后自底向上地对非叶子节点进行考察,若将该节点对应的 子树 替换为 叶子 节点能带来决策树 泛化性能的提升,则将该子树替换为叶子节点。
评估 决策树性能提升的 方法:留出法、交叉验证法、自助法等,详见 《机器学习–周志华》2.2节
以 留出法 为例说明两种剪枝方式的操作过程。
预剪枝 决定一个节点处是否根据某属性划分,是比较划分前后泛化性能的差别。
优点:降低过拟合风险,同时显著减少决策树的训练时间开销和测试时间开销;
缺点:有些分支的当前划分虽然不能提升泛化性能、甚至可能导致泛化性能暂时下降,但在其基础上进行的后续划分却有可能导致性能显著提高;预剪枝基于 贪心 本质禁止这些分支的展开,给预剪枝决策树带来了 欠拟合 的风险。
过程就是介绍里的过程。
优点:通常会保留比 预剪枝 更多的分支,欠拟合风险小,泛化性能往往由于 预剪枝。
缺点:训练时间开销比未剪枝决策树和 预剪枝 决策树都要大很多。
若某属性取值是连续值,可将该连续值 离散化,然后再处理。离散化 可以用 二分法,即取一个值 t t t, 把连续值范围分成两类,之后再对这两类接下来的进行划分。
如 t t t 选择 信息增益 最大的值,具体如下:
设已有的连续值,排序后取值为 a = { a 1 , a 1 , . . . , a n } a=\{a^1, a^1, ...,a^n\} a={a1,a1,...,an}, 候选点
T a = { a i + a i + 1 2 , 1 ≤ i ≤ n − 1 } T_a=\{\frac{a^i+a^{i+1}}{2}, 1\leq i\leq n-1\} Ta={2ai+ai+1,1≤i≤n−1}
t t t 从 T a T_a Ta 中取。这样不会把已有样本分在端点处。于是连续值的信息增益为
G a i n ( D , a ) = m a x t ∈ T a G a i n ( D , a , t ) = m a x t ∈ T a E n t ( D ) − ∑ λ ∈ { − , + } ∣ D v ∣ ∣ D ∣ E n t ( D t v ) Gain(D,a)=max_{t\in T_a}Gain(D,a,t)\\ =max_{t\in{T_a}}Ent(D)-\sum_{\lambda \in \{-,+\}}\frac{|D^v|}{|D|}Ent(D_t^v) Gain(D,a)=maxt∈TaGain(D,a,t)=maxt∈TaEnt(D)−λ∈{−,+}∑∣D∣∣Dv∣Ent(Dtv)
这里 λ \lambda λ 是连续值划分后的两类。
这样就可以把离散值的信息增益与连续值的信息增益进行比较,进而选择最优属性。
即存在有些样本的有些属性的对应值是缺失的,这种情况很常见,但这类数据如果丢掉不用,则会对数据噪声很大浪费。因此需要一套针对缺失值的处理办法。
对缺失值数据的处理需要解决两个问题:
对第 1 个问题,我们根据无缺失样本 所占比例 计算对应信息增益,然后比较选择属性。具体如下:
训练集 D D D, 属性 a a a 有 V V V 个取值,无缺失样本集记为 D ~ \tilde{D} D~, D k ~ \tilde{D_k} Dk~ 表示 D ~ \tilde{D} D~ 中属于第 k = { k = 1 , 2 , . . . , ∣ y ∣ } k=\{k=1,2,... ,|y|\} k={k=1,2,...,∣y∣} 个类的样本子集。假定给每个样本 x x x 赋予一个权重 w x w_x wx(一般初始化为 1)。定义
ρ = ∑ x ∈ D ~ w x ∑ x ∈ D w x \rho=\frac{\sum_{x\in \tilde{D}}w_x}{\sum_{x\in D}w_x} ρ=∑x∈Dwx∑x∈D~wx
p k ~ = ∑ x ∈ D k ~ w x ∑ x ∈ D ~ w x , ( 1 ≤ k ≤ ∣ y ∣ ) \tilde{p_k}=\frac{\sum_{x\in \tilde{D_k}}w_x}{\sum_{x\in \tilde D}w_x}, (1\le k\le|y|) pk~=∑x∈D~wx∑x∈Dk~wx,(1≤k≤∣y∣)
r v ~ = ∑ x ∈ D v ~ w x ∑ x ∈ D ~ w x , ( 1 ≤ v ≤ V ) \tilde{r_v}=\frac{\sum_{x\in \tilde{D_v}}w_x}{\sum_{x\in \tilde D}w_x}, (1\le v\le V) rv~=∑x∈D~wx∑x∈Dv~wx,(1≤v≤V)
ρ \rho ρ 是无缺失样本比例, p k ~ \tilde{p_k} pk~ 无缺失样本中第 k k k 类比例, r v ~ \tilde{r_v} rv~ 无缺失样本中属性 a a a 上取值为 a v a^v av 的样本比例。显然 ∑ k = 1 ∣ y ∣ p k ~ = 1 \sum_{k=1}^{|y|}\tilde{p_k}=1 ∑k=1∣y∣pk~=1 , ∑ v = 1 V r v ~ = 1 \sum_{v=1}^V\tilde{r_v}=1 ∑v=1Vrv~=1.
此时,
G a i n ( D , a ) = ρ × G a i n ( D ~ , a ) = ρ × ( E n t ( D ~ ) − ∑ v = 1 V r v ~ E n t ( D ~ v ) ) Gain(D,a) =\rho \times Gain(\tilde D,a)\\ =\rho \times (Ent(\tilde D)-\sum_{v=1}^V\tilde{r_v}Ent(\tilde D^v)) Gain(D,a)=ρ×Gain(D~,a)=ρ×(Ent(D~)−v=1∑Vrv~Ent(D~v))
E n t ( D ~ ) = − ∑ k = 1 ∣ y ∣ p k ~ l o g x p k ~ Ent(\tilde D)=-\sum_{k=1}^{|y|}\tilde{p_k}log_x\tilde{p_k} Ent(D~)=−k=1∑∣y∣pk~logxpk~
有了信息增益,就可以划分属性。
第 2 个问题,在属性 a a a 上缺失值的样本,在按属性 a a a 划分时同时划分给属性 a a a 的所有子节点,但样本的权值调为 r v ~ ⋅ w x \tilde{r_v} \cdot w_x rv~⋅wx, 再做接下来的工作。
单变量决策树生成的边界与坐标轴平行。若任务边界很复杂,则需要多段才能近似,同时决策树也会很复杂。
故考虑用 斜的边界, 即多个变量作为节点属性进行判别。
具体, 每个非叶子节点用一个线性分类器 ∑ i = 1 d w i a i = t \sum_{i=1}^d w_i a_i =t ∑i=1dwiai=t进行划分, w i w_i wi 是属性 a i a_i ai 的权重, w i w_i wi 和 t t t 可在改节点所含的样本集合属性集上学得。
问题描述:考虑问题 E n t ( D ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k Ent(D)=-\sum_{k=1}^{|y|}p_klog_2{p_k} Ent(D)=−∑k=1∣y∣pklog2pk 的最值,其中 0 ≤ p k ≤ 1 , ∑ k = 1 ∣ y ∣ p k = 1 0\le p_k \le 1, \sum_{k=1}^{|y|}p_k=1 0≤pk≤1,∑k=1∣y∣pk=1, 定义 0 l o g 2 0 = 0 0log_20=0 0log20=0
证明:上述问题可以描述为以下约束优化问题
m a x − ∑ k = 1 ∣ y ∣ p k l o g 2 p k max -\sum_{k=1}^{|y|}p_klog_2p_k max−∑k=1∣y∣pklog2pk
s . t . ∑ k = 1 ∣ y ∣ p k = 1 s.t. \sum_{k=1}^{|y|}p_k=1 s.t.∑k=1∣y∣pk=1
最小值: E n t ( D ) ≥ 0 Ent(D)\ge 0 Ent(D)≥0
最大值:应用 拉格朗日乘子法 ,引入乘子 λ \lambda λ,则对应的拉格朗日函数为
L ( p k , λ ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k + λ ( − ∑ k = 1 ∣ y ∣ p k − 1 ) L(p_k,\lambda)=-\sum_{k=1}^{|y|}p_klog_2{p_k}+\lambda(-\sum_{k=1}^{|y|}p_k-1) L(pk,λ)=−k=1∑∣y∣pklog2pk+λ(−k=1∑∣y∣pk−1)
求解
{ ∂ L p k = 0 − ∑ k = 1 ∣ y ∣ p k = 1 \left\{ \begin{aligned} \frac{\partial L}{p_k}=0 \\ -\sum_{k=1}^{|y|}p_k =1 \end{aligned} \right. ⎩ ⎨ ⎧pk∂L=0−k=1∑∣y∣pk=1
得
∂ L p k = − l o g 2 p k − 1 l n 2 + λ = 0 \frac{\partial L}{p_k}=-log_2p_k-\frac{1}{ln 2}+\lambda=0 pk∂L=−log2pk−ln21+λ=0, 得 p k = 2 λ − 1 l n 2 p_k=2^{\lambda-\frac{1}{ln 2}} pk=2λ−ln21
带入
− ∑ k = 1 ∣ y ∣ p k = 1 -\sum_{k=1}^{|y|}p_k =1 −∑k=1∣y∣pk=1 得 p k = 1 ∣ y ∣ p_k=\frac{1}{|y|} pk=∣y∣1, 此时 E n t ( D ) = l o g x ∣ y ∣ Ent(D)=log_x|y| Ent(D)=logx∣y∣.
[1]. 《机器学习》,周志华 著, 清华大学出版社;
[2]. 信息熵最值计算