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检测网络延迟的代码
May 15 Python
win7+Python3.5下scrapy的安装方法
Jul 31 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
Dec 11 Python
Django文件上传与下载(FileFlid)
Oct 06 Python
python提取xml里面的链接源码详解
Oct 15 Python
Python线程障碍对象Barrier原理详解
Dec 02 Python
TensorFlow MNIST手写数据集的实现方法
Feb 05 Python
python3.8.1+selenium实现登录滑块验证功能
May 22 Python
Python hashlib模块的使用示例
Oct 09 Python
如何在windows下安装配置python工具Ulipad
Oct 27 Python
详解Selenium 元素定位和WebDriver常用方法
Dec 04 Python
Python实现简单的猜单词
Jun 15 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的Yii框架中View视图的使用进阶
2016/03/29 PHP
CI框架整合widget(页面格局)的方法
2016/05/17 PHP
利用php_imagick实现复古效果的方法
2016/10/18 PHP
深入解析PHP底层机制及相关原理
2020/12/11 PHP
在jquery中combobox多选的不兼容问题总结
2013/12/24 Javascript
js图片处理示例代码
2014/05/12 Javascript
innerHTML在IE中报错解决方案
2014/12/15 Javascript
jQuery对象初始化的传参方式
2015/02/26 Javascript
用原生JS对AJAX做简单封装的实例代码
2016/07/13 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
JavaScript动态加载重复绑定问题
2018/04/01 Javascript
详解如何用babel转换es6的class语法
2018/04/03 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
2018/07/19 Javascript
微信小程序实现指定显示行数多余文字去掉用省略号代替
2018/07/25 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
基于axios 解决跨域cookie丢失的问题
2018/09/26 Javascript
详解基于vue-cli3快速发布一个fullpage组件
2019/03/08 Javascript
javascript实现抢购倒计时程序
2019/08/26 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
React中获取数据的3种方法及优缺点
2020/02/18 Javascript
vue 实现把路由单独分离出来
2020/08/13 Javascript
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
Django自定义分页效果
2017/06/27 Python
python 调用c语言函数的方法
2017/09/29 Python
学生信息管理系统python版
2018/10/17 Python
python matplotlib库直方图绘制详解
2019/08/10 Python
用Python生成HTML表格的方法示例
2020/03/06 Python
浅谈python 中的 type(), dtype(), astype()的区别
2020/04/09 Python
python中openpyxl和xlsxwriter对Excel的操作方法
2021/03/01 Python
Sahajan美国:阿育吠陀护肤品牌
2021/01/09 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
优秀大学生事迹材料
2014/12/24 职场文书
教师听课评语大全
2014/12/31 职场文书
乐山大佛导游词
2015/02/02 职场文书
防暑降温通知书
2015/04/27 职场文书
爱护环境建议书
2015/09/14 职场文书