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基础上改进)的更多相关文章
- Python实现决策树C4.5算法
为什么要改进成C4.5算法 原理 C4.5算法是在ID3算法上的一种改进,它与ID3算法最大的区别就是特征选择上有所不同,一个是基于信息增益比,一个是基于信息增益. 之所以这样做是因为信息增益倾向于选 ...
- 02-22 决策树C4.5算法
目录 决策树C4.5算法 一.决策树C4.5算法学习目标 二.决策树C4.5算法详解 2.1 连续特征值离散化 2.2 信息增益比 2.3 剪枝 2.4 特征值加权 三.决策树C4.5算法流程 3.1 ...
- 决策树-C4.5算法(三)
在上述两篇的文章中主要讲述了决策树的基础,但是在实际的应用中经常用到C4.5算法,C4.5算法是以ID3算法为基础,他在ID3算法上做了如下的改进: 1) 用信息增益率来选择属性,克服了用信息增益选择 ...
- 决策树 -- C4.5算法
C4.5是另一个分类决策树算法,是基于ID3算法的改进,改进点如下: 1.分离信息 解释:数据集通过条件属性A的分离信息,其实和ID3中的熵: 2.信息增益率 解释:Gain(A)为获的A ...
- 决策树C4.5算法——计算步骤示例
使用决策树算法手动计算GOLF数据集 步骤: 1.通过信息增益率筛选分支. (1)共有4个自变量,分别计算每一个自变量的信息增益率. 首先计算outlook的信息增益.outlook的信息增益Gain ...
- 机器学习总结(八)决策树ID3,C4.5算法,CART算法
本文主要总结决策树中的ID3,C4.5和CART算法,各种算法的特点,并对比了各种算法的不同点. 决策树:是一种基本的分类和回归方法.在分类问题中,是基于特征对实例进行分类.既可以认为是if-then ...
- 决策树归纳算法之ID3
学习是一个循序渐进的过程,我们首先来认识一下,什么是决策树.顾名思义,决策树就是拿来对一个事物做决策,作判断.那如何判断呢?凭什么判断呢?都是值得我们去思考的问题. 请看以下两个简单例子: 第一个例子 ...
- 决策树(C4.5)原理
决策树c4.5算法是在决策树ID3上面演变而来. 在ID3中: 信息增益 按属性A划分数据集S的信息增益Gain(S,A)为样本集S的熵减去按属性A划分S后的样本子集的熵,即 在此基础上,C4.5计算 ...
- 决策树-预测隐形眼镜类型 (ID3算法,C4.5算法,CART算法,GINI指数,剪枝,随机森林)
1. 1.问题的引入 2.一个实例 3.基本概念 4.ID3 5.C4.5 6.CART 7.随机森林 2. 我们应该设计什么的算法,使得计算机对贷款申请人员的申请信息自动进行分类,以决定能否贷款? ...
随机推荐
- 【翻译自mos文章】怎么正确的计算一个ip地址的subnet id?
怎么正确的计算一个ip地址的subnet id? 来源于: How to calculate the correct subnet for an interface (文档 ID 1059759.1) ...
- Codeforce 163 A. Substring and Subsequence DP
A. Substring and Subsequence One day Polycarpus got hold of two non-empty strings s and t, consist ...
- 利用wget 抓取 网站网页 包括css背景图片
利用wget 抓取 网站网页 包括css背景图片 wget是一款非常优秀的http/ftp下载工具,它功能强大,而且几乎所有的unix系统上都有.不过用它来dump比较现代的网站会有一个问题:不支持c ...
- php利用href进行页面传值的正确姿势
首先在a.php中 <?php $a = "world"; echo "<a href='b.php?m=$a'>删除</a>"; ...
- mount ntfs 失败解决办法
在双系统中,ntfs可能会应为windows的缓存而挂载失败.可用下面命令修复. Use ntfsfix in the terminal, even if you can't access Windo ...
- jquery根据接口返回的值来设置asp:CheckBoxList的选中值
接口返回一个json的值,然后通过jquery来选中asp:CheckBoxList相应选中的值 <asp:CheckBoxList runat="server" Repea ...
- Caffe学习--Net分析
Caffe_Net 1.基本数据 vector<shared_ptr<Layer<Dtype> > > layers_; // 记录每一层的layer参数 vect ...
- FCC编程题之中级算法篇(中)
介绍 接着上次的中级算法题 目录 1. Missing letters 2. Boo who 3. Sorted Union 4. Convert HTML Entities 5. Spinal Ta ...
- FCC编程题之中级算法篇(上)
介绍 FCC: 全称为freeCodeCamp,是一个非盈利性的.面向全世界的编程练习网站.这次的算法题来源于FCC的中级算法题. FCC中级算法篇共分为(上).(中).(下)三篇.每篇各介绍7道算法 ...
- 1044 - Access denied for user 'root'@'%' to database 'xahy-blog' 解决方案二
检查 user 表中'root'@'%' 的grant的权限 select HOST,USER,Grant_priv,Super_priv from mysql.`user`; 可以看到现在这两个权限 ...