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 相关文章推荐
一则python3的简单爬虫代码
May 26 Python
Python实现遍历windows所有窗口并输出窗口标题的方法
Mar 13 Python
Python找出list中最常出现元素的方法
Jun 14 Python
python使用Tkinter实现在线音乐播放器
Jan 30 Python
python实现音乐下载的统计
Jun 20 Python
django DRF图片路径问题的解决方法
Sep 10 Python
Python中psutil的介绍与用法
May 02 Python
浅析matlab中imadjust函数
Feb 27 Python
pyqt5 QlistView列表显示的实现示例
Mar 24 Python
如何理解Python中的变量
Jun 01 Python
matlab、python中矩阵的互相导入导出方式
Jun 01 Python
忆童年!用Python实现愤怒的小鸟游戏
Jun 07 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 stream_context_create()作用和用法分析
2011/03/29 PHP
示例详解Laravel重置密码代码重构
2016/08/10 PHP
Thinkphp 5.0实现微信企业付款到零钱
2018/09/30 PHP
javascript appendChild,innerHTML,join性能比较代码
2009/08/29 Javascript
基于JQuery实现异步刷新的代码(转载)
2011/03/29 Javascript
jquery分页对象使用示例
2014/04/01 Javascript
javascript面向对象特性代码实例
2014/06/12 Javascript
javascript在IE下trim函数无法使用的解决方法
2014/09/12 Javascript
最流行的Node.js精简型和全栈型开发框架介绍
2015/02/26 Javascript
jQuery增加与删除table列的方法
2016/03/01 Javascript
jquery使用Cookie和JSON记录用户最近浏览历史
2016/04/19 Javascript
如何获取元素的最终background-color
2017/02/06 Javascript
原生javascript移动端滑动banner效果
2017/03/10 Javascript
Javascript之图片的延迟加载的实例详解
2017/07/24 Javascript
微信小程序自定义键盘 内部虚拟支付
2018/12/20 Javascript
如何使用CSS3和JQuery easing 插件制作绚丽菜单
2019/06/18 jQuery
vue使用swiper.js重叠轮播组建样式
2019/11/14 Javascript
H5+css3+js搭建带验证码的登录页面
2020/10/11 Javascript
python读取浮点数和读取文本文件示例
2014/05/06 Python
用Python编写一个简单的Lisp解释器的教程
2015/04/03 Python
Python的Twisted框架上手前所必须了解的异步编程思想
2016/05/25 Python
Python编程pygal绘图实例之XY线
2017/12/09 Python
python与sqlite3实现解密chrome cookie实例代码
2018/01/20 Python
在NumPy中创建空数组/矩阵的方法
2018/06/15 Python
python3实现网页版raspberry pi(树莓派)小车控制
2020/02/12 Python
Python模拟伯努利试验和二项分布代码实例
2020/05/27 Python
详解Python IO口多路复用
2020/06/17 Python
python 基于卡方值分箱算法的实现示例
2020/07/17 Python
美国特价机票专家:Airfarewatchdog
2018/01/24 全球购物
北体毕业生求职信
2014/02/28 职场文书
青年文明号服务承诺
2014/03/31 职场文书
软件项目开发计划书
2014/05/01 职场文书
大学生实习证明范本
2014/09/19 职场文书
实习生辞职信范文
2015/03/02 职场文书
《画家和牧童》教学反思
2016/02/17 职场文书
Java循环队列与非循环队列的区别总结
2021/06/22 Java/Android