python实现C4.5决策树算法


Posted in Python onAugust 29, 2018

C4.5算法使用信息增益率来代替ID3的信息增益进行特征的选择,克服了信息增益选择特征时偏向于特征值个数较多的不足。信息增益率的定义如下:

python实现C4.5决策树算法

# -*- coding: utf-8 -*-


from numpy import *
import math
import copy
import cPickle as pickle


class C45DTree(object):
 def __init__(self): # 构造方法
  self.tree = {} # 生成树
  self.dataSet = [] # 数据集
  self.labels = [] # 标签集


 # 数据导入函数
 def loadDataSet(self, path, labels):
  recordList = []
  fp = open(path, "rb") # 读取文件内容
  content = fp.read()
  fp.close()
  rowList = content.splitlines() # 按行转换为一维表
  recordList = [row.split("\t") for row in rowList if row.strip()] # strip()函数删除空格、Tab等
  self.dataSet = recordList
  self.labels = labels


 # 执行决策树函数
 def train(self):
  labels = copy.deepcopy(self.labels)
  self.tree = self.buildTree(self.dataSet, labels)


 # 构件决策树:穿件决策树主程序
 def buildTree(self, dataSet, lables):
  cateList = [data[-1] for data in dataSet] # 抽取源数据集中的决策标签列
  # 程序终止条件1:如果classList只有一种决策标签,停止划分,返回这个决策标签
  if cateList.count(cateList[0]) == len(cateList):
   return cateList[0]
  # 程序终止条件2:如果数据集的第一个决策标签只有一个,返回这个标签
  if len(dataSet[0]) == 1:
   return self.maxCate(cateList)
  # 核心部分
  bestFeat, featValueList= self.getBestFeat(dataSet) # 返回数据集的最优特征轴
  bestFeatLabel = lables[bestFeat]
  tree = {bestFeatLabel: {}}
  del (lables[bestFeat])
  for value in featValueList: # 决策树递归生长
   subLables = lables[:] # 将删除后的特征类别集建立子类别集
   # 按最优特征列和值分隔数据集
   splitDataset = self.splitDataSet(dataSet, bestFeat, value)
   subTree = self.buildTree(splitDataset, subLables) # 构建子树
   tree[bestFeatLabel][value] = subTree
  return tree


 # 计算出现次数最多的类别标签
 def maxCate(self, cateList):
  items = dict([(cateList.count(i), i) for i in cateList])
  return items[max(items.keys())]


 # 计算最优特征
 def getBestFeat(self, dataSet):
  Num_Feats = len(dataSet[0][:-1])
  totality = len(dataSet)
  BaseEntropy = self.computeEntropy(dataSet)
  ConditionEntropy = []  # 初始化条件熵
  slpitInfo = [] # for C4.5,caculate gain ratio
  allFeatVList = []
  for f in xrange(Num_Feats):
   featList = [example[f] for example in dataSet]
   [splitI, featureValueList] = self.computeSplitInfo(featList)
   allFeatVList.append(featureValueList)
   slpitInfo.append(splitI)
   resultGain = 0.0
   for value in featureValueList:
    subSet = self.splitDataSet(dataSet, f, value)
    appearNum = float(len(subSet))
    subEntropy = self.computeEntropy(subSet)
    resultGain += (appearNum/totality)*subEntropy
   ConditionEntropy.append(resultGain) # 总条件熵
  infoGainArray = BaseEntropy*ones(Num_Feats)-array(ConditionEntropy)
  infoGainRatio = infoGainArray/array(slpitInfo) # C4.5信息增益的计算
  bestFeatureIndex = argsort(-infoGainRatio)[0]
  return bestFeatureIndex, allFeatVList[bestFeatureIndex]

 # 计算划分信息
 def computeSplitInfo(self, featureVList):
  numEntries = len(featureVList)
  featureVauleSetList = list(set(featureVList))
  valueCounts = [featureVList.count(featVec) for featVec in featureVauleSetList]
  pList = [float(item)/numEntries for item in valueCounts]
  lList = [item*math.log(item, 2) for item in pList]
  splitInfo = -sum(lList)
  return splitInfo, featureVauleSetList


 # 计算信息熵
 # @staticmethod
 def computeEntropy(self, dataSet):
  dataLen = float(len(dataSet))
  cateList = [data[-1] for data in dataSet] # 从数据集中得到类别标签
  # 得到类别为key、 出现次数value的字典
  items = dict([(i, cateList.count(i)) for i in cateList])
  infoEntropy = 0.0
  for key in items: # 香农熵: = -p*log2(p) --infoEntropy = -prob * log(prob, 2)
   prob = float(items[key]) / dataLen
   infoEntropy -= prob * math.log(prob, 2)
  return infoEntropy


 # 划分数据集: 分割数据集; 删除特征轴所在的数据列,返回剩余的数据集
 # dataSet : 数据集; axis: 特征轴; value: 特征轴的取值
 def splitDataSet(self, dataSet, axis, value):
  rtnList = []
  for featVec in dataSet:
   if featVec[axis] == value:
    rFeatVec = featVec[:axis] # list操作:提取0~(axis-1)的元素
    rFeatVec.extend(featVec[axis + 1:]) # 将特征轴之后的元素加回
    rtnList.append(rFeatVec)
  return rtnList

 # 存取树到文件
 def storetree(self, inputTree, filename):
  fw = open(filename,'w')
  pickle.dump(inputTree, fw)
  fw.close()

 # 从文件抓取树
 def grabTree(self, filename):
  fr = open(filename)
  return pickle.load(fr)

调用代码

# -*- coding: utf-8 -*-

from numpy import *
from C45DTree import *

dtree = C45DTree()
dtree.loadDataSet("dataset.dat",["age", "revenue", "student", "credit"])
dtree.train()

dtree.storetree(dtree.tree, "data.tree")
mytree = dtree.grabTree("data.tree")
print mytree

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

Python 相关文章推荐
Python中itertools模块用法详解
Sep 25 Python
python使用json序列化datetime类型实例解析
Feb 11 Python
运行django项目指定IP和端口的方法
May 14 Python
python3使用SMTP发送简单文本邮件
Jun 19 Python
让你Python到很爽的加速递归函数的装饰器
May 26 Python
python多线程案例之多任务copy文件完整实例
Oct 29 Python
wxpython绘制音频效果
Nov 18 Python
python 实现从高分辨图像上抠取图像块
Jan 02 Python
Python编程快速上手——PDF文件操作案例分析
Feb 28 Python
django处理select下拉表单实例(从model到前端到post到form)
Mar 13 Python
Python中zip函数如何使用
Jun 04 Python
python中判断文件结束符的具体方法
Aug 04 Python
python机器学习之KNN分类算法
Aug 29 #Python
深入理解python中sort()与sorted()的区别
Aug 29 #Python
Python实现拷贝/删除文件夹的方法详解
Aug 29 #Python
Python读写zip压缩文件的方法
Aug 29 #Python
使用python生成杨辉三角形的示例代码
Aug 29 #Python
Python实现查询某个目录下修改时间最新的文件示例
Aug 29 #Python
有关Python的22个编程技巧
Aug 29 #Python
You might like
一个PHP的String类代码
2010/04/20 PHP
PHP生成唯一订单号的方法汇总
2015/04/16 PHP
PHP Opcache安装和配置方法介绍
2015/05/28 PHP
PHP数组与对象之间使用递归实现转换的方法
2015/06/24 PHP
PHP中session跨子域的三种实现方法
2016/07/25 PHP
javascript中的float运算精度实例分析
2010/08/21 Javascript
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
2012/04/12 Javascript
使用node.js 获取客户端信息代码分享
2014/11/26 Javascript
JS冒泡事件与事件捕获实例详解
2016/11/25 Javascript
Node.js用readline模块实现输入输出
2016/12/16 Javascript
图片上传之FileAPI与NodeJs
2017/01/24 NodeJs
javascript 中null和undefined区分和比较
2017/04/19 Javascript
node实现定时发送邮件的示例代码
2017/08/26 Javascript
Vue-cli-webpack搭建斗鱼直播步骤详解
2017/11/17 Javascript
vue 组件开发原理与实现方法详解
2019/11/29 Javascript
解决Angularjs异步操作后台请求用$q.all排列先后顺序问题
2019/11/29 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
2020/08/28 Javascript
vue项目中微信登录的实现操作
2020/09/08 Javascript
[00:58]他们到底在电话里听到了什么?
2017/11/21 DOTA
python实现定时发送qq消息
2019/01/18 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
2019/08/02 Python
pandas的to_datetime时间转换使用及学习心得
2019/08/11 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
2019/08/12 Python
线程安全及Python中的GIL原理分析
2019/10/29 Python
简单了解python元组tuple相关原理
2019/12/02 Python
tensorflow实现在函数中用tf.Print输出中间值
2020/01/21 Python
keras之权重初始化方式
2020/05/21 Python
浅谈Keras的Sequential与PyTorch的Sequential的区别
2020/06/17 Python
使用css3绘制出各种几何图形
2016/08/17 HTML / CSS
Sony C++笔试题
2013/03/10 面试题
二年级学生评语大全
2014/04/23 职场文书
小学生五一劳动节演讲稿
2015/03/18 职场文书
信贷客户经理岗位职责
2015/04/09 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
幼儿园2016年圣诞活动总结
2016/03/31 职场文书
2022年显卡天梯图(6月更新)
2022/06/17 数码科技