决策树
说明:这篇博客是看李航老师的《统计学习方法》做的笔记总结,博客中有很多内容是摘选自李航老师的《统计学习方法》一书,仅供学习交流使用。
决策树(decision tree)是一种基本的分类与回归方法。主要讨论用于分类的决策树。
决策树模型呈树形结构,在分类问题中,表示基于特征对实例进行分类的过程。它可以认为是if-then规则集合,也可以认为是定义在特征空间与类空间上的条件概率分布。其主要优点是模型具有可读性,分类速度快。
简单来说,决策树就是一棵树,一颗决策树包含一个根节点、若干个内部结点和若干个叶结点;叶结点对应于决策结果,其他每个结点则对应于一个特征测试;分类的具体操作是从根节点开始,对实例的每一特征进行测试,根据测试结果,将实例分配到其子节点;这时,每一个子节点对应着给特征的一个取值。如此递归地对实例进行测试并分配,直至达到叶节点。最后将实例分到叶节点的类中。下面直接上个图,帮助大家理解一下:
| 名字 | 体温 | 胎生 | 类别 |
|---|---|---|---|
| 小狗狗 | 恒温 | 是 | 哺乳动物 |

注:圆框代表内部节点,方框代表叶节点。
决策树通常包括三个步骤:特征选择、决策树的生成和决策树的修剪。
决策树学习的目标:根据给定的训练数据集构建一个决策树模型,使它能够对实例进行正确的分类。
决策树学习的本质:从训练数据集中归纳出一组分类规则。
决策树学习的策略:以损失函数为目标函数的最小化。
特征选择
特征选择在于选取对训练数据具有分类能力的特征。这样可以提高决策树学习的效率,如果利用一个特征进行分类的结果与随机分类的结果没有很大差别,则称这个特征是没有分类能力的。经验上扔掉这样的特征对决策树学习的精度影响不大。通常特征选择的准则是信息增益或信息增益比。
简单来说,就是找出比较好的特征来划分特征空间。比如判断是否为哺乳动物这个例子,其中有体温和胎生两个特征,那么选哪一个作为根节点呢?而特征选择就是用来解决这个问题的方法。
经验熵、经验条件熵
为了便于说明,这里先给出熵和条件熵的定义。
在信息论与概率统计中,熵(entropy)是表示随机变量不确定性的度量。设X是一个取有限个值的离散随机变量,其概率分布为
P(X=xi)=pi,i=1,2,…,n
P(X=x_i)=p_i,i=1,2,\dots,n
P(X=xi)=pi,i=1,2,…,n
则随机变量X的熵定义为
H(X)=−∑i=1npilog2pi
H(X)=-\sum_{i=1}^np_ilog_2p_i
H(X)=−i=1∑npilog2pi
熵越大,随机变量的不确定性就越大。
为了更好的理解熵与不确定性的关系,我们可以举一个例子
如一个普通的骰子A,扔出1-6的概率均为1/6
假设一个骰子B,扔出6的概率为50%,扔出1-5的概率为10%
则骰子A的熵为−(16log216)∗6≈2.585-(\frac{1}{6}log_2\frac{1}{6})*6≈2.585−(61log261)∗6≈2.585
骰子B的熵为−12log212−110log2110∗5≈2.161-\frac{1}{2}log_2\frac{1}{2}-\frac{1}{10}log_2\frac{1}{10}*5≈2.161−21log221−101log2101∗5≈2.161
条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性。随机变量X给定条件下随机变量Y的条件熵(conditional entropy)H(Y|X),定义为X给定条件下Y的条件概率分布的熵对X的数学期望
H(Y∣X)=∑i=1npiH(Y∣X=xi)
H(Y|X)=\sum_{i=1}^np_iH(Y|X=x_i)
H(Y∣X)=i=1∑npiH(Y∣X=xi)
这里,pi=P(x=xi),i=1,2,…,np_i=P(x=x_i),i=1,2,\dots,npi=P(x=xi),i=1,2,…,n。
当熵和条件熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的熵和条件熵分别成为经验熵和经验条件熵。
假设现在有一个数据集D,|D|表示数据集D的样本容量,即样本个数。而样本中有K个类(k=1,2,…,Kk=1,2,\dots,Kk=1,2,…,K),∣Ck∣|C_k|∣Ck∣为属于类CkC_kCk的样本数。
此时在数据集D上,经验熵的公式为
H(D)=−∑k=1K∣Ck∣∣D∣log2∣Ck∣∣D∣
H(D)=-\sum_{k=1}^K\frac{|C_k|}{|D|}log_2\frac{|C_k|}{|D|}
H(D)=−k=1∑K∣D∣∣Ck∣log2∣D∣∣Ck∣
同样在上述的数据集中,特征A的取值有n个(数据集中有n个特征),其取值将数据集D划分为了n个小的子集DiD_iDi,而子集DiD_iDi属于类CkC_kCk的样本集合记为DikD_{ik}Dik,即Dik=Di∩CkD_{ik}=D_i∩C_kDik=Di∩Ck。
那么特征A对数据集D的经验条件熵H(D|A)
H(D∣A)=∑i=1n∣Di∣∣D∣H(Di)=−∑i=1n∣Di∣∣D∣∑k=1K∣Dik∣∣Di∣log2∣Dik∣∣Di∣
H(D|A)=\sum_{i=1}^n\frac{|D_i|}{|D|}H(D_i)=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}log_2\frac{|D_{ik}|}{|D_i|}
H(D∣A)=i=1∑n∣D∣∣Di∣H(Di)=−i=1∑n∣D∣∣Di∣k=1∑K∣Di∣∣Dik∣log2∣Di∣∣Dik∣
为了更好的理解公式,这里引入《统计学习方法》书中的例子
| ID | 年龄 | 有工作 | 有自己的房子 | 信贷情况 | 类别 |
|---|---|---|---|---|---|
| 1 | 青年 | 否 | 否 | 一般 | 否 |
| 2 | 青年 | 否 | 否 | 好 | 否 |
| 3 | 青年 | 是 | 否 | 好 | 是 |
| 4 | 青年 | 是 | 是 | 一般 | 是 |
| 5 | 青年 | 否 | 否 | 一般 | 否 |
| 6 | 中年 | 否 | 否 | 一般 | 否 |
| 7 | 中年 | 否 | 否 | 好 | 否 |
| 8 | 中年 | 是 | 是 | 好 | 是 |
| 9 | 中年 | 否 | 是 | 非常好 | 是 |
| 10 | 中年 | 否 | 是 | 非常好 | 是 |
| 11 | 老年 | 否 | 是 | 非常好 | 是 |
| 12 | 老年 | 否 | 是 | 好 | 是 |
| 13 | 老年 | 是 | 否 | 好 | 是 |
| 14 | 老年 | 是 | 否 | 非常好 | 是 |
| 15 | 老年 | 否 | 否 | 一般 | 否 |
该例中类别CkC_kCk的取值有两个否和是,C否=6,C是=9C_否=6,C_是=9C否=6,C是=9,则经验熵为
H(D)=−∑k=1K∣Ck∣∣D∣log2∣Ck∣∣D∣=−∣C否∣∣D∣log2∣C否∣∣D∣−∣C是∣∣D∣log2∣C是∣∣D∣=−615log2615−915log2915=0.971 \begin{aligned} H(D)&=-\sum_{k=1}^K\frac{|C_k|}{|D|}log_2\frac{|C_k|}{|D|} \\ &=-\frac{|C_否|}{|D|}log_2\frac{|C_否|}{|D|}-\frac{|C_是|}{|D|}log_2\frac{|C_是|}{|D|} \\ &=-\frac{6}{15}log_2\frac{6}{15}-\frac{9}{15}log_2\frac{9}{15} =0.971 \end{aligned} H(D)=−k=1∑K∣D∣∣Ck∣log2∣D∣∣Ck∣=−∣D∣∣C否∣log2∣D∣∣C否∣−∣D∣∣C是∣log2∣D∣∣C是∣=−156log2156−159log2159=0.971
该例中第一个特征的取值有3个,其中D1=D2=D3=5D_1=D_2=D_3=5D1=D2=D3=5,D1否=3,D1是=2D_{1否}=3,D_{1是}=2D1否=3,D1是=2,D2否=2,D2是=3D_{2否}=2,D_{2是}=3D2否=2,D2是=3,D3否=1,D3是=4D_{3否}=1,D_{3是}=4D3否=1,D3是=4,则经验条件熵为
H(D∣A1)=−∑i=1n∣Di∣∣D∣∑k=1K∣Dik∣∣Di∣log2∣Dik∣∣Di∣=−∣D1∣∣D∣∑k=1K∣D1k∣∣D1∣log2∣D1k∣∣D1∣−∣D2∣∣D∣∑k=1K∣D2k∣∣D2∣log2∣D2k∣∣D2∣−∣D3∣∣D∣∑k=1K∣D3k∣∣D3∣log2∣D3k∣∣D3∣=−515(35log235+25log225)−515(25log225+35log235)−515(15log215+45log245)=0.8879432≈0.888 \begin{aligned} H(D|A_1)&=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}log_2\frac{|D_{ik}|}{|D_i|} \\ &=-\frac{|D_1|}{|D|}\sum_{k=1}^K\frac{|D_{1k}|}{|D_1|}log_2\frac{|D_{1k}|}{|D_1|}-\frac{|D_2|}{|D|}\sum_{k=1}^K\frac{|D_{2k}|}{|D_2|}log_2\frac{|D_{2k}|}{|D_2|}-\frac{|D_3|}{|D|}\sum_{k=1}^K\frac{|D_{3k}|}{|D_3|}log_2\frac{|D_{3k}|}{|D_3|} \\ &=-\frac{5}{15}(\frac{3}{5}log_2\frac{3}{5}+\frac{2}{5}log_2\frac{2}{5})-\frac{5}{15}(\frac{2}{5}log_2\frac{2}{5}+\frac{3}{5}log_2\frac{3}{5})-\frac{5}{15}(\frac{1}{5}log_2\frac{1}{5}+\frac{4}{5}log_2\frac{4}{5}) \\ &=0.8879432≈0.888 \end{aligned} H(D∣A1)=−i=1∑n∣D∣∣Di∣k=1∑K∣Di∣∣Dik∣log2∣Di∣∣Dik∣=−∣D∣∣D1∣k=1∑K∣D1∣∣D1k∣log2∣D1∣∣D1k∣−∣D∣∣D2∣k=1∑K∣D2∣∣D2k∣log2∣D2∣∣D2k∣−∣D∣∣D3∣k=1∑K∣D3∣∣D3k∣log2∣D3∣∣D3k∣=−155(53log253+52log252)−155(52log252+53log253)−155(51log251+54log254)=0.8879432≈0.888第二个特征(有工作)的取值有2两个,其中D1=10(没有工作),D2=5(有工作)D_1=10(没有工作),D_2=5(有工作)D1=10(没有工作),D2=5(有工作),D1否=6,D1是=4D_{1否}=6,D_{1是}=4D1否=6,D1是=4,D2是=5D_{2是}=5D2是=5,则经验条件熵为
H(D∣A1)=−∑i=1n∣Di∣∣D∣∑k=1K∣Dik∣∣Di∣log2∣Dik∣∣Di∣=−1015H(D1)−515H(D2)=−1015(410log2410+610log2610)−515∗0≈0.324 \begin{aligned} H(D|A_1)&=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}log_2\frac{|D_{ik}|}{|D_i|} \\ &=-\frac{10}{15}H(D_1)-\frac{5}{15}H(D_2) \\ &=-\frac{10}{15}(\frac{4}{10}log_2\frac{4}{10}+\frac{6}{10}log_2\frac{6}{10})-\frac{5}{15}*0 \\ &≈0.324 \end{aligned} H(D∣A1)=−i=1∑n∣D∣∣Di∣k=1∑K∣Di∣∣Dik∣log2∣Di∣∣Dik∣=−1510H(D1)−155H(D2)=−1510(104log2104+106log2106)−155∗0≈0.324
其他特征同理。
代码实现经验熵、经验条件熵
代码实现经验熵计算
from math import log
# 数据集
dataSet=[[0, 0, 0, 0, 'no'],
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
#数据集D的样本个数
num_D=len(dataSet)
#记录类别的字典
labelCounts={}
#记录数据集中的类别,并统计其个数
for featVec in dataSet:
currentLabel=featVec[-1] #读取类别信息
if currentLabel not in labelCounts.keys(): #如果读取的类别没有放入统计次数的字典,添加进去
labelCounts[currentLabel]=0 #默认值为0
labelCounts[currentLabel]+=1 #计数
entropy=0.0 #经验熵
#计算经验熵
for key in labelCounts:
prob=float(labelCounts[key])/num_D
entropy-=prob*log(prob,2) #利用公式计算
print("数据集D的经验熵H(D):",format(entropy,'.3f'))
数据集D的经验熵H(D): 0.971
代码实现经验条件熵计算
from math import log
# 数据集
dataSet=[[0, 0, 0, 0, 'no'],
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
'''
将数据集D按照特征划分为一个个子集
'''
def splitDataSet(dataSet, axis, value):
retDataSet=[]
for featVec in dataSet:
if featVec[axis] == value:
reduceFeatVec=featVec[:axis]
reduceFeatVec.extend(featVec[axis+1:])
retDataSet.append(reduceFeatVec)
return retDataSet
'''
计算数据集的经验熵
'''
def empiricalEnt(dataSet):
#数据集D的样本个数
num_D=len(dataSet)
#记录类别的字典
labelCounts={}
#记录数据集中的类别,并统计其个数
for featVec in dataSet:
currentLabel=featVec[-1] #读取类别信息
if currentLabel not in labelCounts.keys(): #如果读取的类别没有放入统计次数的字典,添加进去
labelCounts[currentLabel]=0 #默认值为0
labelCounts[currentLabel]+=1 #计数
entropy=0.0 #经验熵
#计算经验熵
for key in labelCounts:
prob=float(labelCounts[key])/num_D
entropy-=prob*log(prob,2) #利用公式计算
return entropy
'''
计算经验条件熵
'''
#特征数
features = len(dataSet[0])-1
for i in range(features):
#获取第i个特征的所有值
featList = [example[i] for example in dataSet]
#创建集合uniqueValue,元素不可重复
uniqueValue = set(featList)
#经验条件熵
conditionalEnt = 0.0
#计算经验信息熵
for value in uniqueValue:
#划分子集
subDataSet = splitDataSet(dataSet, i, value)
#子集与原数据集之比
prob = len(subDataSet)/float(len(dataSet))
#子集经验熵
conditionalEnt += prob*empiricalEnt(subDataSet)
print(format(conditionalEnt,'.3f'))
'''
info = empiricalEnt(dataSet)-conditionalEnt
print('第%d个特征的信息增益%.3f' %(i, info))
'''
0.888
0.647
0.551
0.608
信息增益
特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即
g(D,A)=H(D)−H(D∣A)
g(D,A)=H(D)-H(D|A)
g(D,A)=H(D)−H(D∣A)
其中经验熵H(D)表示对数据集D进行分类的不确定性,而经验条件熵H(D|A)表示在特征A给定的条件下对数据集D进行分类的不确定性。那么**信息增益就表示由于特征A而使得对数据集D进行分类得不确定性减少的程度。**那么在进行分类的时候肯定选择信息增益大的作为根节点。
而对信息增益的代码实现也很简单,只需要在上述经验条件熵的第二个for循环后加上如下代码即可
info = empiricalEnt(dataSet)-conditionalEnt
print('第%d个特征的信息增益%.3f' %(i, info))
第0个特征的信息增益0.083
第1个特征的信息增益0.324
第2个特征的信息增益0.420
第3个特征的信息增益0.363
信息增益比
在使用信息增益作为划分训练数据集的特征时,存在偏向于选择取值较多的特征的问题,使用信息增益比可以对这一问题进行校正。
定义:特征A对训练数据集D的信息增益比gR(D,A)g_R(D,A)gR(D,A)定义为其信息增益g(D,A)与训练数据集D关于特征A的值的熵HA(D)H_A(D)HA(D)之比,即
gR(D,A)=g(D,A)HA(D)
g_R(D,A)=\frac{g(D,A)}{H_A(D)}
gR(D,A)=HA(D)g(D,A)
其中,HA(D)=−∑i=1n∣Di∣∣D∣log2∣Di∣∣D∣H_A(D)=-\sum_{i=1}^n\frac{|D_i|}{|D|}log_2\frac{|D_i|}{|D|}HA(D)=−∑i=1n∣D∣∣Di∣log2∣D∣∣Di∣,n是特征A的取值个数。
参考文章:
https://blog.youkuaiyun.com/u012328159/article/details/70184415
https://blog.youkuaiyun.com/jiaoyangwm/article/details/79525237
本文详细介绍了决策树的学习过程,包括特征选择、决策树生成和修剪。通过实例解释了熵、条件熵、信息增益和信息增益比的概念,用于评估特征的重要性。并提供了Python代码实现信息熵和信息增益的计算,展示了如何根据信息增益选择最佳划分特征。
1732

被折叠的 条评论
为什么被折叠?



