机器学习——“让树帮你做决策”之决策树(Decision Tree)(ID3,C4.5,CART,决策树剪枝)

引入:去不去相亲?

我们现实生活中经常见到自己或者其他人做许多决策:今天是否去打球?明天要不要逃课?家人介绍的相亲对象要不要去见?
我们以最后一个为例:
比如说小好妈妈对小好说:“我同事家一男孩儿还不错,你周末去见见。”
小好问:“他多大了?超过30我不见”
妈妈:“没有,和你同岁”
小好:“长得帅不帅?低于一般水平我不见”
妈妈:“长得可帅了,像古天乐呢!”
小好:“O(∩_∩)O哈哈~那他收入怎样?”
(PS.emmm…像古天乐肯定就去啦,但是,为了例子的完整性,还是要象征性的再问一个问题~)
妈妈:“一般般”
小好:“是公务员吗?”
妈妈:“是的”
小好:“那我去见~”
上述对话可用决策树表示为:
在这里插入图片描述
这就是决策树比较简单的表现形式,用树的形式更直观的展现决策流程。
可能有人会问:这我干嘛要做成树的形式,我不用树也可以清楚的知道结果。但是这是针对很小样本的情况,如果样本量很大,或者小好的要求很零散、很多,这时不用决策树很难一目了然的得到一般规律和结果。
这就是决策树算法存在的意义,那么决策树算法到底是什么?让我们来推开决策树的大门!

决策树(Decision Tree)

定义

决策树(Decision Tree),又称为判定树,是数据挖掘技术中的一种重要的分类方法,它是一种以树结构(包括二叉树和多叉树)形式来表达的预测分析模型。

决策树方法是一种比较通用的分类函数逼近法,它是一种常用于预测模型的算法,通过将大量数据有目的分类,找到一些有潜在价值的信息
具体用到的知识我们下一步说,先来看看决策树的构造。

决策树的构造

就像上图是否去相亲的决策树,其中绿色节点表示判断条件橙色节点表示决策结果箭头表示在一个判断条件在不同情况下的决策路径,图中红色箭头表示了上面例子中女孩的决策过程。
由上可知,决策树需要有内部节点:判别条件(年龄、长相、收入、是否是公务员);叶节点:决策结果(是否去相亲);分支:不同判别条件下的决策路径;而根节点就是树最顶层的节点,可以理解为最先的分裂属性,也是所有内部节点的父节点。
Note.什么是父子节点?
由上述图形,年龄节点是长相节点的父节点,也是根节点,子节点由父节点根据某分类规则得来。 决 策 树 的 树 结 构 { 根 节 点 内 部 节 点 叶 节 点 决策树的树结构\begin{cases}根节点\\内部节点\\叶节点\end{cases}

决策树算法原理

在介绍决策树算法原理之前,需要了解一点:决策树的构建准则是使信息量以最快的速度降低到0。
那么,什么是信息量?如何衡量信息量?

在信息论中,认为信源输出的消息是随机的。即在未收到消息之前,是不能肯定信源到底发送什么样的消息。而通信的目的也就是要使接收者在接收到消息后,尽可能多的解除接收者对信源所存在的疑义(不定度),因此这个被解除的不定度实际上就是在通信中所要传送的信息量。”

简而言之,信息量是用来描述信息的不确定程度。比如说,'太阳东升西落’这件事是必然事件,对于这种大家都已知的必然事件带来的信息量就为0,因为没有消除大家的任何疑虑,也就是说这个信息不存在任何不确定性程度的变动(因为他就是确定的,必然发生的)。
再比如:专业射击选手小王(成绩平均在9.0)和射击新手小明(成绩平均在5.0)分别进行射击,对于观众来说,小王射击这个事件的不确定性较小(通常在9.0附近),而小明射击的不确定性较大(可能时好时坏),所以可以认为小明射击事件的信息量更大。
那么信息量是用什么来衡量的呢?就像我们刚才举的例子,“信息的不确定程度的变化”,我们使用信息的不确定程度的降低来衡量信息量的大小。
由于上述的例子中,必然事件(概率为1)的信息量最小,为零。不确定性越大的事件(小明射击)的信息量较大。因此,信息量和概率有着必然的联系。
信息量的公式为: h ( x ) = − l o g 2 p ( x ) h(x)=-log_2p(x) h(x)=log2p(x)
信息熵的公式为: H ( X ) = − ∑ i N p i ( x i ) l o g ( p i ( x i ) ) H(X)=-\sum_i^N p_i(x_i)log(p_i(x_i)) H(X)=iNpi(xi)log(pi(xi))
信息熵:信息对可能产生的信息量的期望——信息量的所有可能取值,即所有可能发生事件所带来的信息量的期望。
注:信息熵用来衡量事件不确定性。其值越大,不确定性越高。
回到这句话:决策树的构建准则是使信息量以最快的速度降低到0
可见,决策树的构建过程是一种优化思想:确定性增益最大化!(将‘不确定性’看做‘不纯度’,‘确定性’看做‘纯度’)即决策树构建要使纯度增益最大化。
综上可得,决策树的算法原理:根据不纯度函数,使每一次选择分裂属性带来的数据不纯度下降最大(纯度增益最大化)。
那么,决策树算法的重点就到了不纯度函数分裂属性的选择上。

决策树算法

根据决策树的发展史,经典算法的演变和发展分别为:ID3——>C4.5——>CART,本文主要介绍这三个算法。
对于不同方法的分裂属性的选择方法先总结至下表:

算法分裂属性度量
ID3信息增益
C4.5信息增益率
CART基尼系数

下面,我们根据一个例子,分别详细讲解ID3,C4.5,CART算法的分类过程。
例:根据日志密度,好友密度、是否使用真实头像、来判断账户是否真实,如下是10条数据(无实意)

日志密度好友密度是否使用真实头像账户是否真实
slyesyes
mlnoyes
lmyesyes
mmyesyes
lmyesyes
lmnoyes
ssnono
msnono
msnoyes
ssyesno

下面通过计算来深入了解每一个算法。

(1)ID3算法

1、原理介绍:若选择一个属性,使数据分类效果最好,其产生的信息增益最大。(因此,ID3算法以信息增益最大化来选择分裂属性)
对信息增益的理解——信息增益:若原数据信息熵为 I 0 I_0 I0,根据属性A划分后得到信息熵 I 1 I_1 I1, I 2 I_2 I2;信息增益为: I 0 − ( I 1 + I 2 ) I_0-(I_1+I_2) I0(I1+I2)
首先,介绍ID3算法的计算公式:
总信息熵: H ( D ) = − ∑ i = 1 c p ( x i ) l o g p ( x i ) H(D)=-\sum^c_{i=1}p(x_i)logp(x_i) H(D)=i=1cp(xi)logp(xi)某属性分裂后的信息熵: H ( D ∣ 分 裂 属 性 A ) = ∑ j = 1 m ∣ D j ∣ ∣ D ∣ ∗ ∑ i = 1 c p ( x i ) l o g p ( x i ) H(D|分裂属性A)=\sum_{j=1}^m \frac{|D_j|}{|D|}*\sum^c_{i=1}p(x_i)logp(x_i) H(DA)=j=1mDDji=1cp(xi)logp(xi)信息增益: g a i n ( 分 裂 属 性 A ) = H ( D ) − H ( D ∣ 分 裂 属 性 A ) gain(分裂属性A)=H(D)-H(D|分裂属性A) gain(A)=H(D)H(DA)
2、案例计算,
信息熵的计算——
账户是否真实: { y e s : 7 n o : 3 \begin{cases}yes:7\\no:3\end{cases} {yes:7no:3
目标变量的信息熵: H ( D ) = − 7 10 l o g 2 7 10 − 3 10 l o g 2 3 10 = 0.8813 H(D)=-\frac{7}{10}log_2\frac{7}{10}-\frac{3}{10}log_2\frac{3}{10}=0.8813 H(D)=107log2107103log2103=0.8813
①日志密度:
在这里插入图片描述
H ( D ∣ 日 志 密 度 ) = 3 10 [ − 1 3 l o g 2 1 3 − 2 3 l o g 2 2 3 ] + 4 10 [ − 1 4 l o g 2 1 4 − 3 4 l o g 2 3 4 ] + 3 10 [ − 3 3 l o g 2 3 3 − 0 ] = 0.6 H(D|日志密度)=\frac{3}{10} [-\frac{1}{3}log_2 \frac{1}{3}-\frac{2}{3}log_2\frac{2}{3}]+\frac{4}{10} [-\frac{1}{4}log_2 \frac{1}{4}-\frac{3}{4}log_2\frac{3}{4}]+\frac{3}{10} [-\frac{3}{3}log_2 \frac{3}{3}-0]=0.6 H(D)=103[31log23132log232]+104[41log24143log243]+103[33log2330]=0.6 g a i n ( 日 志 密 度 ) = H ( D ) − H ( D ∣ 日 志 密 度 ) = 0.8813 − 0.6 = 0.2813 gain(日志密度)=H(D)-H(D|日志密度)=0.8813-0.6=0.2813 gain()=H(D)H(D)=0.88130.6=0.2813
②好友密度:
在这里插入图片描述
H ( D ∣ 好 友 密 度 ) = 4 10 [ − 1 4 l o g 2 1 4 − 3 4 l o g 2 3 4 ] + 4 10 [ − 4 4 l o g 2 4 4 − 0 ] + 2 10 [ − 2 2 l o g 2 2 2 − 0 ] = 0.3245 H(D|好友密度)=\frac{4}{10} [-\frac{1}{4}log_2 \frac{1}{4}-\frac{3}{4}log_2\frac{3}{4}]+\frac{4}{10} [-\frac{4}{4}log_2 \frac{4}{4}-0]+\frac{2}{10} [-\frac{2}{2}log_2 \frac{2}{2}-0]=0.3245 H(D)=104[41log24143log243]+104[44log2440]+102[22log2220]=0.3245 g a i n ( 好 友 密 度 ) = H ( D ) − H ( D ∣ 好 友 密 度 ) = 0.8813 − 0.3245 = 0.5568 gain(好友密度)=H(D)-H(D|好友密度)=0.8813-0.3245=0.5568 gain()=H(D)H(D)=0.88130.3245=0.5568
③是否使用真实头像:
在这里插入图片描述
H ( D ∣ 是 否 使 用 真 实 头 像 ) = 5 10 [ − 1 5 l o g 2 1 5 − 4 5 l o g 2 4 5 ] + 5 10 [ − 3 5 l o g 2 3 5 − 2 5 l o g 2 2 5 ] = 0.8464 H(D|是否使用真实头像)=\frac{5}{10} [-\frac{1}{5}log_2 \frac{1}{5}-\frac{4}{5}log_2\frac{4}{5}]+\frac{5}{10} [-\frac{3}{5}log_2 \frac{3}{5}-\frac{2}{5}log_2\frac{2}{5}]=0.8464 H(D使)=105[51log25154log254]+105[53log25352log252]=0.8464 g a i n ( 是 否 使 用 真 实 头 像 ) = H ( D ) − H ( D ∣ 是 否 使 用 真 实 头 像 ) = 0.8813 − 0.8464 = 0.0349 gain(是否使用真实头像)=H(D)-H(D|是否使用真实头像)=0.8813-0.8464=0.0349 gain(使)=H(D)H(D使)=0.88130.8464=0.0349
g a i n ( 好 友 密 度 ) > g a i n ( 日 志 密 度 ) > g a i n ( 是 否 使 用 真 实 头 像 ) gain(好友密度)>gain(日志密度)>gain(是否使用真实头像) gain()>gain()>gain(使)因此,首先选择好友密度作为分裂属性,后面步骤相同,本文略。
在这里插入图片描述
3、ID3算法缺陷
对于ID3算法,若我们将数据增加一列ID:1,2,3,4,5,6,7,8,9,10
此时, H ( D ∣ I D ) = ∑ j = 1 m ∣ D j ∣ ∣ D ∣ ∗ ∑ i = 1 c p ( x i ) l o g p ( x i ) = 1 10 [ − 1 1 l o g 2 1 1 − 0 ] + . . . + 1 10 [ − 1 1 l o g 2 1 1 − 0 ] ] = 0 H(D|ID)=\sum_{j=1}^m \frac{|D_j|}{|D|}*\sum^c_{i=1}p(x_i)logp(x_i)=\frac{1}{10} [-\frac{1}{1}log_2 \frac{1}{1}-0]+...+\frac{1}{10} [-\frac{1}{1}log_2 \frac{1}{1}-0]]=0 H(DID)=j=1mDDji=1cp(xi)logp(xi)=101[11log2110]+...+101[11log2110]]=0 g a i n ( I D ) = H ( D ) − H ( D ∣ I D ) = 0.8813 − 0 = 0.8813 gain(ID)=H(D)-H(D|ID)=0.8813-0=0.8813 gain(ID)=H(D)H(DID)=0.88130=0.8813此时信息增益总是最大的,而我们知道按照ID划分是没有意义的。由此,我们得出ID3算法的一个缺陷:偏向于选择多值属性!
为了解决这个问题,C4.5算法在其基础上做出了改进,选择分裂信息量来消除属性取值越多信息增益越大的缺陷。

(2)C4.5算法

1、算法原理:引入分裂信息熵splitInf来消除信息增益的计算缺陷(若一个属性的取值较多,会使Gain变大,splitinf也会越大,相互抵消。),选择信息增益率越大的属性作为分裂属性。
对信息增益率的理解——信息增益率:若原数据信息熵为 I 0 I_0 I0,根据属性A划分后得到信息熵 I 1 I_1 I1, I 2 I_2 I2,计算得到每个划分的分裂信息熵 s p l i t I n f splitInf splitInf;信息增益率为: [ I 0 − ( I 1 + I 2 ) ] / s p l i t I n f [I_0-(I_1+I_2)]/splitInf [I0(I1+I2)]/splitInf
首先,介绍C4.5算法的计算公式:
总信息熵: H ( D ) = − ∑ i = 1 c p ( x i ) l o g p ( x i ) H(D)=-\sum^c_{i=1}p(x_i)logp(x_i) H(D)=i=1cp(xi)logp(xi)某属性分裂后的信息熵: H ( D ∣ 分 裂 属 性 A ) = ∑ j = 1 m ∣ D j ∣ ∣ D ∣ ∗ ∑ i = 1 c p ( x i ) l o g p ( x i ) H(D|分裂属性A)=\sum_{j=1}^m \frac{|D_j|}{|D|}*\sum^c_{i=1}p(x_i)logp(x_i) H(DA)=j=1mDDji=1cp(xi)logp(xi)某属性分裂后的分裂信息熵: S p l i t I n f A = − ∑ j = 1 m ∣ D j ∣ ∣ D ∣ l o g 2 ∣ D j ∣ ∣ D ∣ SplitInf_A=-\sum_{j=1}^m\frac{|D_j|}{|D|}log_2\frac{|D_j|}{|D|} SplitInfA=j=1mDDjlog2DDj信息增益率: g a i n _ r a t i o ( 分 裂 属 性 A ) = g a i n ( 分 裂 属 性 A ) S p l i t I n f A gain\_ratio(分裂属性A)=\frac{gain(分裂属性A)}{SplitInf_A} gain_ratio(A)=SplitInfAgain(A)
2、案例计算
S p l i t I n f ( 日 志 密 度 ) = − 3 10 l o g ⁡ 2 3 10 − 4 10 l o g ⁡ 2 4 10 − 3 10 l o g ⁡ 2 3 10 = 1.5709 SplitInf(日志密度)=-\frac{3}{10}log⁡_2\frac{3}{10}-\frac{4}{10}log⁡_2\frac{4}{10}-\frac{3}{10}log⁡_2\frac{3}{10}=1.5709 SplitInf()=103log2103104log2104103log2103=1.5709 S p l i t I n f ( 好 友 密 度 ) = − 4 10 l o g ⁡ 2 4 10 − 4 10 l o g ⁡ 2 4 10 − 2 10 l o g ⁡ 2 2 10 = 1.5219 SplitInf(好友密度)=-\frac{4}{10}log⁡_2\frac{4}{10}-\frac{4}{10}log⁡_2\frac{4}{10}-\frac{2}{10}log⁡_2\frac{2}{10}=1.5219 SplitInf()=104log2104104log2104102log2102=1.5219 S p l i t I n f ( 是 否 使 用 真 实 头 像 ) = − 5 10 l o g ⁡ 2 5 10 − 5 10 l o g ⁡ 2 5 10 = 1 SplitInf(是否使用真实头像)=-\frac{5}{10}log⁡_2\frac{5}{10}-\frac{5}{10}log⁡_2\frac{5}{10}=1 SplitInf(使)=105log2105105log2105=1 G a i n _ R a t i o ( 日 志 密 度 ) = g a i n ( 日 志 密 度 ) s p l i t I n f ( 日 志 密 度 ) = 0.2813 1.5709 = 0.1791 Gain\_Ratio(日志密度)=\frac{gain(日志密度)}{splitInf(日志密度)}=\frac{0.2813}{1.5709}=0.1791 Gain_Ratio()=splitInf()gain()=1.57090.2813=0.1791 G a i n _ R a t i o ( 好 友 密 度 ) = g a i n ( 好 友 密 度 ) s p l i t I n f ( 好 友 密 度 ) = 0.5568 1.5219 = 0.3659 Gain\_Ratio(好友密度)=\frac{gain(好友密度)}{splitInf(好友密度)}=\frac{0.5568}{1.5219}=0.3659 Gain_Ratio()=splitInf()gain()=1.52190.5568=0.3659 G a i n _ R a t i o ( 是 否 使 用 真 实 头 像 ) = g a i n ( 是 否 使 用 真 实 头 像 ) s p l i t I n f ( 是 否 使 用 真 实 头 像 ) = 0.0349 1 = 0.0349 Gain\_Ratio(是否使用真实头像)=\frac{gain(是否使用真实头像)}{splitInf(是否使用真实头像)}=\frac{0.0349}{1}=0.0349 Gain_Ratio(使)=splitInf(使)gain(使)=10.0349=0.0349 G a i n _ R a t i o ( 好 友 密 度 ) > G a i n _ R a t i o ( 日 志 密 度 ) > G a i n _ R a t i o ( 是 否 使 用 真 实 头 像 ) Gain\_Ratio(好友密度)>Gain\_Ratio(日志密度)>Gain\_Ratio(是否使用真实头像) Gain_Ratio()>Gain_Ratio()>Gain_Ratio(使)因此,首先选择好友密度作为分裂属性。
3、C4.5算法的优点
①解决了ID3算法偏向于多值属性的缺陷(引入 S p l i t I n f SplitInf SplitInf
②能够处理缺失值
对于上例,若日志密度存在缺失值如下:

日志密度好友密度是否使用真实头像账户是否真实
slyesyes
mlnoyes
lmyesyes
mmyesyes
lmyesyes
?mnoyes
ssnono
msnono
?snoyes
ssyesno
日志密度分类:yes分类:no合计
s123
m213
l202

S t e p 1 ′ Step1' Step1去除缺失值后此属性中各水平的比例
对任意未知的日志密度的值。取“s”的概率为3/8;取“m”的概率为3/8;取“l”的概率为2/8。
S t e p 2 ′ Step2' Step2按比例填充
S1:日志密度=s的数量——3+2*(3/8)
S2:日志密度=m的数量——3+2*(3/8)
S3:日志密度=l的数量——2+2*(2/8)
③能处理连续变量
C4.5算法处理连续属性的原理是:对不同的可能划分,分别计算所得的信息增益率,选择信息增益率最大的那个划分区间。
S t e p 1 ′ Step 1' Step1 将属性取值排序,计算相邻值的中点 v i v_i vi
S t e p 2 ′ Step 2' Step2对其中每个取值 v i v_i vi作为阈值 将数据集划分为两个部分;
S t e p 3 ′ Step 3' Step3 计算每个分支的信息增益率;
S t e p 4 ′ Step 4' Step4 选择最大信息增益的分支作为阈值,将数据分裂为离散型
PS.详情可见《数据挖掘导论》P99-P100

(3)CART算法(Classification and Regression Tree)

1、分类树

CART算法原理:使用二叉树将预测空间划分为若干子集,随着从根节点到叶节点的移动,每个节点选出最优的分支规则对应的划分区域,目标变量在该节点上的条件分布也随之被确定。
分类准则——基尼系数
首先,介绍CART算法的计算公式:
总Gini: G i n i ( D ) = 1 − ∑ i = 1 c p ( x i ) 2 Gini(D)=1-\sum^c_{i=1}p(x_i)^2 Gini(D)=1i=1cp(xi)2 某属性分裂后的Gini: G i n i ( D ∣ 分 裂 属 性 A ) = ∑ j = 1 m ∣ D j ∣ ∣ D ∣ ∗ G i n i ( D j ) Gini(D|分裂属性A)=\sum_{j=1}^m\frac{|D_j|}{|D|}*Gini(D_j) Gini(DA)=j=1mDDjGini(Dj) Gini增益: Δ G i n i ( D ∣ 分 裂 属 性 A ) = G i n i ( D ) − G i n i ( D ∣ 分 裂 属 性 A ) \Delta Gini(D|分裂属性A)=Gini(D)-Gini(D|分裂属性A) ΔGini(DA)=Gini(D)Gini(DA)
以是否使用真实头像为例:
在这里插入图片描述
G i n i ( 是 否 使 用 真 实 头 像 ) = 5 10 ∗ ( 1 − ( 4 5 ) 2 − ( 1 5 ) 2 ) + 5 10 ∗ ( 1 − ( 3 5 ) 2 − ( 2 5 ) 2 ) Gini(是否使用真实头像)=\frac{5}{10}* (1-(\frac{4}{5})^2-(\frac{1}{5})^2 )+\frac{5}{10}* (1-(\frac{3}{5})^2-(\frac{2}{5})^2 ) Gini(使)=105(1(54)2(51)2)+105(1(53)2(52)2) 样本分布均匀时Gini指标最大;分类越纯Gini越小。选择Gini系数增益最大的变量最为分类属性。

2、回归树

分类准则:最小方差原理
①基于树的方法:将特征空间划分成一系列长方形,然后对每个长方形拟合简单的模型(常数)
在这里插入图片描述
拟合的模型为: f ^ ( x ) = ∑ ( m = 1 ) 5 c m I { X 1 , X 2 ∈ R m } \hat f(x)=\sum_{(m=1)}^5c_m I\{X_1,X_2∈R_m\} f^(x)=(m=1)5cmI{X1,X2Rm} ②回归树的分裂准则——最小方差法
对每个变量、根据不同的分割点计算二叉树两边分裂的数值均值,计算其方差,方差最小的分裂点为其最终分裂点,各个变量方差值对比,选择最小方差的变量作为分裂属性。
回归树的生成计算请戳☞[传送门]☜

决策树剪枝

决 策 树 剪 枝 方 法 { 预 剪 枝 : 在 树 完 全 生 长 之 前 停 止 部 分 分 裂 后 剪 枝 : 在 树 完 全 生 长 之 后 减 去 部 分 枝 丫 决策树剪枝方法\begin{cases}预剪枝:在树完全生长之前停止部分分裂\\后剪枝:在树完全生长之后减去部分枝丫\end{cases} {

预剪枝(Pre-Pruning)

①若节点中所有观测属于一类[没必要再分],停止划分
②若树的深度达到预定阈值,停止划分
③若该节点所含观测值小于设定父节点应含观测值的阈值,停止划分
④若该节点子节点所含观测数小于设定阈值,停止划分
⑤若没有属性满足设定的分裂准则的阈值[纯度增加量不够],停止划分

后剪枝(Post-Pruning)

以CCP(Cost Complexity Pruning)为例——

CCP剪枝:选择节点表面误差率增益值最小的非叶子节点,删除该非叶子节点的左右子节点,若有多个非叶子节点的表面误差率增益值相同小,则选择非叶子节点中子节点数最多的非叶子节点进行剪枝。

CCP剪枝的步骤:
1)从原始的决策树开始生成一个子树序列(均非叶子节点) { T 0 , T 1 , … , T n } \{T_0,T_1,…,T_n \} {T0,T1,,Tn},其中 T ( i + 1 ) T_{(i+1)} T(i+1) T i T_i Ti 产生, T n T_n Tn 为根节点
2)计算所有节点的误差率增益值,选择误差率增益值最小的非叶子节点
3)对选中节点进行剪枝
4)重复
误差率增益值的计算公式为: α = R ( t ) − R ( T ) N ( T ) − 1 \alpha=\frac{R(t)-R(T)}{N(T)-1} α=N(T)1R(t)R(T) ((非叶节点误差-叶节点误差)/(叶节点数-1))
其中,

  • α 衡量的是每个节点所能减少的分类误差率。α越小,说明该节点所能减少的分类误差率越小,继续往下分类意义不大,可以剪枝,将该结点作为叶结点。

  • R(t)-表示非叶子节点的误差代价,R(t)=r(t)*p(t), r(t)为该节点的错误率, p(t) 为节点的数据量占比

  • R(T)-表示子树叶子节点的误差代价, R ( T ) = ∑ ( i = 1 ) m r i ( t ) p i ( t ) R(T)=\sum_{(i=1)}^mr_i (t) p_i (t) R(T)=(i=1)mri(t)pi(t), r i ( t ) r_i (t) ri(t)
    为子节点i的错误率, p i ( t ) p_i (t) pi(t) 表示节点i的数据量占比

  • N(T)-表示子树的叶结点个数
    eg.在这里插入图片描述
    总样本量:55+25=80
    ① 对t4节点,
    错误占比: 4 46 + 4 \frac{4}{46+4} 46+44
    R ( t ) = r ( t ) ∗ p ( t ) R(t)=r(t)*p(t) R(t)=r(t)p(t),t4错误率占所有观测的占比情况: R ( t 4 ) = 4 50 ∗ 50 80 = 1 20 R(t4)=\frac{4}{50}*\frac{50}{80}=\frac{1}{20} R(t4)=5048050=201
    R ( T ) = ∑ ( i = 1 ) m r i ( t ) p i ( t ) R(T)=\sum^m_{(i=1)} r_i (t) p_i (t) R(T)=(i=1)mri(t)pi(t)
    t8和t9叶节点错误率: R ( T 4 ) = 1 45 ∗ 45 80 + 2 5 ∗ 5 80 = 3 80 R(T4)=\frac{1}{45}*\frac{45}{80}+\frac{2}{5}*\frac{5}{80}=\frac{3}{80} R(T4)=4518045+52805=803 (N(t)=2,两个叶节点)
    CCP误差为: α = R ( t ) − R ( T ) N ( T ) − 1 = 1 20 − 3 80 2 − 1 = 0.0125 α=\frac{R(t)-R(T)}{N(T)-1}=\frac{\frac{1}{20}-\frac{3}{80}}{2-1}=0.0125 α=N(T)1R(t)R(T)=21201803=0.0125
    ② 对于非叶子节点t3的子树
    节点错误率: 5 15 + 5 \frac{5}{15+5} 15+55
    t3节点错误占比: R ( t 3 ) = 5 20 ∗ 20 80 = 1 16 R(t3)=\frac{5}{20}*\frac{20}{80}=\frac{1}{16} R(t3)=2058020=161
    t6,t7的错误率: R ( T 3 ) = 1 5 ∗ 5 80 + 1 15 ∗ 15 80 = 1 40 R(T3)=\frac{1}{5}*\frac{5}{80}+\frac{1}{15}*\frac{15}{80}=\frac{1}{40} R(T3)=51805+1518015=401 (N(t)=2,两个叶节点)
    CCP误差为: α = R ( t ) − R ( T ) N ( T ) − 1 = 1 16 − 1 40 2 − 1 = 0.0375 α=\frac{R(t)-R(T)}{N(T)-1}=\frac{\frac{1}{16}-\frac{1}{40}}{2-1}=0.0375 α=N(T)1R(t)R(T)=21161401=0.0375
    ③ 对于非叶子节点t2的子树,
    节点误差占比: R ( t ) = r ( t ) ∗ p ( t ) = 10 60 ∗ 60 80 = 1 8 R(t)=r(t)*p(t)=\frac{10}{60}*\frac{60}{80}=\frac{1}{8} R(t)=r(t)p(t)=60108060=81
    对应叶子节点误差率: R ( T ) = ∑ ( i = 1 ) m r i ( t ) ∗ p i ( t ) = 1 45 ∗ 45 80 + 2 5 ∗ 5 80 + 0 6 ∗ 6 80 + 0 4 ∗ 4 80 = 3 80 R(T)=\sum_{(i=1)}^m r_i (t)*p_i (t)=\frac{1}{45}*\frac{45}{80}+\frac{2}{5}*\frac{5}{80}+\frac{0}{6}*\frac{6}{80}+\frac{0}{4}*\frac{4}{80}=\frac{3}{80} R(T)=(i=1)mri(t)pi(t)=4518045+52805+60806+40804=803,N(T)=4
    CCP误差为: α = R ( t ) − R ( T ) ( N ( T ) − 1 = 1 8 − 3 80 4 − 1 = 0.0292 α=\frac{R(t)-R(T)}{(N(T)-1}=\frac{\frac{1}{8}-\frac{3}{80}}{4-1}=0.0292 α=(N(T)1R(t)R(T)=4181803=0.0292 关于上面决策树的所有节点的α值计算结果为:(自下而上剪枝)
    T 0 : α ( t 4 ) = 0.0125 α ( t 5 ) = 0.05 α ( t 2 ) = 0.0292 α ( t 3 ) = 0.0375 T_0: α(t4)=0.0125 α(t5)=0.05 α(t2)=0.0292 α(t3)=0.0375 T0α(t4)=0.0125α(t5)=0.05α(t2)=0.0292α(t3)=0.0375(减去t4枝叶变为叶节点)
    T 1 : α ( t 5 ) = 0.05 α ( t 2 ) = 0.0375 α ( t 3 ) = 0.0375 T_1:α(t5)=0.05 α(t2)=0.0375 α(t3)=0.0375 T1α(t5)=0.05α(t2)=0.0375α(t3)=0.0375(t2与t3的α 值相同,但是裁剪掉前者可以得到更小的决策树,减去t2变为叶节点)
    以上就是CCP代价复杂度剪枝的全过程。

决策树的Python实现

例子依然采用上述手算例:

日志密度好友密度是否使用真实头像账户是否真实
slyesyes
mlnoyes
lmyesyes
mmyesyes
lmyesyes
lmnoyes
ssnono
msnono
msnoyes
ssyesno

1、导入需要的包

import pandas as pd
import numpy as np
from sklearn import tree
from sklearn.preprocessing import LabelEncoder

2、读入数据

data = pd.read_csv('data/example.csv',engine='python')
data

3、数据处理

# 多值型分类变量转化
x1 = pd.get_dummies(pd.DataFrame(data['日志密度'].values.tolist()),prefix='日志密度',prefix_sep='_',drop_first=True).\
groupby(axis=1,level=0).max()

x2 = pd.get_dummies(pd.DataFrame(data['好友密度'].values.tolist()),prefix='好友密度',prefix_sep='_',drop_first=True).\
groupby(axis=1,level=0).max()

del data['日志密度']
del data['好友密度']

data = pd.concat([data,x1,x2],axis=1)
data

# 二值型变量转化
data['是否使用真实头像'] =  LabelEncoder().fit_transform(np.array(data['是否使用真实头像']))
data['账户是否真实'] =  LabelEncoder().fit_transform(np.array(data['账户是否真实']))

4、数据转化

y = data['账户是否真实']
x = data.drop(['账户是否真实'],axis=1)

5、建模

tree_model = tree.DecisionTreeClassifier(criterion='gini')
tree_model.fit(x,y)

6、画决策树

import graphviz

dot_data = tree.export_graphviz(tree_model,
                               out_file=None,
                               feature_names= ['是否使用真实头像', '日志密度_m', '日志密度_s', '好友密度_m', '好友密度_s'],
                               class_names= ['no','yes'],
                               filled=True,
                               rounded=True,
                               special_characters=True)

graph = graphviz.Source(dot_data)
graph

得到如下图:
在这里插入图片描述
可见,和上述手算例得到相同结果!
决策树在真实数据集上的R语言和python实现及其调参结果请戳☞决策树的R与PYTHON调参对比☜

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值