Python构造决策树

在决策树的学习中,总感觉很多东西,就一个公式,但用代码实现其实挺困难的,程序员大概就是能克服这些苦难的人吧!

下述是个人根据《机器学习实战》做的一些笔记。

#coding:utf-8
from math import log
import operator

#1.计算熵
def calcShannonEnt(dataset):
    numEntries=len(dataset)
    labelsCounts={}
    for featVec in dataset:
        currentLabel=featVec[-1]
        if currentLabel not in labelsCounts.keys():
            labelsCounts[currentLabel]=0
        labelsCounts[currentLabel]+=1
    shannonEnt=0.0
    for key in labelsCounts:
        prob=float(labelsCounts[key])/numEntries
        shannonEnt-=prob*log(prob,2)
    return shannonEnt
#2.划分数据集
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)
            #extend和append的区别:extend直接添加分割的个体,append添加一个列表整体
    return retDataSet
#3.选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
    numFeatures=len(dataSet[0])-1
    baseEntroy=calcShannonEnt(dataSet)
    bestInfoGain=0.0;bestFeature=-1
    for i in range(numFeatures):
        #把dataSet数据项的各个项,[[x,..],[x,..]]的i 位置的数据集合
        featList=[example[i] for example in dataSet]
        #第i 项的集合(去重)
        uniqueVals=set(featList)
        newEntropy=0.0
        for value in uniqueVals:
            #把 i 项数据的各种数据的带有value,重新挑选出来,构成subDataSet
            subDataSet=splitDataSet(dataSet,i,value)
            #计算value项出现的次数,即为概率
            prob=len(subDataSet)/float(len((dataSet)))
            #计算各类划分的数据熵,在求和
            newEntropy+=prob*calcShannonEnt(subDataSet)
        #计算数据增益
        infoGain=baseEntroy-newEntropy
        #挑选信息增益最大的并记录位置
        if(infoGain>bestInfoGain):
            bestInfoGain=infoGain
            bestFeature=i
    return bestFeature
#根据字典的存储,找出出现次数最多的分类名称
#实际就是找出出现次数最多的项
def majorityCnt(classList):
    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),reversed=True)
    return sortedclassCount

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

下图是figure的一个图:代码为



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值