代码笔记--决策树

来源:互联网 发布:朴槿惠 邪教 知乎 编辑:程序博客网 时间:2024/05/18 12:44

1.决策树的构造
首先我们讨论数学上如何使用信息论划分数据集,然后编写代码将理论应用到具体的数据集上,最后编写代码构建决策树。
创建分支的伪代码函数createBranch()如下所示:

检测数据集中的每个子项是否属于同一个分类:    if so return 类标签;    else        寻找划分数据集的最好特征        划分数据集        创建分支节点            for每个划分的子集                调用函数createBranch并增加返回结果到分支节点中        return 分支节点

1.1信息增益
在划分数据集之前之后信息发生的变化成为信息增益,知道如何计算信息增益,我们就可以计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。

信息熵公式

from math import logdef 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)                #以2为底求对数    return shannonEnt

1.2划分数据集

def splitDataSet(dataSet,axis,value):               #按照给定特征划分数据集    retDataSet=[]                                   #创建新的list对象    for featVec in dataSet:        if featVec[axis]==value:            reducedFeatVec=featVec[: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

1.3递归构建决策树

import operatordef 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]
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:        subLables=labels[:]        myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLables)    return myTree
原创粉丝点击