决策树
决策树是什么?决策树(decision tree)是一种基本的分类与回归方法。顾名思义,决策树是基于树结构来进行决策的。决策过程的最终结论对应了我们所希望的判定结果,决策过程中提出的每个判定问题都是对某个属性的测试。每个测试的结果或是导出最终结论,或是导出进一步的判定问题,其考虑范国是在上次决策结果的限定范围之内。一般的,一棵决策树包含一个根结点、若干个内部结点和若干个叶结点;叶结点对应于决策结果?其他每个结点则对应于一个属性测试;每个结点包含的样本集合根据属性测试的结果被划分到子结点中;根结点包含样本全集.从根结点到每个叶结点的路径对应了一个判定测试序列.
决策树的目的
目的是为了产生一棵泛化能力强,即处理未见示例能力强的决策树,其基本流程遵循简单且直观的"分而治之" (divide-and-conquer) 策略
什么时候不需划分
(1) 当前结点包含的样本全属于同一类别,无需划分;
(2) 当前属性集为空,或是所有样本在所有属性上取值相同,无法划分;
(3) 当前结点包含的样本集合为空,不能划分.
划分选择
决策树最重要的即如何选择最优划分属性一般而言,随着划分过程不断进行,我们希望决策树的分支结点所包含的样本尽可能属于同一类别,即结点的"纯度" (purity) 越来越高.
信息熵
信息熵是度量样本集合纯度最常用的一种指标.假定当前样本集合 中第 类样本所占的比例为 Pk(k = 1, 2,. . . , IyI) ,则D的信息熵定义为:
Ent(D)越小,则D的纯度越大。Ent(D)的最小值是0,最大值是log2|y|。
经验熵
当信息熵中的概率由数据估计(特别是最大似然估计)得到时,所对应的信息熵称为经验熵(empirical entropy)。什么叫由数据估计?比如有10个数据,一共有两个类别,A类和B类。其中有7个数据属于A类,则该A类的概率即为十分之七。其中有3个数据属于B类,则该B类的概率即为十分之三。浅显的解释就是,这概率是我们根据数据数出来的
接下来编写代码计算经验熵(信息熵)
def calcShannonEnt(dataSet):
numEntires = len(dataSet)
labelCounts = {}
for featVec in dataSet:
currentLabel = featVec[-1]
if currentLabel not in labelCounts:
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key]) / numEntires
shannonEnt -= prob * log(prob, 2)
return shannonEnt
注解
log(x, y)
返回的是以y为底x为对数的值。
使用决策树做预测需要以下过程:
1 收集数据:可以使用任何方法。比如想构建一个相亲系统,我们可以从媒婆那里,或者通过参访相亲对象获取数据。根据他们考虑的因素和最终的选择结果,就可以得到一些供我们利用的数据了。
2 准备数据:收集完的数据,我们要进行整理,将这些所有收集的信息按照一定规则整理出来,并排版,方便我们进行后续处理
3 分析数据:可以使用任何方法,决策树构造完成之后,我们可以检查决策树图形是否符合预期。
4 训练算法:这个过程也就是构造决策树,同样也可以说是决策树学习,就是构造一个决策树的数据结构。
5 测试算法:使用经验树计算错误率。当错误率达到了可接收范围,这个决策树就可以投放使用了。
6 使用算法:此步骤可以使用适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义
决策树要如何构建呢?通常,这一过程可以概括为3个步骤:特征选择、决策树的生成和决策树的修剪
决策树的一些优点
1 易于理解和解释,决策树可以可视化。
2 几乎不需要数据预处理。其他方法经常需要数据标准化,创建虚拟变量和删除缺失值。决策树还不支持缺失值
3 使用树的花费(例如预测数据)是训练数据点(data points)数量的对数
4 可以同时处理数值变量和分类变量。其他方法大都适用于分析一种变量的集合。
5 可以处理多值输出变量问题
6 使用白盒模型。如果一个情况被观察到,使用逻辑判断容易表示这种规则。相反,如果是黑盒模型(例如人工神经网络),结果会非常难解释
7 即使对真实模型来说,假设无效的情况下,也可以较好的适用。
决策树的一些缺点:
1 决策树学习可能创建一个过于复杂的树,并不能很好的预测数据。也就是过拟合。修剪机制(现在不支持),设置一个叶子节点需要的最小样本数量,或者数的最大深度,可以避免过拟合。
2 决策树可能是不稳定的,因为即使非常小的变异,可能会产生一颗完全不同的树。这个问题通过decision trees with an ensemble来缓解
3 学习一颗最优的决策树是一个NP-完全问题under several aspects of optimality and even for simple concepts。因此,传统决策树算法基于启发式算法,例如贪婪算法,即每个节点创建最优决策。这些算法不能产生一个全家最优的决策树。对样本和特征随机抽样可以降低整体效果偏差
4 概念难以学习,因为决策树没有很好的解释他们,例如,XOR, parity or multiplexer problems.
5 如果某些分类占优势,决策树将会创建一棵有偏差的树。因此,建议在训练之前,先抽样使样本均衡
划分数据集的大原则是:将无序的数据变的更加有序。
划分数据集之前之后信息发生的变化称为信息增益
获得信息增益最高的特征就是最好的选择
集合信息的度量方式称为香浓熵或者简称为熵
如果看不明白什么是信息增益和熵,请不要着急,因为他们自诞生的那一天起,就注定会令世人十分费解。克劳德·香农写完信息论之后,约翰·冯·诺依曼建议使用"熵"这个术语,因为大家都不知道它是什么意思
熵定义为信息的期望值。在信息论与概率统计中,熵是表示随机变量不确定性的度量。如果待分类的事务可能划分在多个分类之中,则符号xi的信息定义为
其中p(xi)是选择该分类的概率。有人可能会问,信息为啥这样定义啊?答曰:前辈得出的结论。这就跟1+1等于2一样,记住并且会用即可。上述式中的对数以2为底,也可以e为底(自然对数)。
通过上式,我们可以得到所有类别的信息。为了计算熵,我们需要计算所有类别所有可能值包含的信息期望值(数学期望),通过下面的公式得到:
其中n是分类的数目。熵越大,随机变量的不确定性就越大
下面我们将学习使用python计算信息熵。
def calcShannonEnt(dataSet):
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)
return shannonEnt
def createDataSet():
dataSet = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
labels = ['no surfacing','flippers']
return dataSet, labels
>>> import trees
>>> myDat,labels=trees.createDataSet()
>>> myDat
[[1, 1, 'yes'], [1,