python实现决策树C4.5算法详解(在ID3基础上改进)

一、概论

C4.5主要是在ID3的基础上改进,ID3选择(属性)树节点是选择信息增益值最大的属性作为节点。而C4.5引入了新概念“信息增益率”,C4.5是选择信息增益率最大的属性作为树节点。

二、信息增益

以上公式是求信息增益率(ID3的知识点)

三、信息增益率

信息增益率是在求出信息增益值在除以

例如下面公式为求属性为“outlook”的值:

四、C4.5的完整代码

from numpy import *
from scipy import *
from math import log
import operator

#计算给定数据的香浓熵:
def calcShannonEnt(dataSet):
 numEntries = len(dataSet)
 labelCounts = {} #类别字典(类别的名称为键,该类别的个数为值)
 for featVec in dataSet:
  currentLabel = featVec[-1]
  if currentLabel not in labelCounts.keys(): #还没添加到字典里的类型
   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: #按dataSet矩阵中的第axis列的值等于value的分数据集
  if featVec[axis] == value:  #值等于value的,每一行为新的列表(去除第axis个数据)
   reducedFeatVec = featVec[:axis]
   reducedFeatVec.extend(featVec[axis+1:])
   retDataSet.append(reducedFeatVec)
 return retDataSet #返回分类后的新矩阵

#选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
 numFeatures = len(dataSet[0])-1 #求属性的个数
 baseEntropy = calcShannonEnt(dataSet)
 bestInfoGain = 0.0; bestFeature = -1
 for i in range(numFeatures): #求所有属性的信息增益
  featList = [example[i] for example in dataSet]
  uniqueVals = set(featList) #第i列属性的取值(不同值)数集合
  newEntropy = 0.0
  splitInfo = 0.0;
  for value in uniqueVals: #求第i列属性每个不同值的熵*他们的概率
   subDataSet = splitDataSet(dataSet, i , value)
   prob = len(subDataSet)/float(len(dataSet)) #求出该值在i列属性中的概率
   newEntropy += prob * calcShannonEnt(subDataSet) #求i列属性各值对于的熵求和
   splitInfo -= prob * log(prob, 2);
  infoGain = (baseEntropy - newEntropy) / splitInfo; #求出第i列属性的信息增益率
  print infoGain;
  if(infoGain > bestInfoGain): #保存信息增益率最大的信息增益率值以及所在的下表(列值i)
   bestInfoGain = infoGain
   bestFeature = i
 return bestFeature 

#找出出现次数最多的分类名称
def majorityCnt(classList):
 classCount = {}
 for vote in classList:
  if vote not in classCount.keys(): classCount[vote] = 0
  classCount[vote] += 1
 sortedClassCount = sorted(classCount.iteritems(), key = operator.itemgetter(1), reverse=True)
 return sortedClassCount[0][0] 

#创建树
def createTree(dataSet, labels):
 classList = [example[-1] for example in dataSet]; #创建需要创建树的训练数据的结果列表(例如最外层的列表是[N, N, Y, Y, Y, N, Y])
 if classList.count(classList[0]) == len(classList): #如果所有的训练数据都是属于一个类别,则返回该类别
  return classList[0];
 if (len(dataSet[0]) == 1): #训练数据只给出类别数据(没给任何属性值数据),返回出现次数最多的分类名称
  return majorityCnt(classList);

 bestFeat = chooseBestFeatureToSplit(dataSet); #选择信息增益最大的属性进行分(返回值是属性类型列表的下标)
 bestFeatLabel = labels[bestFeat] #根据下表找属性名称当树的根节点
 myTree = {bestFeatLabel:{}} #以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 classify(inputTree, featLabels, testVec):
 firstStr = inputTree.keys()[0]
 secondDict = inputTree[firstStr]
 featIndex = featLabels.index(firstStr)
 for key in secondDict.keys():
  if testVec[featIndex] == key:
   if type(secondDict[key]).__name__ == 'dict':
    classLabel = classify(secondDict[key], featLabels, testVec)
   else: classLabel = secondDict[key]
 return classLabel 

#读取数据文档中的训练数据(生成二维列表)
def createTrainData():
 lines_set = open('../data/ID3/Dataset.txt').readlines()
 labelLine = lines_set[2];
 labels = labelLine.strip().split()
 lines_set = lines_set[4:11]
 dataSet = [];
 for line in lines_set:
  data = line.split();
  dataSet.append(data);
 return dataSet, labels

#读取数据文档中的测试数据(生成二维列表)
def createTestData():
 lines_set = open('../data/ID3/Dataset.txt').readlines()
 lines_set = lines_set[15:22]
 dataSet = [];
 for line in lines_set:
  data = line.strip().split();
  dataSet.append(data);
 return dataSet

myDat, labels = createTrainData()
myTree = createTree(myDat,labels)
print myTree
bootList = ['outlook','temperature', 'humidity', 'windy'];
testList = createTestData();
for testData in testList:
 dic = classify(myTree, bootList, testData)
 print dic

五、C4.5与ID3的代码区别

如上图,C4.5主要在第52、53行代码与ID3不同(ID3求的是信息增益,C4.5求的是信息增益率)。

六、训练、测试数据集样例

训练集:

 outlook temperature humidity windy
 ---------------------------------------------------------
 sunny  hot    high   false   N
 sunny  hot    high   true   N
 overcast hot    high   false   Y
 rain  mild   high   false   Y
 rain  cool   normal  false   Y
 rain  cool   normal  true   N
 overcast cool   normal  true   Y

测试集
 outlook temperature humidity windy
 -----------------------------------------------
 sunny  mild   high   false
 sunny  cool   normal  false
 rain   mild   normal  false
 sunny  mild   normal  true
 overcast mild   high   true
 overcast hot    normal  false
 rain   mild   high   true  

以上这篇python实现决策树C4.5算法详解(在ID3基础上改进)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2017-05-30

决策树的python实现方法

本文实例讲述了决策树的python实现方法.分享给大家供大家参考.具体实现方法如下: 决策树算法优缺点: 优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关的特征数据 缺点:可能会产生过度匹配的问题 适用数据类型:数值型和标称型 算法思想: 1.决策树构造的整体思想: 决策树说白了就好像是if-else结构一样,它的结果就是你要生成这个一个可以从根开始不断判断选择到叶子节点的树,但是呢这里的if-else必然不会是让我们认为去设置的,我们要做的是提供一种方法,计算机可以根

机器学习python实战之决策树

决策树原理:从数据集中找出决定性的特征对数据集进行迭代划分,直到某个分支下的数据都属于同一类型,或者已经遍历了所有划分数据集的特征,停止决策树算法. 每次划分数据集的特征都有很多,那么我们怎么来选择到底根据哪一个特征划分数据集呢?这里我们需要引入信息增益和信息熵的概念. 一.信息增益 划分数据集的原则是:将无序的数据变的有序.在划分数据集之前之后信息发生的变化称为信息增益.知道如何计算信息增益,我们就可以计算根据每个特征划分数据集获得的信息增益,选择信息增益最高的特征就是最好的选择.首先我们先来

基于ID3决策树算法的实现(Python版)

实例如下: # -*- coding:utf-8 -*- from numpy import * import numpy as np import pandas as pd from math import log import operator #计算数据集的香农熵 def calcShannonEnt(dataSet): numEntries=len(dataSet) labelCounts={} #给所有可能分类创建字典 for featVec in dataSet: currentLa

python 决策树算法的实现

''' 数据集:Mnist 训练集数量:60000 测试集数量:10000 ------------------------------ 运行结果:ID3(未剪枝) 正确率:85.9% 运行时长:356s ''' import time import numpy as np def loadData(fileName): ''' 加载文件 :param fileName:要加载的文件路径 :return: 数据集和标签集 ''' # 存放数据及标记 dataArr = []; labelArr

基于Python实现的ID3决策树功能示例

本文实例讲述了基于Python实现的ID3决策树功能.分享给大家供大家参考,具体如下: ID3算法是决策树的一种,它是基于奥卡姆剃刀原理的,即用尽量用较少的东西做更多的事.ID3算法,即Iterative Dichotomiser 3,迭代二叉树3代,是Ross Quinlan发明的一种决策树算法,这个算法的基础就是上面提到的奥卡姆剃刀原理,越是小型的决策树越优于大的决策树,尽管如此,也不总是生成最小的树型结构,而是一个启发式算法. 如下示例是一个判断海洋生物数据是否是鱼类而构建的基于ID3思想

python基于ID3思想的决策树

这是一个判断海洋生物数据是否是鱼类而构建的基于ID3思想的决策树,供大家参考,具体内容如下 # coding=utf-8 import operator from math import log import time def createDataSet(): dataSet = [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no'], [0,0,'maybe']] labels = ['no surface

python 基于卡方值分箱算法的实现示例

原理很简单,初始分20箱或更多,先确保每箱中都含有0,1标签,对不包含0,1标签的箱向前合并,计算各箱卡方值,对卡方值最小的箱向后合并,代码如下 import pandas as pd import numpy as np import scipy from scipy import stats def chi_bin(DF,var,target,binnum=5,maxcut=20): ''' DF:data var:variable target:target / label binnum:

应用OpenCV和Python进行SIFT算法的实现详解

应用OpenCV和Python进行SIFT算法的实现 如下图为进行测试的gakki101和gakki102,分别验证基于BFmatcher.FlannBasedMatcher等的SIFT算法,对比其优劣.为体现出匹配效果对于旋转特性的优势,将图gakki101做成具有旋转特性的效果. 基于BFmatcher的SIFT实现 BFmatcher(Brute-Force Matching)暴力匹配,应用BFMatcher.knnMatch( )函数来进行核心的匹配,knnMatch(k-nearest

python Canny边缘检测算法的实现

图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.对于数字图像的离散信号,微分运算就变成计算差分或梯度.图像处理中有多种边缘检测(梯度)算子,常用的包括普通一阶差分,Robert算子(交叉差分),Sobel算子等等,是基于寻找梯度强度.拉普拉斯算子(二阶差分)是基于过零点检测.通过计算梯度,设置阀值,得到边缘图像. Canny边缘检测算子是一种多级检测算法.1986年由J

python常用排序算法的实现代码

这篇文章主要介绍了python常用排序算法的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 排序是计算机语言需要实现的基本算法之一,有序的数据结构会带来效率上的极大提升. 1.插入排序 插入排序默认当前被插入的序列是有序的,新元素插入到应该插入的位置,使得新序列仍然有序. def insertion_sort(old_list): n=len(old_list) k=0 for i in range(1,n): temp=old_lis

python 贪心算法的实现

贪心算法 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关. 基本思路 思想 贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解.每一步只考虑一个数据,他的选取应该满足局部优化的条件.若

python em算法的实现

''' 数据集:伪造数据集(两个高斯分布混合) 数据集长度:1000 ------------------------------ 运行结果: ---------------------------- the Parameters set is: alpha0:0.3, mu0:0.7, sigmod0:-2.0, alpha1:0.5, mu1:0.5, sigmod1:1.0 ---------------------------- the Parameters predict is: al