机器学习笔记之决策树ID3

机器学习笔记之决策树

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特
征数据。
缺点:可能会产生过度匹配问题。
适用数据类型:数值型和标称型。

信息增益

划分数据集最大的原则是:将无序的数据变得更加有序。我们可以使用多种方法划分数据集,但是每种方法都有各自的优缺点。我们可以在划分数据之前使用信息论量化度量信息的内容。
在划分数据集之前之后信息发生的变化称为信息增益,知道如何计算信息增益,我们就可以计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。

计算信息增益

集合信息的度量方式称为香农熵

#计算给定数据集的香农熵
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
        shannonEnt -= prob * log(prob, 2)
    return shannonEnt

dataSet = [[1, 1, 'yes'], 
          [1, 1, 'yes'],
          [1, 0, 'no'],
          [0, 1, 'no'],
          [0, 1, 'no']]
labelss = ['no surfacing', 'flippers']

calcShannonEnt(dataSet)
0.9287712379549449
##划分数据集
#三个输入参数:待划分的数据集、划分数据集的特征、特征的返回值
def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
        reducedFeatVec = featVec[:axis]
        reducedFeatVec.extend(featVec[axis+1:])
        retDataSet.append(reducedFeatVec)
    return retDataSet

splitDataSet(dataSet, 0, 1)
[[1, 'yes'], [1, 'yes'], [0, 'no'], [1, 'no'], [1, 'no']]
splitDataSet(dataSet, 0, 0)
[[1, 'yes'], [1, 'yes'], [0, 'no'], [1, 'no'], [1, 'no']]
## 选择最好的数据集划分方式
#在函数中调用的数据需要满足一定的要求:第一个要
#求是,数据必须是一种由列表元素组成的列表,而且所有的列表元素都要具有相同的数据长度;
#第二个要求是,数据的最后一列或者每个实例的最后一个元素是当前实例的类别标签。
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))
        infoGain = baseEntropy - newEntropy
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature


chooseBestFeatureToSplit(dataSet)
0
## 递归构建决策树
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.items(), 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[:]
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)
    
    return myTree

createTree(dataSet, labelss)
{'no surfacing': {0: {'flippers': {0: 'yes', 1: 'yes'}},
  1: {'flippers': {0: 'yes', 1: 'yes'}}}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值