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中用pycurl监控http响应时间脚本分享
Feb 02 Python
使用Python中的线程进行网络编程的入门教程
Apr 15 Python
Python实现扫描局域网活动ip(扫描在线电脑)
Apr 28 Python
Python模块搜索概念介绍及模块安装方法介绍
Jun 03 Python
Python获取当前页面内所有链接的四种方法对比分析
Aug 19 Python
Python读csv文件去掉一列后再写入新的文件实例
Dec 28 Python
[原创]Python入门教程2. 字符串基本操作【运算、格式化输出、常用函数】
Oct 29 Python
python实时获取外部程序输出结果的方法
Jan 12 Python
python画双y轴图像的示例代码
Jul 07 Python
python3反转字符串的3种方法(小结)
Nov 07 Python
python将下载到本地m3u8视频合成MP4的代码详解
Nov 24 Python
详解Pycharm第三方库的安装及使用方法
Dec 29 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
《魔兽争霸3:重制版》翻车了?你想要的我们都没有
2019/11/07 魔兽争霸
SONY SRF-22W(33W)的电路分析和维修案例
2021/03/02 无线电
php实现encode64编码类实例
2015/03/24 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
android上传图片到PHP的过程详解
2015/08/03 PHP
jQuery 数据缓存data(name, value)详解及实现
2010/01/04 Javascript
使用js画图之正弦曲线
2015/01/12 Javascript
在JavaScript中正确引用bind方法的应用
2015/05/11 Javascript
JavaScript中的lastIndexOf()方法使用详解
2015/06/06 Javascript
浅析Javascript中bind()方法的使用与实现
2016/04/29 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
javascript 中的事件委托详解
2016/10/25 Javascript
JS鼠标滚动分页效果示例
2017/07/05 Javascript
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
[06:48]DOTA2-DPC中国联赛2月26日Recap集锦
2021/03/11 DOTA
由浅入深讲解python中的yield与generator
2017/04/05 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
2017/11/30 Python
python爬取网页转换为PDF文件
2018/06/07 Python
Python利用itchat库向好友或者公众号发消息的实例
2019/02/21 Python
python实现QQ空间自动点赞功能
2019/04/09 Python
Python中模块(Module)和包(Package)的区别详解
2019/08/07 Python
python 命令行传入参数实现解析
2019/08/30 Python
Tensorflow tf.dynamic_partition矩阵拆分示例(Python3)
2020/02/07 Python
python轮询机制控制led实例
2020/05/03 Python
CSS中几个与换行有关的属性简明总结
2014/04/15 HTML / CSS
日本高岛屋百货购物网站:TAKASHIMAYA
2019/03/24 全球购物
匈牙利超级网上商店和优惠:Alza.hu
2019/12/17 全球购物
教师节商场活动方案
2014/02/13 职场文书
园艺师求职信
2014/03/10 职场文书
大班亲子运动会方案
2014/06/10 职场文书
励志演讲稿500字
2014/08/21 职场文书
殡葬服务心得体会
2014/09/11 职场文书
2014年销售内勤工作总结
2014/12/01 职场文书
浅谈如何提高PHP代码的质量
2021/05/28 PHP
Python中的xlrd模块使用整理
2021/06/15 Python