python实现决策树C4.5算法详解(在ID3基础上改进)


Posted in Python onMay 31, 2017

一、概论

C4.5主要是在ID3的基础上改进,ID3选择(属性)树节点是选择信息增益值最大的属性作为节点。而C4.5引入了新概念“信息增益率”,C4.5是选择信息增益率最大的属性作为树节点。

二、信息增益

python实现决策树C4.5算法详解(在ID3基础上改进)

以上公式是求信息增益率(ID3的知识点)

三、信息增益率

python实现决策树C4.5算法详解(在ID3基础上改进)

信息增益率是在求出信息增益值在除以python实现决策树C4.5算法详解(在ID3基础上改进)

例如下面公式为求属性为“outlook”的python实现决策树C4.5算法详解(在ID3基础上改进)值:

python实现决策树C4.5算法详解(在ID3基础上改进)

四、C4.5的完整代码

from numpy import *
from scipy import *
from math import log
import operator

#计算给定数据的香浓熵:
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; #返回熵

#按照给定的特征划分数据集
def splitDataSet(dataSet, axis, value):
 retDataSet = [] 
 for featVec in dataSet: #按dataSet矩阵中的第axis列的值等于value的分数据集
  if featVec[axis] == value:  #值等于value的,每一行为新的列表(去除第axis个数据)
   reducedFeatVec = featVec[:axis]
   reducedFeatVec.extend(featVec[axis+1:]) 
   retDataSet.append(reducedFeatVec) 
 return retDataSet #返回分类后的新矩阵

#选择最好的数据集划分方式
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) #第i列属性的取值(不同值)数集合
  newEntropy = 0.0 
  splitInfo = 0.0;
  for value in uniqueVals: #求第i列属性每个不同值的熵*他们的概率
   subDataSet = splitDataSet(dataSet, i , value) 
   prob = len(subDataSet)/float(len(dataSet)) #求出该值在i列属性中的概率
   newEntropy += prob * calcShannonEnt(subDataSet) #求i列属性各值对于的熵求和
   splitInfo -= prob * log(prob, 2);
  infoGain = (baseEntropy - newEntropy) / splitInfo; #求出第i列属性的信息增益率
  print infoGain; 
  if(infoGain > bestInfoGain): #保存信息增益率最大的信息增益率值以及所在的下表(列值i)
   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): 
 classList = [example[-1] for example in dataSet]; #创建需要创建树的训练数据的结果列表(例如最外层的列表是[N, N, Y, Y, Y, N, Y])
 if classList.count(classList[0]) == len(classList): #如果所有的训练数据都是属于一个类别,则返回该类别
  return classList[0]; 
 if (len(dataSet[0]) == 1): #训练数据只给出类别数据(没给任何属性值数据),返回出现次数最多的分类名称
  return majorityCnt(classList);

 bestFeat = chooseBestFeatureToSplit(dataSet); #选择信息增益最大的属性进行分(返回值是属性类型列表的下标)
 bestFeatLabel = labels[bestFeat] #根据下表找属性名称当树的根节点
 myTree = {bestFeatLabel:{}} #以bestFeatLabel为根节点建一个空树
 del(labels[bestFeat]) #从属性列表中删掉已经被选出来当根节点的属性
 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 #生成的树

#实用决策树进行分类
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 

#读取数据文档中的训练数据(生成二维列表)
def createTrainData():
 lines_set = open('../data/ID3/Dataset.txt').readlines()
 labelLine = lines_set[2];
 labels = labelLine.strip().split()
 lines_set = lines_set[4:11]
 dataSet = [];
 for line in lines_set:
  data = line.split();
  dataSet.append(data);
 return dataSet, labels


#读取数据文档中的测试数据(生成二维列表)
def createTestData():
 lines_set = open('../data/ID3/Dataset.txt').readlines()
 lines_set = lines_set[15:22]
 dataSet = [];
 for line in lines_set:
  data = line.strip().split();
  dataSet.append(data);
 return dataSet

myDat, labels = createTrainData() 
myTree = createTree(myDat,labels) 
print myTree
bootList = ['outlook','temperature', 'humidity', 'windy'];
testList = createTestData();
for testData in testList:
 dic = classify(myTree, bootList, testData)
 print dic

五、C4.5与ID3的代码区别

python实现决策树C4.5算法详解(在ID3基础上改进)

如上图,C4.5主要在第52、53行代码与ID3不同(ID3求的是信息增益,C4.5求的是信息增益率)。

六、训练、测试数据集样例

训练集:

 outlook temperature humidity windy 
 ---------------------------------------------------------
 sunny  hot    high   false   N
 sunny  hot    high   true   N
 overcast hot    high   false   Y
 rain  mild   high   false   Y
 rain  cool   normal  false   Y
 rain  cool   normal  true   N
 overcast cool   normal  true   Y

测试集
 outlook temperature humidity windy 
 -----------------------------------------------  
 sunny  mild   high   false   
 sunny  cool   normal  false   
 rain   mild   normal  false  
 sunny  mild   normal  true   
 overcast mild   high   true   
 overcast hot    normal  false   
 rain   mild   high   true

以上这篇python实现决策树C4.5算法详解(在ID3基础上改进)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现XML文件解析的示例代码
Feb 05 Python
对Python中创建进程的两种方式以及进程池详解
Jan 14 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
May 13 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
Jun 25 Python
python读取并写入mat文件的方法
Jul 12 Python
使用python模拟命令行终端的示例
Aug 13 Python
CentOS7下安装python3.6.8的教程详解
Jan 03 Python
Python函数参数分类原理详解
May 28 Python
通俗讲解python 装饰器
Sep 07 Python
python爬虫爬取图片的简单代码
Jan 18 Python
python爬虫如何解决图片验证码
Feb 14 Python
利用Python网络爬虫爬取各大音乐评论的代码
Apr 13 Python
基于ID3决策树算法的实现(Python版)
May 31 #Python
Python基础知识_浅谈用户交互
May 31 #Python
python数据类型_字符串常用操作(详解)
May 30 #Python
python数据类型_元组、字典常用操作方法(介绍)
May 30 #Python
node.js获取参数的常用方法(总结)
May 29 #Python
老生常谈python函数参数的区别(必看篇)
May 29 #Python
Python进阶_关于命名空间与作用域(详解)
May 29 #Python
You might like
php获取目录下所有文件及目录(多种方法)(推荐)
2019/05/14 PHP
yii2.0框架场景的简单使用示例
2020/01/25 PHP
php 中的信号处理操作实例详解
2020/03/04 PHP
用js实现的模拟jquery的animate自定义动画(2.5K)
2010/07/20 Javascript
基于Jquery的将DropDownlist的选中值赋给label的实现代码
2011/05/06 Javascript
javascript 图片裁剪技巧解读
2012/11/15 Javascript
jquery ajax应用中iframe自适应高度问题解决方法
2014/04/12 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
2015/10/10 Javascript
jQuery EasyUI 菜单与按钮之创建简单的菜单和链接按钮
2015/11/18 Javascript
JS实现CheckBox复选框全选、不选或全不选功能
2020/07/28 Javascript
JavaScript实现身份证验证代码
2016/02/17 Javascript
快速掌握Node.js事件驱动模型
2016/03/21 Javascript
如何学JavaScript?前辈的经验之谈
2016/12/28 Javascript
详解vscode中vue代码颜色插件
2018/10/11 Javascript
玩转Koa之koa-router原理解析
2018/12/29 Javascript
使用jQuery如何写一个含验证码的登录界面
2019/05/13 jQuery
layui固定下拉框的显示条数(有滚动条)的方法
2019/09/10 Javascript
JS如何寻找数组中心索引过程解析
2020/06/01 Javascript
用Python计算三角函数之acos()方法的使用
2015/05/15 Python
Django 连接sql server数据库的方法
2018/06/30 Python
Python配置虚拟环境图文步骤
2019/05/20 Python
python 利用turtle模块画出没有角的方格
2019/11/23 Python
使用OpenCV实现道路车辆计数的使用方法
2020/07/15 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
Python读取图像并显示灰度图的实现
2020/12/01 Python
css3实现波纹特效、H5实现动态波浪效果
2018/01/31 HTML / CSS
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
如何用JQuery进行表单验证
2013/05/29 面试题
城市轨道专业个人求职信范文
2013/09/23 职场文书
怎样拟定创业计划书
2014/05/01 职场文书
学校党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
2014年新农村建设工作总结
2014/12/01 职场文书
2015会计试用期工作总结
2014/12/12 职场文书
党员转正介绍人意见
2015/06/03 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书