树模型-ID3、C4.5、CART
决策树
ID3
ID3使用 信息增益 来选择特征
信息熵
E n t ( D ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k Ent(D) = - \sum_{k=1}^{|y|}{p_k}{log_2{pk}} Ent(D)=−k=1∑∣y∣pklog2pk
∣ y ∣ |y| ∣y∣ 是类别的个数, p k p_k pk 指划分到类别 k k k 的概率,整个数据划分干净时信息熵为 0 0 0,信息熵最大为 l o g 2 log2 log2
计算信息熵时,若 p = 0 p=0 p=0 ,则 p l o g 2 p = 0 {p}{log_2{p}} = 0 plog2p=0
信息熵最小值 m i n E n t ( D ) = 0 min\ Ent(D) = 0 min Ent(D)=0,此时数据集仅有 1 1 1 个类别
信息熵最大值 m a x E n t ( D ) = l o g 2 y = − ∑ k y 1 y l o g 2 1 y = − y × 1 y × l o g 2 1 y = − l o g 2 1 / y = l o g 2 y max\ Ent(D) = log_2{y} = - \sum_{k}^{y} {\frac{1}{y} {log2{\frac{1}{y}}}}=-y \times \frac{1}{y}\times {log2{\frac{1}{y}}}=-log_2{1/y}=log_2{y} max Ent(D)=log2y=−∑kyy1log2y1=−y×y1×log2y1=−log21/y=log2y,此时数据集各类别概率相等
信息增益
信息增益 = 划分之前信息熵 − 划分之后信息熵 信息增益=划分之前信息熵-划分之后信息熵 信息增益=划分之前信息熵−划分之后信息熵,
G a i n ( D ∣ A ) = E n t ( D ) − ∑ v = 1 V ∣ D V ∣ ∣ D ∣ E n t ( D v ) , 其中特征 A = a 1 , a 2 , . . . , a 3 Gain(D|A)=Ent(D)-\sum_{v=1}^{V}\frac{|D_V|}{|D|}Ent(D_v),\ 其中 特征 A ={a_1,a_2,...,a_3} Gain(D∣A)=Ent(D)−∑v=1V∣D∣∣DV∣Ent(Dv), 其中特征A=a1,a2,...,a3
计算每个特征的信息增益,选取最大的特征进行划分。
伪代码
--------------------------------------------------------
输入:训练集 D={(x1,y1), (x2,y2), ... , (xm,ym)}
属性集 A={a1, a2, ... , ad}
过程:函数 TreeGenerate(D, A)
生成节点node;
if D 中样本全部属于同一类别 C then // 判断是否同属于一类
将 node 标记为 C 类叶子结点; return;
end if
if A = 空集 OR D 中样本 在特征集 A 上取值相同 then // 判断特征是否可分
将 node 标记为叶节点, 其类别为 D 中样本最多的类; return;
end if
for a in A do
计算 信息增益;
end do
从 A 中选择最优划分属性 a_*;
for a_* 的每一个值 a_*^v do
为 node 生成一个分支;
令 D_v 表示为 D 中在 a_* 特征上取值为 a_*^v 的样本子集;
if D_v 为空 then
将分支节点标记为叶节点, 其类别标记为 D 中样本最多的类; return;
else
以 TreeGenerate(D_v, A \ {a_*}) 为分支节点
end if
end for
输出:以 node 为根节点的决策树
缺点
- 无剪枝策略,容易过拟合;
- 信息增益偏好对可取值数目较多的特征有所偏好;
- 只能用于处理离散分布的特征;
- 没有考虑缺失值。
C4.5
信息增益率
信息增益
G a i n ( D ∣ A ) = E n t ( D ) − ∑ v = 1 V ∣ D V ∣ ∣ D ∣ E n t ( D v ) , 其中特征 A = a 1 , a 2 , . . . , a 3 Gain(D|A)=Ent(D)-\sum_{v=1}^{V}\frac{|D_V|}{|D|}Ent(D_v),\ 其中 特征 A ={a_1,a_2,...,a_3} Gain(D∣A)=Ent(D)−∑v=1V∣D∣∣DV∣Ent(Dv), 其中特征A=a1,a2,...,a3
I V ( A ) = − ∑ k = 1 y ∣ D k ∣ ∣ D ∣ ∗ l o g 2 ∣ D k ∣ ∣ D ∣ IV(A)=-\sum_{k=1}^{y} {\frac{|D_k|}{|D|}}*log2{\frac{|D_k|}{|D|}} IV(A)=−∑k=1y∣D∣∣Dk∣∗log2∣D∣∣Dk∣
通常,属性A的可能取值数越多(即K越大),则IV(A)的值通常会越大,若选择了IV(A)较小的特征进行分支,则可起到减少了树的复杂度的作用。但是这样一来,增益率会偏向分支小的特征,致使分类效果下降。
因此,C4.5算法不是直接选择信息增益率最大的候选划分属性,而是先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择信息增益率最高的。
- 先对所有属性的信息增益进行从高到低排序,从候选划分属性中选出信息增益高于平均水平的;
- 在从中选出增益率高的;
连续值处理
当属性类型为离散型,无须对数据进行离散化处理;
当属性类型为连续型,则需要对数据进行离散化处理。具体思路如下:
具体思路:
- m m m 个样本的连续特征 A A A 有 m m m 个值,从小到大排列 A = a 1 , a 2 , . . . , a m A ={a_1,a_2,...,a_m} A=a1,a2,...,am ,取相邻两样本值的平均数做划分点,一共有 m − 1 m-1 m−1 个,其中第 i i i 个划分点 T i T_i Ti表示为: T i = ( a i + a i + 1 ) / 2 T_i=(a_i + a_{i+1})/2 Ti=(ai+ai+1)/2 。
- 分别计算以这 m − 1 m-1 m−1 个点作为二元切分点时的信息增益率。选择信息增益率最大的点 a t a_t at 为该连续特征的最佳切分点。比如取到的信息增益率最大的点为 a t a_t at ,则小于 a t a_t at 的值为类别1,大于 a t a_t at 的值为类别2,这样就做到了连续特征的离散化。
缺失值处理
缺失值处理 分为 属性缺失 和 标签缺失
-
根据缺失比例,折算信息增益(无缺失值样本所占的比例乘以无缺失值样本子集的信息增益)和信息增益率
G a i n ( D ∣ A ) = ρ × G a i n ( D ′ ∣ A ) = ρ × ( E n t ( D ′ ) − ∑ v = 1 V ∣ D V ′ ∣ ∣ D ′ ∣ E n t ( D v ′ ) ) , 其中特征 A = a 1 , a 2 , . . . , a 3 , ρ = ∑ D 在属性 A 上无缺失样的个数 D 的个数 Gain(D|A)= \rho \times Gain(D'|A)=\rho \times (Ent(D')-\sum_{v=1}^{V} \frac{|D'_V|}{|D'|}Ent(D'_v)),\ 其中 特征 A ={a_1,a_2,...,a_3},\rho=\frac{\sum D在属性A上无缺失样的个数}{D的个数} Gain(D∣A)=ρ×Gain(D′∣A)=ρ×(Ent(D′)−∑v=1V∣D′∣∣DV′∣Ent(Dv′)), 其中特征A=a1,a2,...,a3,ρ=D的个数∑D在属性A上无缺失样的个数
例子:
编号 色泽 纹理 好瓜 权重 1 - 清晰 是 2 乌黑 清晰 是 3 乌黑 模糊 是 4 浅白 清晰 否 5 浅白 - 否 6 - 模糊 是 7 - 清晰 否 E n t ( D ) = − ( 2 4 l o g 2 ( 2 4 ) + 2 4 l o g 2 ( 2 4 ) ) Ent(D)= -(\frac{2}{4} log_2(\frac{2}{4})+\frac{2}{4} log_2(\frac{2}{4})) Ent(D)=−(42log2(42)+42log2(42))
E n t ( D 乌黑 ∣ 色泽 ) = − ( 1 2 l o g 2 ( 1 2 ) + 1 2 l o g 2 ( 1 2 ) ) Ent(D_{乌黑}|色泽)= -(\frac{1}{2} log_2(\frac{1}{2})+\frac{1}{2} log_2(\frac{1}{2})) Ent(D乌黑∣色泽)=−(21log2(21)+21log2(21))
E n t ( D 浅白 ∣ 色泽 ) = − ( 1 2 l o g 2 ( 1 2 ) + 1 2 l o g 2 ( 1 2 ) ) Ent(D_{浅白}|色泽)= -(\frac{1}{2} log_2(\frac{1}{2})+\frac{1}{2} log_2(\frac{1}{2})) Ent(D浅白∣色泽)=−(21log2(21)+21log2(21))
ρ = 4 / 7 \rho=4/7 ρ=4/7
G a i n ( D ∣ 色泽 ) = ρ ∗ G a i n ( D ∣ 色泽 ) = 4 7 ∗ ( E n t ( D ) − ( 2 4 ∗ E n t ( D 乌黑 ∣ 色泽 ) + 2 4 ∗ E n t ( D 浅白 ∣ 色泽 ) ) Gain(D|色泽)=\rho * Gain(D|色泽)=\frac{4}{7} * (Ent(D)-(\frac{2}{4} * Ent(D_{乌黑}|色泽) + \frac{2}{4} * Ent(D_{浅白}|色泽)) Gain(D∣色泽)=ρ∗Gain(D∣色泽)=74∗(Ent(D)−(42∗Ent(D乌黑∣色泽)+42∗Ent(D浅白∣色泽))
-
引入权重概念,并将含缺失值样本经权值计算后,划入所有子树节点。可理解为将同一个样本以不同的概率划入到不同的结点中。
以纹理=清晰为例
编号 色泽 纹理 好瓜 权重 1 - 清晰 是 1 2 乌黑 清晰 是 1 4 浅白 清晰 否 1 5 浅白 - 否 4/6 7 浅白 清晰 是 1 在前一个表中,第5条数据划分到清晰的权重为 4 6 \frac{4}{6} 64 ,
ρ = 3 + 4 / 6 4 + 4 / 6 \rho=\frac{3+4/6}{4+4/6} ρ=4+4/63+4/6(无缺失值样本比例)
p 好瓜 = 2 3 + 4 / 6 p_{好瓜}=\frac{2}{3+4/6} p好瓜=3+4/62 (无缺失值样本中,好瓜的比例)
p 坏瓜 = 1 + 4 / 6 3 + 4 / 6 p_{坏瓜}=\frac{1+4/6}{3+4/6} p坏瓜=3+4/61+4/6 (无缺失值样本中,坏瓜的比例)
r 乌黑 = 1 3 + 4 / 6 r_{乌黑}=\frac{1}{3+4/6} r乌黑=3+4/61 (无缺失值样本中,色泽=乌黑的比例)
r 浅白 = 2 + 4 / 6 3 + 4 / 6 r_{浅白}=\frac{2+4/6}{3+4/6} r浅白=3+4/62+4/6 (无缺失值样本中,色泽=浅白的比例)
E n t ( D ) = − ( p 好瓜 l o g 2 ( p 好瓜 ) + p 坏瓜 l o g 2 ( p 坏瓜 ) ) Ent(D)= -(p_{好瓜} log_2(p_{好瓜})+p_{坏瓜} log_2(p_{坏瓜})) Ent(D)=−(p好瓜log2(p好瓜)+p坏瓜log2(p坏瓜))
E n t ( D 乌黑 ∣ 色泽 ) = − ( 1 1 l o g 2 ( 1 1 ) ) Ent(D_{乌黑}|色泽)= -(\frac{1}{1} log_2(\frac{1}{1})) Ent(D乌黑∣色泽)=−(11log2(11))
E n t ( D 浅白 ∣ 色泽 ) = − ( 1 2 + 4 / 6 l o g 2 ( 1 2 + 4 / 6 ) + 1 + 4 / 6 2 + 4 / 6 l o g 2 ( 1 + 4 / 6 2 + 4 / 6 ) ) Ent(D_{浅白}|色泽)= -(\frac{1}{2+4/6} log_2(\frac{1}{2+4/6})+\frac{1+4/6}{2+4/6} log_2(\frac{1+4/6}{2+4/6})) Ent(D浅白∣色泽)=−(2+4/61log2(2+4/61)+2+4/61+4/6log2(2+4/61+4/6))
G a i n ( D , 色泽 ) = ρ ( E n t ( D ) − ∑ v V r ∗ E n t ( D ∣ 色泽 ) ) Gain(D,色泽)=\rho (Ent(D)- \sum_{v}^{V} r*Ent(D|色泽)) Gain(D,色泽)=ρ(Ent(D)−∑vVr∗Ent(D∣色泽))
-
在检测的时候,碰到属性缺失,走所有分支,计算每个类别的概率,取概率最大的类别赋值给该样本
剪枝
剪枝又分为前剪枝和后剪枝,
-
前剪枝是指在构造树的过程中就知道哪些节点可以剪掉 。
在节点划分前确定是否继续增长,及早停止增长的主要方法有:
- 节点内数据样本数小于切分最小样本数阈值;
- 提前设定决策树的高度,当达到这个高度时,就停止构建决策树
- 每次扩展决策树后都计算其对系统性能的增益,若小于该阈值,则让它停止生长
- 所有节点特征都已分裂;
- 节点划分前准确率比划分后准确率高。
前剪枝不仅可以降低过拟合的风险而且还可以减少训练时间,但另一方面它是基于“贪心”策略,会带来欠拟合风险,预剪枝的显著缺点是视野效果。
-
后剪枝是指构造出完整的决策树之后再来考查哪些子树可以剪掉。
C4.5算法采用悲观剪枝方法。根据剪枝前后的误判率来判定是否进行子树的修剪, 如果剪枝后与剪枝前相比其误判率是保持或者下降,则这棵子树就可以被替换为一个叶子节点。 因此,不需要单独的剪枝数据集
把一颗子树(具有多个叶子节点)的剪枝后用一个叶子节点来替代的话,在训练集上的误判率肯定是上升的,但是在新数据上不一定。于是我们需要把子树的误判计算加上一个经验性的惩罚因子。对于一颗叶子节点,它覆盖了 N N N 个样本,其中有 E E E 个错误,那么该叶子节点的错误率为 ( E + 0.5 ) / N (E+0.5)/N (E+0.5)/N 。这个 0.5 0.5 0.5 就是惩罚因子,那么一颗子树,它有 L L L 个叶子节点,那么该子树的误判率估计为:
e 子树 = ∑ E i + 0.5 L ∑ N i e_{子树}=\frac{\sum E_i + 0.5L}{\sum N_i} e子树=∑Ni∑Ei+0.5L
其中, E i E_i Ei 表示子树的每一个叶子节点的误判样本数量, L L L 为子树的叶子节点个数, N i N_i Ni 为每一个叶子节点的样本数量。
这样的话,我们可以看到一颗子树虽然具有多个子节点,但由于加上了惩罚因子,所以子树的误判率计算未必占到便宜。剪枝后内部节点变成了叶子节点,其误判个数 J J J 也需要加上一个惩罚因子,变成 J + 0.5 J+0.5 J+0.5。
如果要判断一个子树是否可以进行剪枝,只要保证子树的误判次数 > 剪枝后叶子节点误判数
那么子树是否可以被剪枝就取决于剪枝后的错误 J + 0.5 J + 0.5 J+0.5 是否在 ∑ E i + 0.5 ∗ L \sum E_i + 0.5*L ∑Ei+0.5∗L 的标准误差内。对于样本的误判率 e e e,可以根据经验把它估计成各种各样的分布模型,比如是二项式分布,比如是正态分布。
那么树的误判次数就是伯努利分布,我们可以估计出该树的误判次数的均值和标准差:
E 子树误判次数 = N ∗ e 子树 E_{子树误判次数}=N*e_{子树} E子树误判次数=N∗e子树
s t d 子树误判次数 = N ∗ e 子树 ∗ ( 1 − e 子树 ) std_{子树误判次数}=\sqrt{N*e_{子树}*(1-e_{子树})} std子树误判次数=N∗e子树∗(1−e子树)
其中, e 子树 = ∑ E i + 0.5 L ∑ N i e_{子树}=\frac{\sum E_i + 0.5L}{\sum N_i} e子树=∑Ni∑Ei+0.5L
将子树转化为叶子节点后,误判率
e 子树转为叶子结点 = J + 0.5 N e_{子树转为叶子结点}=\frac{J + 0.5}{N} e子树转为叶子结点=NJ+0.5
误判次数
E 子树转为叶子结点 = N ∗ e 子树转为叶子结点 E_{子树转为叶子结点}=N*e_{子树转为叶子结点} E子树转为叶子结点=N∗e子树转为叶子结点
剪枝条件为:
E 子树误判次数 + s t d 子树误判次数 > = E 子树转为叶子结点 E_{子树误判次数}+std_{子树误判次数}>=E_{子树转为叶子结点} E子树误判次数+std子树误判次数>=E子树转为叶子结点
伪代码
--------------------------------------------------------
输入:训练集 D={(x1,y1), (x2,y2), ... , (xm,ym)}
属性集 A={a1, a2, ... , ad}
过程:函数 TreeGenerate(D, A)
生成节点node;
if D 中样本全部属于同一类别 C then // 判断是否同属于一类
将 node 标记为 C 类叶子结点; return;
end if
if A = 空集 OR D 中样本 在特征集 A 上取值相同 then // 判断特征是否可分
将 node 标记为叶节点, 其类别为 D 中样本最多的类; return;
end if
for a in A do
计算 信息增益率
end for
选择信息增益率最大值作为 最优划分属性 a_*;
for a_* 的每一个值 a_*^v do
为 node 生成一个分支;
令 D_v 表示为 D 中在 a_* 特征上取值为 a_*^v 的样本子集;
if D_v 为空 then
将分支节点标记为叶节点, 其类别标记为 D 中样本最多的类; return;
else
以 TreeGenerate(D_v, A \ {a_*}) 为分支节点
end if
end for
输出:以 node 为根节点的决策树
相比于ID3优点
-
用信息增益率来选择划分特征,克服了用信息增益选择的不足,但信息增益率对可取值数目较少的属性有所偏好;
-
能够处理离散型和连续型的属性类型,即将连续型的属性进行离散化处理;
-
能够处理具有缺失属性值的训练数据;
1). 根据缺失比例,折算信息增益(无缺失值样本所占的比例乘以无缺失值样本子集的信息增益)和信息增益率
2). 根据权重划分数据集
-
在构造树的过程中进行剪枝;
缺点
- 处理连续值时计算复杂度较高,原处理方法为计算多个划分点,排序,并分别计算信息增益和信息增益率
- 数据量受限,数据量大时内存无法计算
- 信息增益率可能会使得高信息增益的分类特征下降,若属性熵 I V ( A ) IV(A) IV(A)很小,作为分母有可能会使得整个信息增益率非常大,因此C4.5采用了一个启发式的算法,先从候选属性中找出高于平均水平的属性,再从高于平均水平的属性中选择增益率最高的属性。
- 多叉树不如二叉树效率高
- 只能用于分类
CART-基尼系数
ID3中使用了信息增益选择特征,增益大优先选择。C4.5中,采用信息增益率选择特征,减少因特征值多导致信息增益大的问题。CART分类树算法使用基尼系数选择特征,基尼系数代表了模型的不纯度,基尼系数越小,不纯度越低,特征越好。这和信息增益(率)相反。
基尼系数
G i n i ( D ) = ∑ i = 1 n p ( x i ) ∗ ( 1 − p ( x i ) ) = 1 − ∑ i = 1 n p ( x i ) 2 Gini(D)=\sum_{i=1}^{n} p(x_i)*(1-p(x_i))=1-\sum_{i=1}^{n} {p(x_i)}^2 Gini(D)=∑i=1np(xi)∗(1−p(xi))=1−∑i=1np(xi)2
其中, p ( x i ) p(x_i) p(xi) 是分类 x i x_i xi 出现的概率, n n n 是分类的数目。 G i n i ( D ) Gini(D) Gini(D) 反映了从数据集 D D D 中随机抽取两个样本,其类别标记不一致的概率。因此, G i n i ( D ) Gini(D) Gini(D)越小,则数据集 D D D 的纯度越高。
对于样本 D D D,个数为 ∣ D ∣ |D| ∣D∣,根据特征 A A A 是否取某一可能值 a a a,把样本D分成两部分 ∣ D 1 ∣ |D_1| ∣D1∣ 和 ∣ D 2 ∣ |D_2| ∣D2∣ 。所以CART分类树算法建立起来的是二叉树,而不是多叉树。
D 1 = ( x , y ) ∈ D ∣ A ( x ) = a , D 2 = D − D 1 D_1=(x,y) \in D | A(x) = a,\ D_2=D-D_1 D1=(x,y)∈D∣A(x)=a, D2=D−D1
在属性为 A A A 的条件下,基尼系数
G i n i ( D ∣ A = a ) = D 1 D G i n i ( D 1 ) + D 2 D G i n i ( D 2 ) Gini(D|A=a)=\frac{D_1}{D}Gini(D_1)+\frac{D_2}{D}Gini(D_2) Gini(D∣A=a)=DD1Gini(D1)+DD2Gini(D2)
连续值处理
同C4.5,计算基尼系数
缺失值处理
- 计算基尼系数时属性缺失,使用不缺失的计算基尼系数,同时乘以非特征缺失样本的比重,这部分和C4.5相似。
- 在划分时,属性缺失????????
基尼指数与熵的区别
基尼指数增益:
G i n i ( D ) = ∑ i = 1 n p ( x i ) ∗ ( 1 − p ( x i ) ) = 1 − ∑ i = 1 n p ( x i ) 2 Gini(D)=\sum_{i=1}^{n} p(x_i)*(1-p(x_i))=1-\sum_{i=1}^{n} {p(x_i)}^2 Gini(D)=∑i=1np(xi)∗(1−p(xi))=1−∑i=1np(xi)2
基尼指数是二类分:
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)
又:
l n ( x ) = − 1 + x + o ( x ) ln(x)=-1+x+o(x) ln(x)=−1+x+o(x)
所以:
E n t ( D ) = − ∑ k = 1 k p k l n p k ≈ ∑ k = 1 k p k ( 1 − p k ) Ent(D)=-\sum_{k=1}^{k}p_k ln p_k \approx \sum_{k=1}^{k}p_k (1-p_k) Ent(D)=−∑k=1kpklnpk≈∑k=1kpk(1−pk)
伪代码
--------------------------------------------------------
输入:训练集 D={(x1,y1), (x2,y2), ... , (xm,ym)}
属性集 A={a1, a2, ... , ad}
过程:函数 TreeGenerate(D, A)
生成节点node;
if D 中样本全部属于同一类别 C then // 判断是否同属于一类
将 node 标记为 C 类叶子结点; return;
end if
if A = 空集 OR D 中样本 在特征集 A 上取值相同 then // 判断特征是否可分
将 node 标记为叶节点, 其类别为 D 中样本最多的类; return;
end if
while
if 当前节点样本个数 < 阈值:
return
else if 当前节点基尼系数 < 阈值:
return
end if
for a in A do
if a 是连续值 then
生成划分节点列表 a_sp_list
for a_sp in a_sp_list:
选择基尼系数最小的 a_sp
end for
else
for a_sp in a:
选择基尼系数最小的 a_sp
end for
end else
end for
选择最小划分节点a_sp
左树循环调用TreeGenerate(D, A)
右树循环调用TreeGenerate(D, A)
输出:以 node 为根节点的决策树
``