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


Posted in Python onDecember 20, 2017

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

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

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

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

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

香农熵的计算公式如下:

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

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'}}}}

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

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

上面数据的实际意义是通过生物特征,来判断是否属于鱼类,第一列数据中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数据库,它包含了很多患者眼部状况的观察条件以及医生推荐的眼镜类型。

数据集如下:

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

测试代码如下:

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机器学习之决策树分类详解

决策树结构如下:

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

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

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

Python 相关文章推荐
Python 用户登录验证的小例子
Mar 06 Python
人机交互程序 python实现人机对话
Nov 14 Python
用matplotlib画等高线图详解
Dec 14 Python
PyCharm+PySpark远程调试的环境配置的方法
Nov 29 Python
python pexpect ssh 远程登录服务器的方法
Feb 14 Python
python 绘制拟合曲线并加指定点标识的实现
Jul 10 Python
Python创建一个元素都为0的列表实例
Nov 28 Python
Python列表解析操作实例总结
Feb 26 Python
Python count函数使用方法实例解析
Mar 23 Python
在python中实现求输出1-3+5-7+9-......101的和
Apr 02 Python
Python爬虫过程解析之多线程获取小米应用商店数据
Nov 14 Python
Python爬虫入门教程01之爬取豆瓣Top电影
Jan 24 Python
python机器学习之神经网络(三)
Dec 20 #Python
python机器学习之神经网络(二)
Dec 20 #Python
PyCharm 常用快捷键和设置方法
Dec 20 #Python
python机器学习之神经网络(一)
Dec 20 #Python
使用python实现ANN
Dec 20 #Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
Dec 19 #Python
浅谈Python实现贪心算法与活动安排问题
Dec 19 #Python
You might like
用php将任何格式视频转为flv的代码
2009/09/03 PHP
浅析PHP绘图技术
2013/07/03 PHP
调整PHP的性能
2013/10/30 PHP
php 判断IP为有效IP地址的方法
2018/01/28 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
Mootools 1.2教程 类(一)
2009/09/15 Javascript
js表格分页实现代码
2009/09/18 Javascript
javascript的数组和常用函数详解
2014/05/09 Javascript
JavaScript动态创建link标签到head里的方法
2014/12/22 Javascript
Jquery 实现图片轮换
2015/01/28 Javascript
BootStrap实现树形目录组件代码详解
2016/06/21 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
jQuery中 $ 符号的冲突问题及解决方案
2016/11/04 Javascript
Bootstrap里的文件分别代表什么意思及其引用方法
2017/05/01 Javascript
Node.js中使用mongoose操作mongodb数据库的方法
2017/09/12 Javascript
webpack公共组件引用路径简化小技巧
2018/06/15 Javascript
2种在vue项目中使用百度地图的简单方法
2018/09/28 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
2019/02/21 Javascript
layUI实现列表查询功能
2019/07/27 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
如何在vue-cli中使用css-loader实现css module
2021/01/07 Vue.js
Node快速切换版本、版本回退(降级)、版本更新(升级)
2021/01/07 Javascript
基于python编写的微博应用
2014/10/17 Python
PYTHON压平嵌套列表的简单实现
2016/06/08 Python
Python3调用微信企业号API发送文本消息代码示例
2017/11/10 Python
python如何生成网页验证码
2018/07/28 Python
加拿大时尚床上用品零售商:QE Home | Quilts Etc
2018/01/22 全球购物
汽车运用工程专业毕业生推荐信
2013/12/25 职场文书
应届毕业生如何写求职信
2014/02/16 职场文书
项目投资意向书
2014/04/01 职场文书
银行委托书范本
2014/04/04 职场文书
完整版商业计划书
2014/09/15 职场文书
社区国庆节活动总结
2015/03/23 职场文书
入党介绍人意见范文
2015/06/01 职场文书
导游词之新疆-喀纳斯
2019/10/10 职场文书
Apache自带的ab压力测试工具的实现
2022/07/23 Servers