Python机器学习之决策树算法


Posted in Python onDecember 22, 2017

一、决策树原理

决策树是用样本的属性作为结点,用属性的取值作为分支的树结构。
决策树的根结点是所有样本中信息量最大的属性。树的中间结点是该结点为根的子树所包含的样本子集中信息量最大的属性。决策树的叶结点是样本的类别值。决策树是一种知识表示形式,它是对所有样本数据的高度概括决策树能准确地识别所有样本的类别,也能有效地识别新样本的类别。 

决策树算法ID3的基本思想:

首先找出最有判别力的属性,把样例分成多个子集,每个子集又选择最有判别力的属性进行划分,一直进行到所有子集仅包含同一类型的数据为止。最后得到一棵决策树。

J.R.Quinlan的工作主要是引进了信息论中的信息增益,他将其称为信息增益(information gain),作为属性判别能力的度量,设计了构造决策树的递归算法。

举例子比较容易理解:

对于气候分类问题,属性为:
天气(A1) 取值为: 晴,多云,雨
气温(A2)  取值为: 冷 ,适中,热
湿度(A3)  取值为: 高 ,正常
风 (A4)  取值为: 有风, 无风

每个样例属于不同的类别,此例仅有两个类别,分别为P,N。P类和N类的样例分别称为正例和反例。将一些已知的正例和反例放在一起便得到训练集。
由ID3算法得出一棵正确分类训练集中每个样例的决策树,见下图。

Python机器学习之决策树算法

决策树叶子为类别名,即P 或者N。其它结点由样例的属性组成,每个属性的不同取值对应一分枝。
若要对一样例分类,从树根开始进行测试,按属性的取值分枝向下进入下层结点,对该结点进行测试,过程一直进行到叶结点,样例被判为属于该叶结点所标记的类别。
现用图来判一个具体例子,
某天早晨气候描述为:
天气:多云
气温:冷
湿度:正常
风: 无风

它属于哪类气候呢?-------------从图中可判别该样例的类别为P类。 

ID3就是要从表的训练集构造图这样的决策树。实际上,能正确分类训练集的决策树不止一棵。Quinlan的ID3算法能得出结点最少的决策树。

ID3算法:

     1. 对当前例子集合,计算各属性的信息增益;
     2. 选择信息增益最大的属性Ak;
     3. 把在Ak处取值相同的例子归于同一子集,Ak取几个值就得几个子集;
     4.对既含正例又含反例的子集,递归调用建树算法;
     5. 若子集仅含正例或反例,对应分枝标上P或N,返回调用处。

一般只要涉及到树的情况,经常会要用到递归。 

对于气候分类问题进行具体计算有:
1、 信息熵的计算: Python机器学习之决策树算法其中S是样例的集合, P(ui)是类别i出现概率:

Python机器学习之决策树算法

|S|表示例子集S的总数,|ui|表示类别ui的例子数。对9个正例和5个反例有:
P(u1)=9/14
P(u2)=5/14
H(S)=(9/14)log(14/9)+(5/14)log(14/5)=0.94bit 

2、信息增益的计算:Python机器学习之决策树算法

其中A是属性,Value(A)是属性A取值的集合,v是A的某一属性值,Sv是S中A的值为v的样例集合,| Sv |为Sv中所含样例数。

以属性A1为例,根据信息增益的计算公式,属性A1的信息增益为

Python机器学习之决策树算法

S=[9+,5-] //原样例集中共有14个样例,9个正例,5个反例
S晴=[2+,3-]//属性A1取值晴的样例共5个,2正,3反
S多云=[4+,0-] //属性A1取值多云的样例共4个,4正,0反
S雨=[3+,2-] //属性A1取值晴的样例共5个,3正,2反
故 

Python机器学习之决策树算法

3、结果为

Python机器学习之决策树算法

属性A1的信息增益最大,所以被选为根结点。

4、建决策树的根和叶子

ID3算法将选择信息增益最大的属性天气作为树根,在14个例子中对天气的3个取值进行分枝,3 个分枝对应3 个子集,分别是:

Python机器学习之决策树算法

其中S2中的例子全属于P类,因此对应分枝标记为P,其余两个子集既含有正例又含有反例,将递归调用建树算法。

5、递归建树

分别对S1和S3子集递归调用ID3算法,在每个子集中对各属性求信息增益.
(1)对S1,湿度属性信息增益最大,以它为该分枝的根结点,再向下分枝。湿度取高的例子全为N类,该分枝标记N。取值正常的例子全为P类,该分枝标记P。
(2)对S3,风属性信息增益最大,则以它为该分枝根结点。再向下分枝,风取有风时全为N类,该分枝标记N。取无风时全为P类,该分枝标记P。

二、PYTHON实现决策树算法分类

本代码为machine learning in action 第三章例子,亲测无误。
 1、计算给定数据shangnon数据的函数:

def calcShannonEnt(dataSet): 
 #calculate the shannon value 
 numEntries = len(dataSet) 
 labelCounts = {} 
 for featVec in dataSet:  #create the dictionary for all of the data 
  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) #get the log value 
 return shannonEnt

 2. 创建数据的函数

def createDataSet(): 
 dataSet = [[1,1,'yes'], 
    [1,1, 'yes'], 
    [1,0,'no'], 
    [0,1,'no'], 
    [0,1,'no']] 
 labels = ['no surfacing','flippers'] 
 return dataSet, labels

3.划分数据集,按照给定的特征划分数据集

def splitDataSet(dataSet, axis, value): 
 retDataSet = [] 
 for featVec in dataSet: 
  if featVec[axis] == value:  #abstract the fature 
   reducedFeatVec = featVec[:axis] 
   reducedFeatVec.extend(featVec[axis+1:]) 
   retDataSet.append(reducedFeatVec) 
 return retDataSet

4.选择最好的数据集划分方式

def chooseBestFeatureToSplit(dataSet): 
 numFeatures = len(dataSet[0])-1 
 baseEntropy = calcShannonEnt(dataSet) 
 bestInfoGain = 0.0; bestFeature = -1 
 for i in range(numFeatures): 
  featList = [example[i] for example in dataSet] 
  uniqueVals = set(featList) 
  newEntropy = 0.0 
  for value in uniqueVals: 
   subDataSet = splitDataSet(dataSet, i , value) 
   prob = len(subDataSet)/float(len(dataSet)) 
   newEntropy +=prob * calcShannonEnt(subDataSet) 
  infoGain = baseEntropy - newEntropy 
  if(infoGain > bestInfoGain): 
   bestInfoGain = infoGain 
   bestFeature = i 
 return bestFeature

5.递归创建树

用于找出出现次数最多的分类名称的函数

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): 
 classList = [example[-1] for example in dataSet] 
 # the type is the same, so stop classify 
 if classList.count(classList[0]) == len(classList): 
  return classList[0] 
 # traversal all the features and choose the most frequent feature 
 if (len(dataSet[0]) == 1): 
  return majorityCnt(classList) 
 bestFeat = chooseBestFeatureToSplit(dataSet) 
 bestFeatLabel = labels[bestFeat] 
 myTree = {bestFeatLabel:{}} 
 del(labels[bestFeat]) 
 #get the list which attain the whole properties 
 featValues = [example[bestFeat] for example in dataSet] 
 uniqueVals = set(featValues) 
 for value in uniqueVals: 
  subLabels = labels[:] 
  myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels) 
 return myTree

然后是在python 名利提示符号输入如下命令:

myDat, labels = trees.createDataSet() 
myTree = trees.createTree(myDat,labels) 
print myTree

结果是:
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

6.实用决策树进行分类的函数

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

在Python命令提示符,输入:
trees.classify(myTree,labels,[1,0]) 

得到结果:
'no'
Congratulation. Oh yeah. You did it.!!!

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

Python 相关文章推荐
python支持断点续传的多线程下载示例
Jan 16 Python
Python中处理unchecked未捕获异常实例
Jan 17 Python
Python打印斐波拉契数列实例
Jul 07 Python
python的变量与赋值详细分析
Nov 08 Python
Python实现SQL注入检测插件实例代码
Feb 02 Python
Python Web框架之Django框架Model基础详解
Aug 16 Python
pytorch多GPU并行运算的实现
Sep 27 Python
Python面向对象原理与基础语法详解
Jan 02 Python
如何在python开发工具PyCharm中搭建QtPy环境(教程详解)
Feb 04 Python
浅谈python中频繁的print到底能浪费多长时间
Feb 21 Python
Python Flask异步发送邮件实现方法解析
Aug 01 Python
Pyinstaller打包Scrapy项目的实现步骤
Sep 22 Python
python+selenium实现登录账户后自动点击的示例
Dec 22 #Python
python实现决策树
Dec 21 #Python
python利用sklearn包编写决策树源代码
Dec 21 #Python
python实现决策树分类算法
Dec 21 #Python
Python语言描述机器学习之Logistic回归算法
Dec 21 #Python
python Crypto模块的安装与使用方法
Dec 21 #Python
python编写Logistic逻辑回归
Dec 30 #Python
You might like
我的论坛源代码(五)
2006/10/09 PHP
PHP扩展CURL的用法详解
2014/06/20 PHP
php简单解析mysqli查询结果的方法(2种方法)
2016/06/29 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
Avengerls vs KG BO3 第二场2.18
2021/03/10 DOTA
如何简单地用YUI做JavaScript动画
2007/03/10 Javascript
CutePsWheel javascript libary 控制输入文本框为可使用滚轮控制的js库
2010/02/07 Javascript
多浏览器兼容性比较好的复制到剪贴板的js代码
2011/10/09 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
javascript函数作用域学习示例(js作用域)
2014/01/13 Javascript
浏览器窗口加载和大小改变事件示例
2014/02/27 Javascript
js倒计时抢购实例
2015/12/20 Javascript
基于socket.io+express实现多房间聊天
2016/03/17 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
2016/10/28 Javascript
React Native AsyncStorage本地存储工具类
2017/10/24 Javascript
浅谈用Webpack路径压缩图片上传尺寸获取的问题
2018/02/22 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
2018/03/28 jQuery
Vue表单绑定的实例代码(单选按钮,选择框(单选时,多选时,用 v-for 渲染的动态选项)
2019/05/13 Javascript
vue的滚动条插件实现代码
2019/09/07 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
pytorch 数据处理:定义自己的数据集合实例
2019/12/31 Python
Python编写单元测试代码实例
2020/09/10 Python
Trench London官方网站:高级风衣和意大利皮夹克
2020/07/11 全球购物
哈萨克斯坦移动和数字技术在线商店:SatelOnline.kz
2020/09/04 全球购物
工程造价专业大学生职业规划范文
2014/03/09 职场文书
弘扬雷锋精神演讲稿
2014/05/10 职场文书
作风建设年活动总结
2014/08/27 职场文书
新婚姻法离婚协议书范文
2014/11/30 职场文书
仓管员岗位职责
2015/02/03 职场文书
员工辞职信范文
2015/03/02 职场文书
国情备忘录观后感
2015/06/04 职场文书
工作一年自我鉴定
2019/06/20 职场文书
Django REST framework 限流功能的使用
2021/06/24 Python