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 相关文章推荐
Tornado Web服务器多进程启动的2个方法
Aug 04 Python
跟老齐学Python之坑爹的字符编码
Sep 28 Python
python使用arcpy.mapping模块批量出图
Mar 06 Python
Python之多线程爬虫抓取网页图片的示例代码
Jan 10 Python
python实现微信远程控制电脑
Feb 22 Python
Python OpenCV处理图像之滤镜和图像运算
Jul 10 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
Feb 27 Python
Mac PyCharm中的.gitignore 安装设置教程
Apr 16 Python
python如何使用腾讯云发送短信
Sep 17 Python
10个python爬虫入门基础代码实例 + 1个简单的python爬虫完整实例
Dec 16 Python
用python发送微信消息
Dec 21 Python
Python中Selenium对Cookie的操作方法
Jul 09 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中的内存管理问题
2011/08/31 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
php判断文件上传图片格式的实例详解
2017/09/30 PHP
thinkPHP5框架设置404、403等http状态页面的方法
2018/06/05 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
LBS blog sql注射漏洞[All version]-官方已有补丁
2007/08/26 Javascript
动态修改DOM 里面的 id 属性的弊端分析
2008/09/03 Javascript
面向对象的Javascript之三(封装和信息隐藏)
2012/01/27 Javascript
jQuery实现设置、移除文本框默认值功能
2015/01/13 Javascript
JS修改iframe页面背景颜色的方法
2015/04/01 Javascript
基于BootStrap Metronic开发框架经验小结【四】Bootstrap图标的提取和利用
2016/05/12 Javascript
jQuery实现删除li节点的方法
2016/12/06 Javascript
Bootstrap3 内联单选和多选框
2016/12/29 Javascript
ECMAScript6变量的解构赋值实例详解
2017/09/19 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
vue ssr服务端渲染(小白解惑)
2019/11/10 Javascript
Vue 使用Props属性实现父子组件的动态传值详解
2019/11/13 Javascript
Node.js中文件系统fs模块的使用及常用接口
2020/03/06 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
[02:43]中国五虎出征TI3视频
2013/08/02 DOTA
[13:38]2015国际邀请赛中国战队出征仪式
2015/05/29 DOTA
python后端接收前端回传的文件方法
2019/01/02 Python
Python提取频域特征知识点浅析
2019/03/04 Python
解决django后台管理界面添加中文内容乱码问题
2019/11/15 Python
Python 从attribute到property详解
2020/03/05 Python
在python中修改.properties文件的操作
2020/04/08 Python
Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)
2020/07/20 Python
button在IE6/7下的黑边去除方案
2012/12/24 HTML / CSS
马来西亚网上购物:Youbeli
2018/03/30 全球购物
ColourPop美国官网:卡拉泡泡,洛杉矶彩妆品牌
2019/04/28 全球购物
介绍一下Linux内核的排队自旋锁
2014/08/27 面试题
小区物业门卫岗位职责
2014/04/10 职场文书
党的群众路线对照检查材料
2014/08/27 职场文书
追悼会悼词大全
2015/06/23 职场文书
假如给我三天光明读书笔记
2015/06/26 职场文书
2016年社区“我们的节日·中秋节”活动总结
2016/04/05 职场文书