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和bash统计CPU利用率的方法
Jul 10 Python
python时间日期函数与利用pandas进行时间序列处理详解
Mar 13 Python
Pytorch入门之mnist分类实例
Apr 14 Python
django manage.py扩展自定义命令方法
May 27 Python
Python使用googletrans报错的解决方法
Sep 25 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
Dec 04 Python
Python 利用切片从列表中取出一部分使用的方法
Feb 01 Python
python绘制评估优化算法性能的测试函数
Jun 25 Python
Python可变参数会自动填充前面的默认同名参数实例
Nov 18 Python
安装多个版本的TensorFlow的方法步骤
Apr 21 Python
python subprocess pipe 实时输出日志的操作
Dec 05 Python
总结几个非常实用的Python库
Jun 26 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
global.php
2006/12/09 PHP
ThinkPHP中的关联模型注意点
2014/06/16 PHP
php获取apk包信息的方法
2014/08/15 PHP
PHP文件缓存类实现代码
2015/10/26 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
ext 代码生成器
2009/08/07 Javascript
ExtJs之带图片的下拉列表框插件
2010/03/04 Javascript
JavaScript 类的定义和引用 JavaScript高级培训 自定义对象
2010/04/27 Javascript
jQuery 选择表格(table)里的行和列及改变简单样式
2012/12/15 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
一个JS函数搞定网页标题(title)闪动效果
2014/05/13 Javascript
Javascript 构造函数详解
2014/10/22 Javascript
js实现用户离开页面前提示是否离开此页面的方法(包括浏览器按钮事件)
2015/07/18 Javascript
使用Promise解决多层异步调用的简单学习心得
2016/05/17 Javascript
在web中js实现类似excel的表格控件
2016/09/01 Javascript
Vue.js自定义指令的用法与实例解析
2017/01/18 Javascript
jQuery的$.extend 浅拷贝与深拷贝
2017/03/08 Javascript
jQuery基于cookie实现换肤功能实例
2017/10/14 jQuery
echarts设置图例颜色和地图底色的方法实例
2018/08/01 Javascript
Vuex的初探与实战小结
2018/11/26 Javascript
ionic使用angularjs表单验证(模板验证)
2018/12/12 Javascript
Angular 2使用路由自定义弹出组件toast操作示例
2019/05/10 Javascript
layer关闭当前窗口页面以及确认取消按钮的方法
2019/09/09 Javascript
python爬虫实战之最简单的网页爬虫教程
2017/08/13 Python
Python实现判断并移除列表指定位置元素的方法
2018/04/13 Python
python用opencv批量截取图像指定区域的方法
2019/01/24 Python
基于keras 模型、结构、权重保存的实现
2020/01/24 Python
CSS3中伪元素::before和::after的用法示例
2017/09/18 HTML / CSS
实习老师个人总结的自我评价
2013/09/28 职场文书
上级检查欢迎词
2014/01/18 职场文书
老公保证书
2015/01/17 职场文书
营销计划书
2015/01/17 职场文书
教师个人成长总结
2015/02/11 职场文书
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
2021/06/03 Python
二维码条形码生成的JavaScript脚本库
2022/07/07 Javascript