C4.5是基于ID3改进的分类决策树算法,特点是C4.用信息增益率来选择属性,而ID3使用的是熵(entropy, 熵是一种不纯度度量准则),且对非离散数据也能处理,能够对不完整数据进行处理。

  • 1、信息熵:
  • 2、条件熵:
  • 3、信息增益:

    g(D,A)​=H(D)-H(D/A)

    4、信息增益率:

    gr(D,A)=g(D,A)/H(A)​

参考代码如下:

1)C45DTree.py

# -*- coding: utf-8 -*-from numpy import *
import math
import copy
import cPickle as pickleclass 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(",") for row in rowList if row.strip()]  # strip()函数删除空格、Tab等self.dataSet = recordListself.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] = subTreereturn 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 ratioallFeatVList = []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.0for value in featureValueList:subSet = self.splitDataSet(dataSet, f, value)appearNum = float(len(subSet))subEntropy = self.computeEntropy(subSet)resultGain += (appearNum/totality)*subEntropyConditionEntropy.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# 计算信息熵# @staticmethoddef 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.0for key in items:  # 香农熵: = -p*log2(p) --infoEntropy = -prob * log(prob, 2)prob = float(items[key]) / dataLeninfoEntropy -= 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)

2)C45DTreeDemo.py

# -*- coding: utf-8 -*-from numpy import *
from C45DTree import *dtree = C45DTree()
dtree.loadDataSet("D:\dataset.dat",["outlook", "temperature", "humidity", "windy"])
dtree.train()dtree.storetree(dtree.tree, "data.tree")
mytree = dtree.grabTree("data.tree")print mytree

3)测试数据和执行结果:

0, 0, 0, 0, N
0, 0, 0, 1, N
1, 0, 0, 0, Y
2, 1, 0, 0, Y
2, 2, 1, 0, Y
2, 2, 1, 1, N
1, 2, 1, 1, Y
{'windy': {' 0': {'outlook': {'1': ' Y ', '0': ' N ', '2': ' Y '}}, ' 1': {'outlook': {'1': ' Y', '0': ' N ', '2': ' N '}}}}

【Python学习系列十一】Python实现决策树实现C4.5(信息增益率)相关推荐

  1. Python学习系列 -- 改善 Python 程序的 91 个建议

    转载自:https://zhuanlan.zhihu.com/p/32817459 自己写Python也有四五年了,一直是用自己的"强迫症"在维持自己代码的质量,除了Google的 ...

  2. python学习笔记(十一)-python程序目录工程化

    在一个程序当中,一般都会包含文件夹:bin.conf.lib.data.logs,以及readme文件. 所写程序存放到各自的文件夹中,如何进行串联? 首先,通过导入文件导入模块方式,引用其他人写好的 ...

  3. Python学习系列(六)(模块)

    Python学习系列(六)(模块) Python学习系列(五)(文件操作及其字典) 一,模块的基本介绍 1,import引入其他标准模块 标准库:Python标准安装包里的模块. 引入模块的几种方式: ...

  4. Python学习系列(五)(文件操作及其字典)

    Python学习系列(五)(文件操作及其字典) Python学习系列(四)(列表及其函数) 一.文件操作 1,读文件      在以'r'读模式打开文件以后可以调用read函数一次性将文件内容全部读出 ...

  5. Python: 学习系列之七:模块、PIPY及Anaconda

    系列 Python: 学习系列之一:Python能做什么 Python: 学习系列之二:基础介绍(int/float/string/range/list/tuple/dict/set) Python: ...

  6. python学习一(python与pip工具下载与安装)

    python学习一(python与pip工具下载与安装)  一 Python下载  二 安装Python  三 安装 pip   3.1 采用cd命令进入到Scripts 目录下面   3.2 输入命 ...

  7. Python学习教程(Python学习视频_Python学些路线):Day05 总结和练习

    Python学习教程(Python学习视频_Python学些路线):总结和练习 练习清单 寻找"水仙花数". 寻找"完美数". "百钱百鸡" ...

  8. Python学习教程(Python学习路线):Python面试100题(二)

    Python学习教程(Python学习路线):面试题接着给大家整理! 16.<div class="nam">中国</div>,用正则匹配出标签里面的内容( ...

  9. Python学习之解决python下载第三方依赖速度慢的问题

    Python学习之解决python下载第三方依赖速度慢的问题 参考文章: (1)Python学习之解决python下载第三方依赖速度慢的问题 (2)https://www.cnblogs.com/su ...

最新文章

  1. 产品定义到产品推广的思路
  2. 数据库连接出错,请检查连接字串"的多种问题解决办法
  3. kafka内存不断增加_为什么 Kafka 能这么快的 6 个原因
  4. 1008. Elevator (20)
  5. C语言 vprintf 函数 - C语言零基础入门教程
  6. aop的实现原理_非Spring管理Bean如何添加AOP呢?
  7. Python3.x学习资料汇总(待续)
  8. 以下关于java文件名的叙述正确的有_sun java认证考试题库
  9. Git教程 Git Bash详细教程
  10. 静态路由的简单案例(华为),一看就会
  11. ansys变形太夸张_ANSYS大变形典例:线性与非线性分析差别巨大,如何选择?
  12. 医疗 PACS 系统的海量影像数据归档实例
  13. The Backrooms - Level 0.2 - 我爱杏仁水
  14. 鹏业安装算量常见安装问题处理
  15. unreal world 皮革_不真实的世界Unreal World新手速刷攻略是什么?
  16. 不要说话 -- 陈奕迅/小柯
  17. 融云红包上线 要让每一款App都能“抢红包”
  18. 小程序微信支付功能开发
  19. 基于C#分步式聊天系统的在线视频直播系统 之 FY.Logfiles(日志文件组件)
  20. 价值 20 万美元的爱马仕包包是用蘑菇做的,你还会买吗?

热门文章

  1. Dokcer容器实战之部署论坛
  2. sap在线服务器,SAP服务器常用端口
  3. c语言中int*point 其中point是指针变量名,2012年计算机等级二级C语言章节习题及答案(9)...
  4. java http 上传_Java使用HttpURLConnection上传文件
  5. 基于iview 封装一个vue 表格分页组件
  6. Git 撤销中间某次的提交记录
  7. POJ 2182 Lost Cows (求序列第k大)
  8. javascript 手机号间隔显示 123 4567 8910
  9. (转)在Eclipse中创建Maven多模块工程
  10. GO 输出字符数同时输出这个字符串的字节数