决策树及其随机森林——学习笔记
介绍:
决策树(Decision Tree)是一种基本的分类与回归方法,本文主要讨论分类决策树。决策树模型呈树形结构,在分类问题中,表示基于特征对实例进行分类的过程。它可以认为是if-then规则的集合,也可以认为是定义在特征空间与类空间上的条件概率分布。相比朴素贝叶斯分类,决策树的优势在于构造过程不需要任何领域知识或参数设置,因此在实际应用中,对于探测式的知识发现,决策树更加适用。
一、决策树模型
1、定义
分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点和有向边组成。结点有两种类型:内部节点和叶节点,内部节点表示一个特征或属性,叶节点表示一个类。
分类的时候,从根节点开始,对实例的某一个特征进行测试,根据测试结果,将实例分配到其子结点;此时,每一个子结点对应着该特征的一个取值。如此递归向下移动,直至达到叶结点,最后将实例分配到叶结点的类中。
举一个通俗的栗子,各位立志于脱单的单身男女在找对象的时候就已经完完全全使用了决策树的思想。假设一位母亲在给女儿介绍对象时,有这么一段对话:
母亲:给你介绍个对象。
女儿:年纪多大了?
母亲:26。
女儿:长的帅不帅?
母亲:挺帅的。
女儿:收入高不?
母亲:不算很高,中等情况。
女儿:是公务员不?
母亲:是,在税务局上班呢。
女儿:那好,我去见见。
这个女生的决策过程就是典型的分类决策树。相当于对年龄、外貌、收入和是否公务员等特征将男人分为两个类别:见或者不见。假设这个女生的决策逻辑如下:
2、决策树与if-then规则
现在我们可以更抽象一些。决策树可以看成一个if-then规则的集合:由决策树的根结点到叶结点的每一条路径构建一条规则;路径上的内部结点的特征对应着规则的条件,而叶结点对应着分类的结论。决策树的路径和其对应的if-then规则集合是等效的,它们具有一个重要的性质:互斥并且完备。这里的意思是说:每一个实例都被一条路径或一条规则所覆盖,而且只被一条规则所覆盖。
3、决策树与条件概率分布
决策树还是给定特征条件下类的条件概率分布的一种表示。该条件分布定义在特征空间的划分(partition)上,特征空间被划分为互不相交的单元(cell),每个单元定义一个类的概率分布就构成了一个条件概率分布。决策树的一条路径对应于划分中的一个单元。决策树所表示的条件概率分布由各个单元给定条件下类的条件概率分布组成。给定实例的特征X,一定落入某个划分,决策树选取该划分里最大概率的类作为结果输出。如图:
图(a)表示该实例的特征向量是二维的(即具有两个特征),图(b)表示给定特征X分类属于+1类的条件概率分布。图中的方块有些地方完全没有,比如x(2)轴上[a2,1]这个区间,说明只要X落在这里,Y就一定是-1的,同理对于[0,a1]和[0,a2]围起来的一定是+1的。有些地方只有一半,比如x(1)轴上[a1,1]这个区间,说明决策树认为X落在这里,Y只有一半概率是+1的,根据选择条件概率大的类别的原则,就认为Y是−1的(因为不满足P(Y=+1|X)>0.5)。
4.决策树的学习
决策树学习算法包含特征选择、决策树的生成与剪枝过程。决策树的学习算法通常是递归地选择最优特征,并用最优特征对数据集进行分割。开始时,构建根结点,选择最优特征,该特征有几种值就分割为几个子集,每个子集分别递归调用此方法,返回结点,返回的结点就是上一层的子结点。直到所有特征都已经用完,或者数据集只有一维特征为止。
二、特征选择
特征选择问题希望选取对训练数据具有良好分类能力的特征,这样可以提高决策树学习的效率。如果利用一个特征进行分类的结果与随机分类的结果没有很大差别,则称这个特征是没有分类能力的(对象是否喜欢打游戏应该不会成为关键特征吧,也许也会……)。为了解决特征选择问题,找出最优特征,先要介绍一些信息论里面的概念。
1、熵(entropy)
熵是表示随机变量不确定性的度量。设X是一个取有限个值的离散随机变量,其概率分布为
另外, 0log0=0 0 l o g 0 = 0 ,当对数的底为2时,熵的单位为bit;为e时,单位为nat。
熵越大,随机变量的不确定性就越大。从定义可验证
python如下:
def calcShannonEnt(dataSet):
'''
计算香农熵
:param dataSet:数据集
:return: 计算结果
'''
numEntries = len(dataSet)
labelCounts = {}
for featVec in dataSet: # 遍历每个实例,统计标签的频数
currentLabel = featVec[-1]
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key]) / numEntries
shannonEnt -= prob * log(prob,2) # 以2为底的对数
return shannonEnt
2.条件熵(conditional entropy)
设随机变量
(X,Y)
(
X
,
Y
)
,其联合概率分布为:
这里, pi=P(X=xi),i=1,2,...,n p i = P ( X = x i ) , i = 1 , 2 , . . . , n
python实现如下:
def splitDataSet(dataSet, axis, value):
'''
按照给定特征划分数据集
:param dataSet:待划分的数据集
:param axis:划分数据集的特征
:param value: 需要返回的特征的值
:return: 划分结果列表
'''
retDataSet = []
for featVec in dataSet:
if featVec[axis] == value:
reducedFeatVec = featVec[:axis] #chop out axis used for splitting
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet
def calcConditionalEntropy(dataSet, i, featList, uniqueVals):
'''
计算X_i给定的条件下,Y的条件熵
:param dataSet:数据集
:param i:维度i
:param featList: 数据集特征列表
:param uniqueVals: 数据集特征集合
:return: 条件熵
'''
conditionEnt = 0.0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet, i, value)
prob = len(subDataSet) / float(len(dataSet)) # 极大似然估计概率
conditionEnt += prob * calcShannonEnt(subDataSet) # 条件熵的计算
return conditionEnt
3.信息增益(information gain)
信息增益是指在得知特征
X
X
的条件下,类别的信息的不确定性减少的程度。特征
A
A
对数据集的信息增益
gain(D,A)
g
a
i
n
(
D
,
A
)
定义为:数据集
D
D
的经验熵减去在给定特征
A
A
的条件下的经验熵
H(D|A)
H
(
D
|
A
)
:
这个差,又叫做 互信息,信息增益(互信息)越大的特征,具有越强的分类能力。
根据信息增益准则的特征选择方法是:对训练数据集(或子集)计算其每个特征的信息增益,选择信息增益最大的特征。
计算信息增益的算法如下:
输入:训练数据集 D D 和特征;
输出:特征 A A 对训练数据集的信息增益 g(D,A) g ( D , A ) .
(1)计算数据集 D D 的经验熵:
(2)计算特征A对数据集D的经验条件熵 H(D|A) H ( D | A )