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

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

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

信息增益以及决策树算法-机器学习实战(python)_第1张图片

现在 还没有划分数据集,计算信息熵按照公式为

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#循环使用



你可能感兴趣的:(数据分析)