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 14 Python
查找python项目依赖并生成requirements.txt的方法
Jul 10 Python
解决vscode python print 输出窗口中文乱码的问题
Dec 03 Python
django 自定义过滤器的实现
Feb 26 Python
Python 类属性与实例属性,类对象与实例对象用法分析
Sep 20 Python
基于python cut和qcut的用法及区别详解
Nov 22 Python
Pytorch Tensor 输出为txt和mat格式方式
Jan 03 Python
python定义类self用法实例解析
Jan 22 Python
Python使用ElementTree美化XML格式的操作
Mar 06 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
Jun 29 Python
python3 删除所有自定义变量的操作
Apr 08 Python
Django框架中视图的用法
Jun 10 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 过滤危险html代码
2009/06/29 PHP
php 无法载入mysql扩展
2010/03/12 PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
2014/06/19 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
Laravel框架Auth用户认证操作实例分析
2019/09/29 PHP
用js+xml自动生成表格的东西
2006/12/21 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
JQuery对表单元素的基本操作使用总结
2014/07/18 Javascript
js实现ArrayList功能附实例代码
2014/10/29 Javascript
JavaScript基础知识学习笔记
2014/12/02 Javascript
JavaScript动态添加css样式和script标签
2016/07/19 Javascript
webpack 1.x升级过程中的踩坑总结大全
2017/08/09 Javascript
js中getBoundingClientRect的作用及兼容方案详解
2018/02/01 Javascript
JavaScript实现多态和继承的封装操作示例
2018/08/20 Javascript
vue+element 模态框表格形式的可编辑表单实现
2019/06/07 Javascript
vue.js的简单自动求和计算实例
2019/11/08 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
Python中的进程分支fork和exec详解
2015/04/11 Python
python图像常规操作
2017/11/11 Python
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
2020/04/18 Python
python list多级排序知识点总结
2019/10/23 Python
Python3 requests模块如何模仿浏览器及代理
2020/06/15 Python
Pycharm新手使用教程(图文详解)
2020/09/17 Python
html5新增的属性和废除的属性简要概述
2013/02/20 HTML / CSS
canvas使用注意点总结
2013/07/19 HTML / CSS
全球知名鞋履品牌授权零售商:Journeys
2016/09/17 全球购物
Myprotein荷兰官网:欧洲第一运动营养品牌
2020/07/11 全球购物
大学应届毕业生个人求职信
2013/09/23 职场文书
自我鉴定范文
2013/11/10 职场文书
教师自我鉴定
2013/12/13 职场文书
三方股东合作协议书
2014/10/28 职场文书
2015年元旦主持词结束语
2014/12/14 职场文书
客户经理岗位职责
2015/01/31 职场文书
2016年公司新年寄语
2015/08/17 职场文书
2016秋季幼儿园开学寄语
2015/12/03 职场文书