《机器学习实战》之决策树-笔记2

3决策树

3.1信息增益

在划分数据集之前之后信息发生的变化称为信息增益。计算每个特征值划分数据集获得的信息增益,选择信息增益最高的特征作为主要特征。

3.1.1熵

熵定义为信息的期望值

#香农熵计算
from math import log

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 #概率P
        shannonEnt -=prob * log(prob,2)
    return shannonEnt

#示例:简单鱼鉴定数据集    
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
在python命令提示符输入下列命令:
>>>

增加第三个名为maybe的分类,测试熵的变化。可以发现混合的数据越多,熵越大。

3.1.1划分数据集-信息增益

对每个特征划分数据集的结果计算一次信息熵,然后判断按照那个特征划分数据集是最好的划分方式。即选择信息增益最大的特征。
#按照给定特征划分数据集    
def splitDataSet(dataSet, axis, value): #三个参数:待划分的数据集、划分数据集的特征、需要返回的特征的值
    retDataSet = [] #创建新的list对象
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

利用前面简单鱼样本数据myDat测试函数splitDataSet()。

In [36]行意思是:对myDat数据集按第一个特征划分,如果第一个特征等于1,则将数据抽取出来。(myDat,0,1),0表示第一个特征,1表示如果第一个特征的值等于1。

同理,按第一个特征为0划分,结果如下
接下来,我们遍历整个数据集,循环计算香农熵和splitDataSet(),找到最好的特征划分方式。
#计算信息增益,选择最好的特征   
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:
            subDataSet = splitDataSet(dataSet,i,value) #划分数据集
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet) #新熵
        infoGain = baseEntropy - newEntropy
        if(infoGain > bestInfoGain): #选择信息增益最大的
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

函数调用的数据有要求:
1、数据必须是有列表元素组成的列表,且所有列表元素长度相同;
2、数据最后一列或者每个实例的最后一个元素是当前实例的类别标签。可以是数值型或字符型。

测试结果告诉我们,第0个特征是最好的用于划分数据集myDat的特征。即数据集的第一维特征。

上述是决策树的子模块。下面我们将递归构建决策树。
递归结束的条件是:程序遍历完所有划分数据集的属性,或者每个分支下的所有实例都具有相同的分类。

如果数据集已经处理完了所有属性,但是类标签依然不是唯一的,此时,采用多数表决的方法决定叶子节点的分类。定义叶子节点和创建树的函数代码如下:
# 多数表决 决定叶子节点的分类
# 需在treees.py顶部增加一行代码 import operator
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)
    return sortedClassCount[0][0]
    
# 创建树
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)
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}} # 字典变量 存储树的所有信息
    del(labels[bestFeat])
    featValues = [example[bestFeat] for example in dataSet] # 得到列表,包含所有属性值
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLabels = labels[:] # 复制类标签,存储在新列表subLabels中
        myTree[bestFeatLabel][value]=createTree(splitDataSet\
                (dataSet,bestFeat,value),subLabels)
    return myTree

执行代码,输出结果如下:


变量myTree包含了很多代表树结构信息的嵌套字典,从左边开始,第一个关键字no surfacing是第一个划分数据集的特征名称,该关键字也是另一个数据字典。对于其他关键词,其值可能是类标签,也可能是另一个数据字典。如果值是类标签,则该子节点就是叶子节点;如果值是另一个数据字典,则子节点是一个判断节点。

上述讲述了如何构造树,下面将绘制图形,方便描述数据信息的内在含义。

3.2 用Matplotlib注解绘制树形图


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值