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注释详解
Jun 01 Python
Python3 queue队列模块详细介绍
Jan 05 Python
详解python多线程之间的同步(一)
Apr 03 Python
Python 点击指定位置验证码破解的实现代码
Sep 11 Python
使用Pandas的Series方法绘制图像教程
Dec 04 Python
python实现高斯判别分析算法的例子
Dec 09 Python
Python编程快速上手——Excel表格创建乘法表案例分析
Feb 28 Python
浅谈Python的方法解析顺序(MRO)
Mar 05 Python
keras得到每层的系数方式
Jun 15 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
Jun 24 Python
Python性能分析工具py-spy原理用法解析
Jul 27 Python
Python模块常用四种安装方式
Oct 20 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统计数值数组中出现频率最多的10个数字的方法
2015/04/20 PHP
学习php设计模式 php实现装饰器模式(decorator)
2015/12/07 PHP
PHP数组游标实现对数组的各种操作详解
2016/01/26 PHP
Zend Framework基本页面布局分析
2016/03/19 PHP
CI框架常用方法小结
2016/05/17 PHP
PHP实现加密文本文件并限制特定页面的存取的效果
2016/10/21 PHP
PHP递归实现汉诺塔问题的方法示例
2017/11/25 PHP
jQuery在IE下使用未闭合的xml代码创建元素时的Bug介绍
2012/01/10 Javascript
DWR3 访问WEB元素的两种方法实例详解
2017/01/03 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
echarts设置图例颜色和地图底色的方法实例
2018/08/01 Javascript
vue.js 中使用(...)运算符报错的解决方法
2018/08/09 Javascript
js正则取值的结果数组调试方法
2018/10/10 Javascript
微信小程序 textarea 层级过高问题简单解决方案
2019/10/14 Javascript
阿望教你用vue写扫雷小游戏
2020/01/20 Javascript
vue如何在项目中调用腾讯云的滑动验证码
2020/07/15 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
2021/01/06 Javascript
Python time模块详解(常用函数实例讲解,非常好)
2014/04/24 Python
Python实现利用最大公约数求三个正整数的最小公倍数示例
2017/09/30 Python
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
在Python中获取两数相除的商和余数方法
2018/11/10 Python
python实现趣味图片字符化
2019/04/30 Python
python添加菜单图文讲解
2019/06/04 Python
Tensorflow模型实现预测或识别单张图片
2019/07/19 Python
python双向链表原理与实现方法详解
2019/12/03 Python
python3 常见解密加密算法实例分析【base64、MD5等】
2019/12/19 Python
在tensorflow中实现去除不足一个batch的数据
2020/01/20 Python
python 操作excel表格的方法
2020/12/05 Python
一文带你掌握Pyecharts地理数据可视化的方法
2021/02/06 Python
有影响力的人、名人和艺术家的官方商品:Represent
2019/11/26 全球购物
The North Face意大利官网:服装、背包和鞋子
2020/06/17 全球购物
领导班子个人查摆问题对照检查材料
2014/10/02 职场文书
上甘岭观后感
2015/06/10 职场文书
宝葫芦的秘密观后感
2015/06/11 职场文书