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使用cStringIO实现临时内存文件访问的方法
Mar 26 Python
Centos7 Python3下安装scrapy的详细步骤
Mar 15 Python
python+pandas分析nginx日志的实例
Apr 28 Python
在pyqt5中QLineEdit里面的内容回车发送的实例
Jun 21 Python
解决python文件双击运行秒退的问题
Jun 24 Python
用python实现英文字母和相应序数转换的方法
Sep 18 Python
python实现修改固定模式的字符串内容操作示例
Dec 30 Python
django创建超级用户时指定添加其它字段方式
May 14 Python
Python3读写ini配置文件的示例
Nov 06 Python
python反爬虫方法的优缺点分析
Nov 25 Python
Python还能这么玩之用Python做个小游戏的外挂
Jun 04 Python
Python实现生活常识解答机器人
Jun 28 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
计数器详细设计
2006/10/09 PHP
如何在PHP中使用Oracle数据库(5)
2006/10/09 PHP
小偷PHP+Html+缓存
2006/12/20 PHP
通过JavaScript或PHP检测Android设备的代码
2011/03/09 PHP
实例讲解PHP面向对象之多态
2014/08/20 PHP
ThinkPHP上使用多说评论插件的方法
2014/10/31 PHP
CI框架出现mysql数据库连接资源无法释放的解决方法
2016/05/17 PHP
PHP简单实现DES加密解密的方法
2016/07/12 PHP
PHP mysqli事务操作常用方法分析
2017/07/22 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
javascript中IE浏览器不支持NEW DATE()带参数的解决方法
2012/03/01 Javascript
jquery全选checkBox功能实现代码(取消全选功能)
2013/12/10 Javascript
js获取select默认选中的Option并不是当前选中值
2014/05/07 Javascript
教你如何使用PHP输出中文JSON字符串
2014/05/22 Javascript
jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
2015/10/10 Javascript
jQuery的each循环用法简单示例
2016/06/12 Javascript
JS简单实现点击复制链接的方法
2016/08/03 Javascript
老生常谈javascript变量的命名规范和注释
2016/09/29 Javascript
基于JavaScript实现无缝滚动效果
2017/07/21 Javascript
Python3实现购物车功能
2018/04/18 Python
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
python 进程 进程池 进程间通信实现解析
2019/08/23 Python
Pytorch之Variable的用法
2019/12/31 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
2020/04/14 Python
python程序实现BTC(比特币)挖矿的完整代码
2021/01/20 Python
美国畅销的跑步机品牌:ProForm
2017/02/06 全球购物
美国顶级品牌男士大码服装店:DXL
2017/08/30 全球购物
美国家居装饰店:Pier 1
2019/09/04 全球购物
四川internet信息高速公路(C#)笔试题
2012/02/29 面试题
Linux上比较文件的命令都有哪些
2013/09/28 面试题
初一地理教学反思
2014/01/16 职场文书
考察现实表现材料
2014/05/19 职场文书
办公楼租房协议书范本
2014/11/25 职场文书
2015社区爱国卫生工作总结
2015/04/21 职场文书
2016八一建军节慰问信
2015/11/30 职场文书
详解Vue项目的打包方式(生成dist文件)
2022/01/18 Vue.js