在决策树的学习中,总感觉很多东西,就一个公式,但用代码实现其实挺困难的,程序员大概就是能克服这些苦难的人吧!
下述是个人根据《机器学习实战》做的一些笔记。
#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的一个图:代码为