侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python机器学习之决策树分类详解

Python  /  管理员 发布于 7年前   173

决策树分类与上一篇博客k近邻分类的最大的区别就在于,k近邻是没有训练过程的,而决策树是通过对训练数据进行分析,从而构造决策树,通过决策树来对测试数据进行分类,同样是属于监督学习的范畴。决策树的结果类似如下图:


图中方形方框代表叶节点,带圆边的方框代表决策节点,决策节点与叶节点的不同之处就是决策节点还需要通过判断该节点的状态来进一步分类。

那么如何通过训练数据来得到这样的决策树呢?

这里涉及要信息论中一个很重要的信息度量方式,香农熵。通过香农熵可以计算信息增益。

香农熵的计算公式如下:

p(xi)代表数据被分在i类的概率,可以通过计算数据集中i类的个数与总的数据个数之比得到,计算香农熵的python代码如下:

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 

一般来说,数据集中,不同的类别越多,即信息量越大,那么熵值越大,通过计算熵,就可以知道选择哪一个特征能够最好的分开数据,这个特征就是一个决策节点。

下面就可以根据训练数据开始构造决策树。

首先编写一个根据给定特征划分数据集的函数:

#划分数据集,返回第axis轴为value值的数据集 def splitDataSet(dataset,axis,value):   retDataSet=[]   for featVec in dataset:     if featVec[axis]==value:       reducedFeatVec=featVec[:]       del(reducedFeatVec[axis])       retDataSet.append(reducedFeatVec)   return retDataSet 

下面找出数据集中能够最好划分数据的那个特征,它的原理是计算经过每一个特征轴划分后的数据的信息增益,信息增益越大,代表通过该特征轴划分是最优的。

#选择最好的数据集划分方式,返回最佳的轴 def chooseBestFeatureToSplit(dataset):   numFeatures=len(dataset[0])-1   baseEntrypy=calcShannonEnt(dataset)   bestInfoGain=0.0   bestFeature=-1   for i in range(numFeatures):     featList=[example[i] for example in dataset]     uniqueVals=set(featList)     newEntrypy=0.0     for value in uniqueVals:       subDataSet=splitDataSet(dataset,i,value)       prob=len(subDataSet)/float(len(dataset))       newEntrypy+=prob*calcShannonEnt(subDataSet)     infoGain=baseEntrypy-newEntrypy        #计算信息增益,信息增益最大,就是最好的划分     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)   return sortedClassCount[0][0] 

递归创建决策树:

#根据训练数据创建树 def createTree(dataSet,labels):   myLabels=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=myLabels[bestFeat]   myTree={bestFeatLabel:{}}   del(myLabels[bestFeat])   featValue=[example[bestFeat] for example in dataSet]   uniqueVal=set(featValue)   for value in uniqueVal:     subLabels=myLabels[:]     myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels)   return myTree 

将上述代码保存到tree.py中,在命令窗口输入以下代码:

>>> dataSet=[[1,1,'yes'],        [1,1,'yes'],        [1,0,'no'],        [0,1,'no'],        [0,1,'no']] >>> labels=['no sufacing','flippers'] >>> tree.createTree(dataSet,labels) {'no sufacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}} 

就得到了决策树的结构,可以画出树的结构图

上面数据的实际意义是通过生物特征,来判断是否属于鱼类,第一列数据中1代表在水中可以生存,0代表在水中不可以生存。第二列中1代表有脚蹼,0代表没有脚蹼。yes是鱼类,no不是鱼类。label是训练数据中每一列代表的意义。那么通过训练数据我们就构造出了决策树,由图可知,我们首先可以根据第一列特征,即在水中是否可以生存来进行第一步判断,不可以生存的肯定不是鱼类,可以生存的还要看是否有脚蹼,有脚蹼的才是鱼类。

不难看出,决策树最大的优势就是它的数据形式易于理解,分类方式直观。

训练出决策树之后,我们就可以根据根据决策树来对新的测试数据进行分类。

分类代码如下:

#根据决策树分类 def classify(inputTree,featLabels,testVec):   firstStr=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 

这里有一个通过决策数算法进行分类的一个实例,眼科医生是如何判断患者需要佩戴隐形眼镜的类型的。

判断的结果有三种,硬材料,软材料和不适合佩戴。

训练数据采用隐形眼镜数据集,数据集来自UCI数据库,它包含了很多患者眼部状况的观察条件以及医生推荐的眼镜类型。

数据集如下:


测试代码如下:

def example():   fr=open('lenses.txt')   lenses=[inst.strip().split('\t') for inst in fr.readlines()]   lensesLabels=['age','prescript','astigmatic','tearRate']   lensesTree=createTree(lenses,lensesLabels)   return lensesTree 

结果:

决策树结构如下:

这样,医生便可以一步步的观察来最终得知该患者适合什么材料的隐形眼镜了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    详解Python中 sys.argv[]的用法简明解释
    下一条:
    python机器学习之神经网络(三)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客