Python实现决策树C4.5算法的示例


Posted in Python onMay 30, 2018

为什么要改进成C4.5算法

原理

C4.5算法是在ID3算法上的一种改进,它与ID3算法最大的区别就是特征选择上有所不同,一个是基于信息增益比,一个是基于信息增益。

之所以这样做是因为信息增益倾向于选择取值比较多的特征(特征越多,条件熵(特征划分后的类别变量的熵)越小,信息增益就越大);因此在信息增益下面加一个分母,该分母是当前所选特征的熵,注意:这里而不是类别变量的熵了。

这样就构成了新的特征选择准则,叫做信息增益比。为什么加了这样一个分母就会消除ID3算法倾向于选择取值较多的特征呢?

因为特征取值越多,该特征的熵就越大,分母也就越大,所以信息增益比就会减小,而不是像信息增益那样增大了,一定程度消除了算法对特征取值范围的影响。

实现

在算法实现上,C4.5算法只是修改了信息增益计算的函数calcShannonEntOfFeature和最优特征选择函数chooseBestFeatureToSplit。

calcShannonEntOfFeature在ID3的calcShannonEnt函数上加了个参数feat,ID3中该函数只用计算类别变量的熵,而calcShannonEntOfFeature可以计算指定特征或者类别变量的熵。

chooseBestFeatureToSplit函数在计算好信息增益后,同时计算了当前特征的熵IV,然后相除得到信息增益比,以最大信息增益比作为最优特征。

在划分数据的时候,有可能出现特征取同一个值,那么该特征的熵为0,同时信息增益也为0(类别变量划分前后一样,因为特征只有一个取值),0/0没有意义,可以跳过该特征。

Python实现决策树C4.5算法的示例

#coding=utf-8
import operator
from math import log
import time
import os, sys
import string

def createDataSet(trainDataFile):
 print trainDataFile
 dataSet = []
 try:
 fin = open(trainDataFile)
 for line in fin:
  line = line.strip()
  cols = line.split('\t')
  row = [cols[1], cols[2], cols[3], cols[4], cols[5], cols[6], cols[7], cols[8], cols[9], cols[10], cols[0]]
  dataSet.append(row)
  #print row
 except:
 print 'Usage xxx.py trainDataFilePath'
 sys.exit()
 labels = ['cip1', 'cip2', 'cip3', 'cip4', 'sip1', 'sip2', 'sip3', 'sip4', 'sport', 'domain']
 print 'dataSetlen', len(dataSet)
 return dataSet, labels

#calc shannon entropy of label or feature
def calcShannonEntOfFeature(dataSet, feat):
 numEntries = len(dataSet)
 labelCounts = {}
 for feaVec in dataSet:
 currentLabel = feaVec[feat]
 if currentLabel not in labelCounts:
  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:
 if featVec[axis] == value:
  reducedFeatVec = featVec[:axis]
  reducedFeatVec.extend(featVec[axis+1:])
  retDataSet.append(reducedFeatVec)
 return retDataSet
 
def chooseBestFeatureToSplit(dataSet):
 numFeatures = len(dataSet[0]) - 1 #last col is label
 baseEntropy = calcShannonEntOfFeature(dataSet, -1)
 bestInfoGainRate = 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 *calcShannonEntOfFeature(subDataSet, -1) #calc conditional entropy
 infoGain = baseEntropy - newEntropy
  iv = calcShannonEntOfFeature(dataSet, i)
 if(iv == 0): #value of the feature is all same,infoGain and iv all equal 0, skip the feature
 continue
 
 infoGainRate = infoGain / iv
 if infoGainRate > bestInfoGainRate:
  bestInfoGainRate = infoGainRate
  bestFeature = i
 return bestFeature
  
#feature is exhaustive, reture what you want label
def majorityCnt(classList):
 classCount = {}
 for vote in classList:
 if vote not in classCount.keys():
  classCount[vote] = 0
 classCount[vote] += 1
 return max(classCount)  
 
def createTree(dataSet, labels):
 classList = [example[-1] for example in dataSet]
 if classList.count(classList[0]) ==len(classList): #all data is the same label
 return classList[0]
 if len(dataSet[0]) == 1: #all feature is exhaustive
 return majorityCnt(classList)
 bestFeat = chooseBestFeatureToSplit(dataSet)
 bestFeatLabel = labels[bestFeat]
 if(bestFeat == -1): #特征一样,但类别不一样,即类别与特征不相关,随机选第一个类别做分类结果
 return classList[0] 
 myTree = {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 main():
 if(len(sys.argv) < 3):
 print 'Usage xxx.py trainSet outputTreeFile'
 sys.exit()
 data,label = createDataSet(sys.argv[1])
 t1 = time.clock()
 myTree = createTree(data,label)
 t2 = time.clock()
 fout = open(sys.argv[2], 'w')
 fout.write(str(myTree))
 fout.close()
 print 'execute for ',t2-t1
if __name__=='__main__':
 main()

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

Python 相关文章推荐
Python中使用PDB库调试程序
Apr 05 Python
python json.loads兼容单引号数据的方法
Dec 19 Python
解决pyqt5中QToolButton无法使用的问题
Jun 21 Python
python实现比较类的两个instance(对象)是否相等的方法分析
Jun 26 Python
python flask web服务实现更换默认端口和IP的方法
Jul 26 Python
python中的Elasticsearch操作汇总
Oct 30 Python
pytorch之添加BN的实现
Jan 06 Python
python实现猜数游戏
Mar 27 Python
Python爬虫实现HTTP网络请求多种实现方式
Jun 19 Python
详解Python IO编程
Jul 24 Python
Pycharm连接gitlab实现过程图解
Sep 01 Python
python数据分析之单因素分析线性拟合及地理编码
Jun 25 Python
python实现决策树ID3算法的示例代码
May 30 #Python
浅谈Django中的数据库模型类-models.py(一对一的关系)
May 30 #Python
Python实现的读取电脑硬件信息功能示例
May 30 #Python
Python应用库大全总结
May 30 #Python
Django中反向生成models.py的实例讲解
May 30 #Python
Python RabbitMQ消息队列实现rpc
May 30 #Python
python日期时间转为字符串或者格式化输出的实例
May 29 #Python
You might like
php下将图片以二进制存入mysql数据库中并显示的实现代码
2010/05/27 PHP
CentOS 6.3下安装PHP xcache扩展模块笔记
2014/09/10 PHP
PHP图像裁剪缩略裁切类源码及使用方法
2016/01/07 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
php自定义函数实现二维数组按指定key排序的方法
2016/09/29 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
PHP结合jquery ajax实现上传多张图片,并限制图片大小操作示例
2019/03/01 PHP
JQuery中html()方法使用不当带来的陷阱
2011/04/07 Javascript
Node.js实战 建立简单的Web服务器
2012/03/08 Javascript
Javascript核心读书有感之词法结构
2015/02/01 Javascript
常见的javascript跨域通信方法
2015/12/31 Javascript
js仿百度切换皮肤功能(html+css)
2016/07/10 Javascript
JavaScript无操作后屏保功能的实现方法
2017/07/04 Javascript
深入理解Vue transition源码分析
2017/07/30 Javascript
使用Vue构建可重用的分页组件
2018/03/26 Javascript
Fabric 应用案例
2016/08/28 Python
Python中表达式x += y和x = x+y 的区别详解
2017/06/20 Python
python抓取文件夹的所有文件
2018/02/27 Python
python打包生成的exe文件运行时提示缺少模块的解决方法
2018/10/31 Python
详解Python odoo中嵌入html简单的分页功能
2019/05/29 Python
python 读取二进制 显示图片案例
2020/04/24 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
CSS3属性使网站设计增强同时不消弱可用性
2009/08/29 HTML / CSS
香港交友网站:be2香港
2018/07/22 全球购物
视图的作用
2014/12/19 面试题
几道数据库的面试题或笔试题
2014/05/31 面试题
优秀教师先进事迹
2014/01/22 职场文书
2014年国培研修感言
2014/03/09 职场文书
2014乡镇干部纪律作风整顿思想汇报
2014/09/13 职场文书
大学生党员个人对照检查材料范文
2014/09/25 职场文书
财务整改报告范文
2014/11/05 职场文书
合作与交流自我评价
2015/03/09 职场文书
公务员廉洁从政心得体会
2016/01/19 职场文书
小学一年级数学教学反思
2016/02/16 职场文书
Linux7.6二进制安装Mysql8.0.27详细操作步骤
2021/11/27 MySQL
Nebula Graph解决风控业务实践
2022/03/31 MySQL