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抓取网页中的图片示例
Feb 28 Python
Python自动重试HTTP连接装饰器
Apr 28 Python
Python实现采用进度条实时显示处理进度的方法
Dec 19 Python
对numpy Array [: ,] 的取值方法详解
Jul 02 Python
python获取Pandas列名的几种方法
Aug 07 Python
python打印直角三角形与等腰三角形实例代码
Oct 20 Python
python调用jenkinsAPI构建jenkins,并传递参数的示例
Dec 09 Python
python中用ggplot绘制画图实例讲解
Jan 26 Python
pytorch实现手写数字图片识别
May 20 Python
python pygame入门教程
Jun 01 Python
Python OpenCV 图像平移的实现示例
Jun 04 Python
python缺失值的解决方法总结
Jun 09 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中使用Curl、socket、file_get_contents三种方法POST提交数据
2011/08/12 PHP
PHP异步调用socket实现代码
2012/01/12 PHP
PHP中使用sleep函数实现定时任务实例分享
2014/08/21 PHP
DOM基础及php读取xml内容操作的方法
2015/01/23 PHP
PHP微信红包生成代码分享
2016/10/06 PHP
关于ThinkPHP中的异常处理详解
2018/05/11 PHP
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
JS 文件大小判断的实现代码
2010/04/07 Javascript
JS判断是否为数字,是否为整数,是否为浮点数的代码
2010/04/24 Javascript
javascript鼠标跟随运动3种效果(眼球效果,苹果菜单,方向跟随)
2016/10/27 Javascript
jQuery中animate的几种用法与注意事项
2016/12/12 Javascript
JQuery页面随滚动条动态加载效果的简单实现(推荐)
2017/02/08 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
React 源码中的依赖注入方法
2018/11/07 Javascript
Nest.js散列与加密实例详解
2021/02/24 Javascript
Python MySQLdb Linux下安装笔记
2015/05/09 Python
python基础教程之Filter使用方法
2017/01/17 Python
TensorFlow saver指定变量的存取
2018/03/10 Python
Python 共享变量加锁、释放详解
2019/08/28 Python
python爬虫中多线程的使用详解
2019/09/23 Python
基于python的itchat库实现微信聊天机器人(推荐)
2019/10/29 Python
python实现门限回归方式
2020/02/29 Python
使用jupyter notebook直接打开.md格式的文件
2020/04/10 Python
详解python程序中的多任务
2020/09/16 Python
泰国时尚电商:POMELO Fashion
2020/03/11 全球购物
Bitiba意大利:在线宠物商店
2020/10/31 全球购物
俄罗斯家居用品购物网站:Евродом
2020/11/21 全球购物
校本教研工作制度
2014/01/22 职场文书
运动会入场式解说词
2014/02/18 职场文书
教师爱岗敬业演讲稿
2014/05/05 职场文书
任命书范本大全
2014/06/06 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
生死牛玉儒观后感
2015/06/11 职场文书
治庸问责工作总结
2015/08/11 职场文书
升学宴学生致辞
2015/09/29 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书