您的位置:首页 > 其它

机器学习---决策树

2014-06-23 14:17 381 查看
转载:/article/9111585.html?reload
应为要用到迭代决策树,就先学了决策树。主要参考《机器学习实战》。

一、决策树概念

决策树原理很简单,一个流程图就能明白。



图中构造了一个假想的邮件系统,通过检测域名地址和是否包含单词“曲棍球”来将邮件分类。
决策树也有分类树和回归树的分别。常见的分类数就是id3和c4.5,回归树有cart。
分类树就像上图进行分类,回归树在每个节点都会得一个预测值,以年龄为例,该预测值等于属于这个节点的所有人平均年龄。
接下来以ID3分类数为例,介绍决策树的构造。
关于决策树的原理和c++实现,可以看此博客决策树——从原理到实现,写的很不错。

二、决策树的构造

机器学习实战中有很详细的叙述,伪代码如下:
<span style="font-size:14px;">检测数据集中每个子项是否属于同一分类:
if so return 类标签;
else
寻找划分数据集的最好特征
划分数据集
创建分支节点
for 每个划分的子集
调用函数createBranch并增加返回结果到分支节点中
return 分支节点</span>


每一次分支都要找出划分数据集最好的特征,ID3中选取最好的特征是根据信息增益来选取的。

对于信息增益,先要明白信息熵的概念,首先熵是由热力学引述来的,在热力学中,熵表示能量分布的均匀程度,能量越混乱,熵越小,而能量总是由无序状态向有序状态转变,这就是熵增。无序状态的能量是能够做功的有效能量,熵增就意味着能量转化为不能做功的无效能量。(扯多了)
在信息论中,信息熵用来度量信息量,信息越有序,熵越小。计算公式如下



通过比较信息增益大小,找出信息增益最大的特征,即按照该特征划分的数据集的信息熵和原数据集的信息熵差值最大。
接下来就可以递归构造决策树了,结束条件:1、程序遍历完所有特征属性。2、每个分支下的所有实例都具有相同分类。
ID3每次划分消耗一个特征,这和C4.5、CART,是不一样的。若分支结束,叶子节点仍有分类不同的,以投票方式选择类别,即选取数目最多的那一类。

三、python实现

<span style="font-size:14px;">from math import log
import operator
#计算香农熵
def calcShannonEnt(dataSet):
numEntries=len(dataSet)
labelCounts={}
for featVec in dataSet:#为所有分类创建字典
currentLabel=featVec[-1]#the last
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 surfacin','flippers']
return dataSet,labels
#划分数据集
def splitDataSet(dataSet,axis,value):
retDataSet=[]
for featVec in dataSet:
if featVec[axis]==value:
reducedFeatVec=featVec[:axis]#0~axis
reducedFeatVec.extend(featVec[axis+1:])#注意两个函数区别
retDataSet.append(reducedFeatVec)
return retDataSet
#选择最好的特征
def chooseBestFeatureToSplit(dataSet):
numFeatures=len(dataSet[0])-1#不包括类标签
baseEntropy=calcShannonEnt(dataSet)
bestInfoGain=0.0;bestFeature=-1
for i in range(numFeatures):
featList=[example[i] for example in dataSet]
uniqueVals=set(featList)
newEntropy=0.0
for value in uniqueVals:#计算信息熵
subDataSet = splitDataSet(dataSet,i,value)
prob = len(subDataSet)/float(len(dataSet))
newEntropy += prob*calcShannonEnt(subDataSet)
infoGain=baseEntropy-newEntropy
if (infoGain>bestInfoGain):#找到最好的信息增益
bestInfoGain = infoGain
bestFeature = i
return bestFeature
#分支结束若叶子节点分类不唯一,采取投票方式
def majorityCht(classList):
classCount={}
for vote in classList:
if vote not in classCount.key():
classCount[vote]=0
classCount[vote]+=1
sortedClassCount=sorted(classCount.iteritems(),
key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
#构造树
def createTree(dataSet,labels):
classList = [example[-1] for example in dataSet]
if classList.count(classList[0])==len(classList):
return classList[0]
if len(dataSet[0])==1:# no more features
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet)#bestFeat is the index of best feature
bestFeatLabel = labels[bestFeat]
myTree = {bestFeatLabel:{}}
del (labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]
uniqueFeatVals = set(featValues)
for value in uniqueFeatVals:
subLabels=labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet\
(dataSet,bestFeat,value),subLabels)
return myTree</span>


参考文献
[1]. 机器学习实战
[2]. 决策树之ID3算法

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: