决策树学习笔记

决策树学习笔记

好像是三个星期前看了决策树,当时我是看着书上的代码码的。今天再看的时候,发现已经忘了很多东西了,所以决定写写博客。(第一篇博客)


什么是决策树

首先,什么是决策树?决策树是用来对事物进行分类的,是属于监督型的学习算法。举个例子,要区分一张人民币是真是假,那就要通过人民币的特征去识别。假如识别人民币的特征有:100那仨字有没凹凸质感、有无安全线。要使用决策树去识别真假,首先就要进行特征选择。首选那些对识别人民币真假贡献特别大的特征(比如说90%的100那仨字有凹凸质感的人民币是真币,而70%的有安全线的人民币是真币,那就说明100那仨字有质感这个特征对识别人民币真假贡献最大)。那么如何选择那些对识别人民币真假贡献大的特征呢?就是通过给出的一些数据来计算特征的熵,熵越小的就对识别人民币真假贡献越大。 选择完对识别真假钱贡献最大的特征后,再选择次大的特征。然后根据这些特征的顺序对一张人民币进行真假判定。

熵定义为:信息的期望值。那么信息是什么?信息是这样定义的:如果待分类的事物可能划分在多个分类之中,则待分类的事物 xi 的信息定义为:

l(xi)=log2pi
其中 pi 代表 xi 出现的概率。那么熵的公式就是:

H(X)=i=1npilog2pi
其中n是分类的数目。如果把上面真钱假钱的例子代入,那么 xi 就代表真钱或者假钱的一个分类。 pi 就代表真钱或者假钱在一个数据集中所占的概率。

接下来我们要做的工作就是,划分数据集。根据什么划分数据集呢?就是分别计算按单独某个特征进行分类的时候,所得到的熵的大小进行选择。熵越小的,说明这个特征对于分类贡献最大。就好像按照100那仨字有质感这个特征识别人民币真假的时候,最容易判别人民币的真假,由这个特征计算出来的熵就最小。那我们在决策的时候,就要首先按照这个特征进行判别。
总的来说,决策树就是给定一个数据集,计算各个特征进行分类的时候的熵的大小,构建出一棵决策树,熵越小的特征就越先进行判别。


代码实现

这里用的代码是<<机器学习实战>>那本书上的代码。
创建数据集:

def createDataSet():
dataSet = [[1, 1, 'yes'],
           [1, 1, 'yes'],
           [1, 0, 'no'],
           [0, 1, 'no'],
           [0, 1, 'no']]
labels = ['intaglio','security strip']
return dataSet, labels  

划分数据集:

def splitDataSet(dataSet,axis,value):
retDataSet = []
for featVec in dataSet:
    if featVec[axis] == value:
        reducedFeatVec = featVec[:axis]     
        reducedFeatVec.extend(featVec[axis+1:])
        retDataSet.append(reducedFeatVec)
return retDataSet  

计算香农熵:

def calcShannonEnt(dataSet):
num = len(dataSet)
labelDict={}
for row in dataSet:
    labelDict[row[-1]] = labelDict.get(row[-1],0)+1
shannonEnt=0.0
for key in labelDict:
    prob = float(labelDict[key])/num
    shannonEnt -= prob*log(prob,2)
return shannonEnt

split并循环计算香农熵,选出适宜的特征:

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 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: 
    return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet)
bestFeatLabel = labels[bestFeat]
myTree = {bestFeatLabel:{}}
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]
uniqueVals = set(featValues)
for value in uniqueVals:
    subLabels = labels[:]       
    myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
return myTree

这部分代码有一个majorityCnt的函数,是为了解决用完所有特征,仍不能将某些数据分类的多数表决函数。

def majorityCnt(classList):
classCount={}
for vote in classList:
    if vote not in classCount.keys(): classCount[vote] = 0
    classCount[vote] += 1
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]

第一稿,写的不够详细,以后接着补充。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值