一、概论

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基础上改进)的更多相关文章

  1. Python实现决策树C4.5算法

    为什么要改进成C4.5算法 原理 C4.5算法是在ID3算法上的一种改进,它与ID3算法最大的区别就是特征选择上有所不同,一个是基于信息增益比,一个是基于信息增益. 之所以这样做是因为信息增益倾向于选 ...

  2. 02-22 决策树C4.5算法

    目录 决策树C4.5算法 一.决策树C4.5算法学习目标 二.决策树C4.5算法详解 2.1 连续特征值离散化 2.2 信息增益比 2.3 剪枝 2.4 特征值加权 三.决策树C4.5算法流程 3.1 ...

  3. 决策树-C4.5算法(三)

    在上述两篇的文章中主要讲述了决策树的基础,但是在实际的应用中经常用到C4.5算法,C4.5算法是以ID3算法为基础,他在ID3算法上做了如下的改进: 1) 用信息增益率来选择属性,克服了用信息增益选择 ...

  4. 决策树 -- C4.5算法

    C4.5是另一个分类决策树算法,是基于ID3算法的改进,改进点如下: 1.分离信息   解释:数据集通过条件属性A的分离信息,其实和ID3中的熵:   2.信息增益率   解释:Gain(A)为获的A ...

  5. 决策树C4.5算法——计算步骤示例

    使用决策树算法手动计算GOLF数据集 步骤: 1.通过信息增益率筛选分支. (1)共有4个自变量,分别计算每一个自变量的信息增益率. 首先计算outlook的信息增益.outlook的信息增益Gain ...

  6. 机器学习总结(八)决策树ID3,C4.5算法,CART算法

    本文主要总结决策树中的ID3,C4.5和CART算法,各种算法的特点,并对比了各种算法的不同点. 决策树:是一种基本的分类和回归方法.在分类问题中,是基于特征对实例进行分类.既可以认为是if-then ...

  7. 决策树归纳算法之ID3

    学习是一个循序渐进的过程,我们首先来认识一下,什么是决策树.顾名思义,决策树就是拿来对一个事物做决策,作判断.那如何判断呢?凭什么判断呢?都是值得我们去思考的问题. 请看以下两个简单例子: 第一个例子 ...

  8. 决策树(C4.5)原理

    决策树c4.5算法是在决策树ID3上面演变而来. 在ID3中: 信息增益 按属性A划分数据集S的信息增益Gain(S,A)为样本集S的熵减去按属性A划分S后的样本子集的熵,即 在此基础上,C4.5计算 ...

  9. 决策树-预测隐形眼镜类型 (ID3算法,C4.5算法,CART算法,GINI指数,剪枝,随机森林)

    1. 1.问题的引入 2.一个实例 3.基本概念 4.ID3 5.C4.5 6.CART 7.随机森林 2. 我们应该设计什么的算法,使得计算机对贷款申请人员的申请信息自动进行分类,以决定能否贷款? ...

随机推荐

  1. SICP 习题 (1.41)解题总结

    SICP 习题1.41 看似和周边的题目没有关系,突然叫我们去定义一个叫double的过程,事实上这道题的核心还是高阶函数. 题目要求我们定义一个过程double,它以一个过程作为參数,这个作为參数的 ...

  2. Mosquito的优化——epoll优化(七)

    本文由逍遥子撰写,转发请标注原址: http://blog.csdn.net/houjixin/article/details/46413583 或 http://houjixin.blog.163. ...

  3. 当我们谈论Erlang Maps时,我们谈论什么 Part 2

    声明:本文讨论的Erlang Maps是基于17.0-rc2,时间2014-3-4.兴许Maps可能会出现语法或函数API上的有所调整,特此说明. 前情提要: [Erlang 0116] 当我们谈论E ...

  4. WebRTC代码走读(八):代码文件夹结构

    转载注明出处http://blog.csdn.net/wanghorse ├── ./base //基础平台库,包含线程.锁.socket等 ├── ./build //编译脚本.gyp ├── ./ ...

  5. 在openwrt上编译一个最简单的ipk包

    1 什么是opkg Opkg 是一个轻量快速的套件管理系统,目前已成为 Opensource 界嵌入式系统标准.常用于路由.交换机等嵌入式设备中,用来管理软件包的安装升级与下载. opkg updat ...

  6. 关于Spring的69个面试问答——终极列表 (转)

    这篇文章总结了一些关于Spring框架的重要问题,这些问题都是你在面试或笔试过程中可能会被问到的.下次你再也不用担心你的面试了,Java Code Geeks这就帮你解答. 大多数你可能被问到的问题都 ...

  7. asp.net 连接字符串的多种写法

    一.使用OleDbConnection对象连接OLE DB数据源 1.连接Access 数据库 Access 2000: “provider=Microsoft.Jet.Oledb.3.5;Data ...

  8. Ubuntu系统下Import cv2提示no modules ...错误

    最近利用pycharm在Ubuntu系统下调试一个Python项目,将pycharm的解释器从python2.7更换到python3.4后,程序中的Import cv2提示no modules nam ...

  9. GDOI2016酱油记(补发)

    这篇酱油记是前年发在MCHacker一个叫code-hub的博客上的(已崩),现在来补发一下... GDOI2016扯淡(爆零记) 大家好,我是巨弱DCDCBigBig,在五一期间和一群神牛去考GDO ...

  10. 【PRML学习笔记】第四章:分类的线性模型

    一.基础概念 线性分类模型:决策面(decision boundary)是输入向量的线性函数 目标类别的表示"1 of K" :$ t = (0,1,0,0,0)^T$ 二.分类问 ...