参考博客:决策树基础篇之让我们从相亲说起 (po主Jack-Cui,《——大部分内容转载自
信息熵与ID3算法参考 (po主青松愉快,
参考书籍:《机器学习实战》——第三章
一 决策树
1 概念介绍
决策树(decision tree)是一种基本的分类与回归方法。以下讲的是分类决策树。
用《机器学习实战》——第三章的例子来说,一个简单的邮件分类流程如下,包含判断模块(矩形)、终止模块(椭圆)、分支(左右箭头),到达终止模块后停止运行并得到分类。
用比较术语的说法是:
分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点(node)和有向边(directed edge)组成。结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类。
我们可以把决策树看成一个if-then规则的集合,将决策树转换成if-then规则的过程是这样的:由决策树的根结点(root node)到叶结点(leaf node)的每一条路径构建一条规则;路径上内部结点的特征对应着规则的条件,而叶结点的类对应着规则的结论。决策树的路径或其对应的if-then规则集合具有一个重要的性质:互斥并且完备。这就是说,每一个实例都被一条路径或一条规则所覆盖,而且只被一条路径或一条规则所覆盖。这里所覆盖是指实例的特征与路径上的特征一致或实例满足规则的条件。
2 流程
使用决策树做预测需要以下过程:
决策树构建这一过程可以概括为3个步骤:特征选择、决策树的生成和决策树的修剪。
- 收集数据:可以使用任何方法得到一些供我们利用的数据。
- 准备数据:收集完的数据,我们要进行整理,将这些所有收集的信息按照一定规则整理出来,并排版,方便我们进行后续处理。
- 分析数据:可以使用任何方法,决策树构造完成之后,我们可以检查决策树图形是否符合预期。
- 训练算法:这个过程也就是构造决策树,同样也可以说是决策树学习,就是构造一个决策树的数据结构。
- 测试算法:使用经验树计算错误率。当错误率达到了可接收范围,这个决策树就可以投放使用了。
- 使用算法:此步骤可以使用适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义。
3 划分数据集—特征选择
每一个判断节点都是将数据集划分的依据,划分后目的在于能够正确的将一类数据尽可能的划分到一起,不断的划分数据子集,直到所有具有相同类型的数据均在一个数据子集内。
划分数据的原则是将无序数据变得更加有序,如何度量划分前后数据的变化?
3.1信息增益与香农熵
信息论中,将划分数据集前后信息发生的变化称为信息增益(information gain)。
在决策树分类问题中,信息增益就是决策树在进行属性选择划分前和划分后信息的差值。
如何计算这种信息的变化?信息熵是其中一种。在1948年,香农引入了信息熵(又称香浓熵shannon entropy),将其定义为离散随机事件出现的概率,一个系统越 是有序,信息熵就越低,反之一个系统越是混乱,它的信息熵就越高。所以信息熵可以被认为是系统有序化程度的一个度量。
3.2 信息熵计算
熵定义为信息的期望值。在信息论与概率统计中,熵是表示随机变量不确定性的度量。如果待分类的事务可能划分在多个分类之中,则符号xi的信息定义为
其中p(xi)是选择该分类的概率。通过上式,我们可以得到所有类别的信息。
为了计算熵,我们需要计算所有类别所有可能值包含的信息期望值(数学期望),通过下面的公式得到:
其中n是分类的数目。一个变量的变化情况可能越多,那么它携带的信息量就越大。
对于分类系统来说,类别是变量,它的取值是,(即有n个类)而每一个类别出现的概率分别是
其中P(Ck) = |Ck| / |D|,其中|Ck|为类Ck的数据个数,|D|为数据总个数。这种概率由数据估计(特别是最大似然估计)得到的方法的熵称为经验熵(empirical entropy)。这概率是我们根据数据数出来的。将熵公式中的概率用P(Ck) = |Ck| / |D|替代,则经验熵公式如下:
3.3 信息增益计算
这么多信息,浅显的总结一下就是:
- 信息增益是信息前后的变化,这里选用熵来衡量信息量,划分前后熵的差值为信息增益
- 熵越小, 系统越有序(so 越小越好)
- 用 数据估计的概率 计算的熵称为 经验熵
3.2 经验熵python代码
伪代码:
1 创建/读取数据集
2计算每个类的数据数量
3 公式计算
数据集demo选取如下(部分截图),这是一个贷款申请系统,系统根据用户特征(年龄,是否有工作,是否有房子,信贷情况),预测判断类别(是否放贷)。
def createDataSet():
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']]
labels = ['年龄', '有工作', '有自己的房子', '信贷情况'] #特征属性
return dataSet, labels #返回数据集和特征属性
def calcShannonEnt(dataSet):
#返回数据集行数
numEntries=len(dataSet)
#保存每个标签(label)出现次数的字典
labelCounts={}
#对每组特征向量进行统计
for featVec in dataSet:
currentLabel=featVec[-1] #提取标签信息
if currentLabel not in labelCounts.keys(): #如果标签没有放入统计次数的字典,添加进去
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1 #label计数
shannonEnt=0.0 #经验熵
#计算经验熵
for key in labelCounts:
prob=float(labelCounts[key])/numEntries #选择该标签的概率
shannonEnt-=prob*log(prob,2) #利用公式计算
return shannonEnt #返回经验熵
3.3 数据集划分
有个衡量划分数据集的标准——熵,那么接下来该划分数据集了。
书《机器学习实战》chapter3 上采用ID3算法——按照每个特征划分数据集。下面代码先以此为例然后后面再总结写有哪些划分算法。
ID3算法的核心思想: 在决策树的每一个非叶子结点划分之前,先计算每一个属性所带来的信息增益,选择最大信息增益的属性来划分,因为信息增益越大,区分样本的能力就越强,越具有代表性,很显然这是一种自顶向下的贪心策略。
算法总结