您的位置:首页 > 编程语言 > Python开发

信息增益以及决策树算法-机器学习实战(python)

2017-05-09 21:01 976 查看

信息增益:信息熵和条件熵的差值就是信息增益,主要含义是指期望信息或者信息上的有效减少量,根据他来 确定在什么样的层次上选择什么样的变量来分类。

计算过程我通过一个例子来展现出来



现在 还没有划分数据集,计算信息熵按照公式为
Entropy(S)=-9/14*log2(9\14)-9/14*log2(9\14)

当Wind固定为Weak时:记录有8条,其中yes为6个,NO为2个;

同样,取值为Strong的记录6个,正例负例个3个。我们可以计算相应的熵为:

Entropy(Weak)=-(6/8)*log(6/8)-(2/8)*log(2/8)=0.811

Entropy(Strong)=-(3/6)*log(3/6)-(3/6)*log(3/6)=1.0

现在就可以计算出相应的信息增益了:

所以,对于一个Wind属性固定的分类系统的信息量为 (8/14)*Entropy(Weak)+(6/14)*Entropy(Strong)

然后信息增益为Gain(Wind)=Entropy(S)-(8/14)*Entropy(Weak)-(6/14)*Entropy(Strong)=0.940-(8/14)*0.811-(6/14)*1.0=0.048

其他特征也是这样计算

决策树代码详解

#coding:utf-8
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#没有的话创建新的标签为0
labelCounts[currentLabel] += 1#计算标签数量
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key]) / numEntries#每个标签所占概率
shannonEnt -= prob * log(prob, 2) # 计算乘积
return shannonEnt
def splitDataSet(dataSet, axis, value):#划分数据集
retDataSet = []
for featVec in dataSet:#逐行读取
if featVec[axis] == value:# axis为列数
reducedFeatVec = featVec[:axis] #因为列表语法,所以实际上是去除第axis列的内容
reducedFeatVec.extend(featVec[axis + 1:])#扩展列表
retDataSet.append(reducedFeatVec)#添加列表
return retDataSet
def chooseBestFeatureToSplit(dataSet): #选择最好的数据集划分方式
numFeature = len(dataSet[0])-1
baseEntropy = calcShannonEnt(dataSet)
bestInfoGain = 0.0
beatFeature = -1
for i in range(numFeature):
featureList = [example[i] for example in dataSet] #获取第i个特征所有的可能取值
# example[0]=[1,1,1,0,0],example[1]=[1,1,0,1,1]
uniqueVals = set(featureList) #set函数去重
newEntropy = 0.0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet,i,value) #以i为数据集特征,value为值,划分数据集
prob = len(subDataSet)/float(len(dataSet)) #数据集特征为i的所占的比例
newEntropy +=prob * calcShannonEnt(subDataSet) #计算每种数据集的信息熵
infoGain = baseEntropy- 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.iteritems(),key =operator.itemgetter(1),reverse=True)#排序,True升序
return sortedClassCount[0][0] #返回出现次数最多的
def createTree(dataSet,labels): #创建树的函数代码
classList = [example[-1] for example in dataSet]#最后一行的标签
if classList.count(classList[0])==len(classList): #所有的类标签完全相同,count函数返回元素出现的次数
return classList[0]
if len(dataSet[0]) ==1: #遍历完所有特征值时返回出现次数最多的,只有标签的时候
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet) #选择最好的数据集划分方式,重新划分key
bestFeatLabel = labels[bestFeat] #对应的特征名称
myTree = {bestFeatLabel:{}}#字典传入
del(labels[bestFeat]) #删除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#循环使用



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息