构造决策树

决策树分类器基础代码

注:先提交代码和各行代码的解释,后续完善。参照机器学习实战教材

from math import log
import operator

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

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) #log base 2    
    return shannonEnt #自定义函数返回信息熵
    
def splitDateSet(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 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: #依次遍历某特征的某个值
            subDateSet=splitDateSet(dataset,i,value)# 对当前特征的每个特征划分一次数据集
            prob=len(subDateSet)/float(len(dataset))# 计算每种划分的信息熵公式
            newEntropy +=prob*calcShannonEnt(subDateSet)# 计算每种划分的信息熵公式

        infoGain=baseEntropy-newEntropy # 计算每种划分方式的信息增益
        if (infoGain>bestInfoGain): #计算最好的信息增益
            bestInfoGain=infoGain
            bestFeature=i
    return bestFeature   #返回最好特征划分的索引值 
#test=chooseBestFeatureToSplit(dataset)#求得数据集最好的特征划分的索引值
def majorityCnt(classList):#该函数使用分类名称的列表,然后创建键值为classList中唯一值的数据字典,
#字典对象存储了classList中每个类表现出现的次数,并利用operator操作键值排序字典,并返回次数最多的分类名称。    
    classCount={}  
    for vote in classList:      
        if vote not in classCount.keys():classCount[vote]=0      
        classCount[vote]+=1         
    sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)   
    return sortedClassCount[0][0]

def creatTree(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:{}}#得到的返回值插入到字典变量myTree中
    del(labels[bestFeat])#对属性标签依次删除已经插入到字典的特征
    featValues=[example[bestFeat] for example in dataset]#得到当前用来划分的特征的所有属性值
    uniqueVals=set(featValues)#对当前特征的所有属性值去重,得到唯一值
    for value in uniqueVals: #遍历当前特征的所有属性的唯一值
        subLabels=labels[:]#复制了类标签,并将其储存在新列表变量中,确保不修改原始列表内容
        myTree[bestFeatLabel][value]=creatTree(splitDateSet(dataset,bestFeat,value),subLabels)
    return myTree    
dataset, labels=createDataSet() #得到待划分的数据集和特征
test=creatTree(dataset,labels)#完成决策树的嵌套字典
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值