机器学习实战之决策树

决策树是一种基于树形结构来进行决策的算法,它可以被用来解决分类和回归问题。决策树通过一系列的判断来对于输入的数据进行分类或者预测。

它的构建过程通常会基于数据集中的各种属性和属性值来设置各种不同的分支和叶子节点。通过比对输入数据集和决策树的各种分支和叶子节点之间的差异性,决策树能够得出最终的分类或预测结果。

决策树算法相对来说比较容易理解和实现,非常适合处理一些较小的数据集。但如果数据集过于庞大,建模过程就会变得非常耗时和昂贵。但决策树也比较容易出现过拟合的问题。

海洋动物分类

不浮出水面是否可以生存(no surfacing)是否有脚蹼(flippers)属于鱼类
1
2
3
4
5

学习如何计算信息增益来划分数据集,集合信息的度量方式称为香农熵或简称为熵(Entropy)。

如果待分类的事务可能划分在多个分类之中,则熵的计算公式为

 H(X)表示随机变量X的熵,pi​表示X取第i个取值的概率,n表示X可能取值的总数。

具体代码复现

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

该函数用于计算熵,是上诉公式的代码实现

def creatDataset():
    dataset = [[1,1,'yes'],
              [1,1,'yes'],
              [1,0,'no'],
              [0,1,'no'],
              [0,1,'no']]
    labels = ['no surfacing','flippers']
    return dataset,labels

创建数据集

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)
    return retDataSet

数据划分

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

通过计算信息增益来选择最好的数据集划分方式,本次使用的数据集有两个特征值,通过与原始数据集的熵做差来进行对比。

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[:]
        myTree[bestFeatLabel][value]= createTree(splitDataset(dataset,bestFeat,value),subLabels)
    return myTree

以上是树的递归创建过程,当所有类的标签完全相同时,则直接返回该类标签;或是使用完所有特征仍然不能将数据集划分成仅包含唯一类别的分组。

def classify(inputTree,featLabels,testVec):
    firstStr = list(inputTree.keys())[0]
    secondDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr)
    for key in secondDict.keys():
        if testVec[featIndex] == key:
            if type(secondDict[key]).__name__=='dict':
                classLabel = classify(secondDict[key],featLabels,testVec)
            else: classLabel = secondDict[key]
    return classLabel

最后使用决策树的分类函数,分类结果如下

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值