决策树算法C4.5算法

1.1 题目的主要研究内容

  1. 组的主要任务描述

熟悉和掌握决策树的分类原理、实质和过程,掌握决策树典型算法(ID3、C4.5、CART)的核心思想和实现过程。

(2)自己工作的主要描述(宋体小四号不加粗1.5倍行距)

首先进行决策树中C4.5算法的概述及其C4.5算法的思想、说明C4.5算法的原理及其推导过程、C4.5算法的流程、C4.5算法就ID3算法的差异、C4.5算法改进的优缺点。

1.2 C4.5算法概述

C4.5算法之所以是最常用的决策树算法,是因为它继承了ID3算法的所有优点并对ID3算的进行了改进和补充。C4.5算法采用信息增益率作为选择分支属性的标准,克服了ID3算法中信息增益选择属性时偏向选择取值多的属性的不足,并能够完成对连续属性离散化是处理,还能够对不完整数据进行处理。C4.5算法属于基于信息论(Information Theory)的方法,它是以信息论为基础,以信息熵和信息增益度为衡量标准,从而实现对数据的归纳分类。

1.3 C4.5算法的思想

C4.5算法与ID3算法生成决策树的步骤过程基本相同,主要区别在于连续型属性和属性度量的计算,ID3算法不能处理连续型属性,而C4.5算法可以先离散化连续型属性,然后进行属性选择计算;在属性度量计算时,ID3算法利用信息增益进行属性选择计算,C4.5 算法则运用信息增益率计算。

1.4 C4.5算法相对于ID3算法改进之后有如下优点:

(1) C4.5算法的最大改进就是不在用信息增益来选择属性,而是采用信息增率,这么做就可以避免那些样本数量多但却对分类贡献少的属性作为根节点,提高了算法准确率。

(2)对树进行前剪枝,发现数据有问题可以及时处理,不用等到树建完后在对其剪枝,这样就大大提高了算法效率。

(3)能够通过对数据进行泛化,使连续数据离散化,从而增加了对连续数据的处理能力。

(4)在面对有缺失的数据时,C4.5算法依然能够有效处理。

1.5 C4.5算法信息增益率

信息增益率就是对信息增益进行了规范化,即C4.5算法思想运用信息增益率公式替换了ID3算法中的信息增益的计算思想。

信息增益的规范化用到了“分裂信息(split information)”的概念。

在训练集T中,公式表达了属性A的分裂信息。

与信息增益不同的是,信息增益率是用来计量相同的划分所获得的信息。

即为属性A的增益率的计算公式。

由上面公式公式可知C4.5算法的具体具体公式。

在用C4.5算法构造决策树时,信息增益率最大的属性即为当前节点的分裂属性,随着递归计算,被计算的属性的信息增益率会变得越来越小,到后期则选择相对比较大的信息增益率的条件属性作为分裂属性。

1.6 C4.5算法流程图

1.7 C4.5算法生成决策树的步骤

Stepl:创建一个节点N。

Step2:IF训练数据集为空,THEN返回单个节点N作为空的叶子节点。

Step3:IF训练集中的所有样本都属于同一个类C,THEN返回节点N为叶节点并将该节点标记为类C。

Step4:IF训练集的属性列表为空,THEN返回N作为叶节点,并标记为数据集中样本多的类别。

Step5:IF属性是连续型的,THEN对该属性进行离散化。

Step6:根据公式(2.8)计算属性列表中属性的信息增益率。

Step7:选择最高的信息增益率的属性A,并把节点N标记为属性A

Step8:递归方式循环以上步骤,得到初步决策树。

Step9:利用更大的训练数据集对决策树进行修剪(优化)。

在进行决策树构造时,会根据数据集中的信息判断是否满足停止建树的条件,否则继续迭代。一般情况下,结束的条件主要有:属性列表为空; 数据集中样本都已经归类;所剩样本都属于同一个类。满足其中一个条件便结束建树,得到初始的决策树。接着运用后剪枝的策略进行剪枝,简化决策树。

1.8主要程序代码

import numpy as np

import pandas as pd

import time

from sklearn.metrics import accuracy_score

from utils.plotDecisionTree import *

#计算经验熵

def calcEntropy(dataSet):

mD = len(dataSet)                       # mD表示数据集的数据向量个数

dataLabelList = [x[-1] for x in dataSet]       # 数据集最后一列 标签

dataLabelSet = set(dataLabelList)          # 转化为标签集合,集合不重复,所以转化

ent = 0

for label in dataLabelSet:                  # 对于集合中的每一个标签

mDv = dataLabelList.count(label)       # 统计它出现的次数

prop = float(mDv) / mD               # 计算频率

ent = ent - prop * np.math.log(prop, 2)   # 计算条件熵,见算法预备知识

return ent

#计算经验条件熵

def calcCondEntropy(dataSet,featureSet,i):

mD = len(dataSet)

ent=0

for feature in featureSet:

# 拆分数据集,去除第i行数据特征

splitedDataSet = splitDataSet(dataSet, i, feature)

mDv = len(splitedDataSet)

ent = ent + float(mDv) / mD * calcEntropy(splitedDataSet)

return ent

# 拆分数据集

# index   要拆分的特征的下标

# feature 要拆分的特征

# 返回值   dataSet中index所在特征为feature,且去掉index一列的集合

def splitDataSet(dataSet, index, feature):

splitedDataSet = []

mD = len(dataSet)

for data in dataSet:

if(data[index] == feature):                 # 将数据集拆分

sliceTmp = data[:index]                 # 取[0,index)

sliceTmp.extend(data[index + 1:])       # 扩展(index,len]

splitedDataSet.append(sliceTmp)

return splitedDataSet

# 根据信息增益比,选择最佳的特征,并且返回最佳特征的下标

def chooseBestFeature_C45(dataSet):

entD = calcEntropy(dataSet)                     # 计算经验熵

featureNumber = len(dataSet[0]) - 1

maxGainRatio = -100                          # 最大增益比

maxIndex = -1                                # 最大增益比下标

GainRatio=0

for i in range(featureNumber):

featureI = [x[i] for x in dataSet]          # 数据集合中的第i列特征

featureSet = set(featureI)                  # 特征集合

# 计算信息增益比

GainRatio = (entD - calcCondEntropy(dataSet,featureSet,i)) / entD

if(maxIndex == -1):

maxGainRatio = GainRatio            #利用GainRatio选择子树的根节点

maxIndex = i

elif(maxGainRatio < GainRatio):             # 记录最大的信息增益和下标

maxGainRatio = GainRatio

maxIndex = i

return maxIndex                              # 返回下标

# 寻找最多的特征,作为标签

def mainLabel(labelList):

labelRec = labelList[0]

maxLabelCount = -1

labelSet = set(labelList)

for label in labelSet:

if(labelList.count(label) > maxLabelCount):

maxLabelCount = labelList.count(label)

labelRec = label

return labelRec

# 生成决策树

# dataSet:数据集, featureNames:数据属性类别, featureNamesSet:属性类别集合, labelListParent:父节点标签列表

def createFullDecisionTree(dataSet, featureNames, featureNamesSet, labelListParent):

labelList = [x[-1] for x in dataSet]

if(len(dataSet) == 0):             # 如果数据集为空,返回父节点标签列表的主要标签

return mainLabel(labelListParent)

elif(len(dataSet[0]) == 1):  # 没有可划分的属性,选出最多的label作为该数据集的标签

return mainLabel(labelList)

elif(labelList.count(labelList[0]) == len(labelList)):  # 全部都属于同一个Label,返回labList[0]

return labelList[0]

# 不满足上面的边界情况则需要创建新的分支节点

bestFeatureIndex = chooseBestFeature_C45(dataSet)      # 根据信息增益,选择数据集中最好的特征下标

bestFeatureName = featureNames.pop(bestFeatureIndex)    # 取出属性类别

myTree = {bestFeatureName: {}}                      # 新建节点,一个字典

featureList = featureNamesSet.pop(bestFeatureIndex)     # 取出最佳属性的类别

featureSet = set(featureList)                           # 剔除属性类别集合

for feature in featureSet:                              # 遍历最佳属性所有取值

featureNamesNext = featureNames[:]

featureNamesSetNext = featureNamesSet[:][:]

splitedDataSet = splitDataSet(dataSet, bestFeatureIndex, feature)   # 剔除最佳特征

# 递归地生成新的节点

# featureNames:数据属性类别, featureNamesSet:属性类别集合, labelListParent:父节点标签列表

# 一个二叉树

myTree[bestFeatureName][feature] = createFullDecisionTree(splitedDataSet, featureNamesNext, featureNamesSetNext, labelList)

return myTree

# 读取数据集

def readDataSet(path):

ifile = open(path,"r",encoding="utf-8")

#表头

featureName = ifile.readline()

featureName = featureName.rstrip("\n")

#类别,属性

featureNames = (featureName.split(' ')[0]).split(',')

#读取文件

lines = ifile.readlines()

#数据集

dataSet = []

for line in lines:

tmp = line.split('\n')[0]

tmp = tmp.split(',')

dataSet.append(tmp)

#获取标签

labelList = [x[-1] for x in dataSet]

#获取featureNamesSet

featureNamesSet = []

for i in range(len(dataSet[0]) - 1):

col = [x[i] for x in dataSet]

colSet = set(col)

featureNamesSet.append(list(colSet))

#返回 数据集,属性名,所有属性的取值集合,以及标签列表

return dataSet, featureNames, featureNamesSet,labelList

def tree_predict(tree, data):

#print(data)

feature = list(tree.keys())[0]    #取树第一个结点的键(特征)

#print(feature)

label = data[feature]             #该特征下的属性

next_tree = tree[feature][label]  #取下一个结点树

if type(next_tree) == str:        #如果是个字符串,说明已经到达叶节点返回分类结果

return next_tree

else:                             # 否则继续如上处理

return tree_predict(next_tree, data)

def main():

#获取训练集,所有属性名称,每个属性的类别,所有标签

dataTrain, featureNames, featureNamesSet,labelList = readDataSet("data/ex3data.csv")

print("dataTrain: \n",dataTrain,"featureNames:\n",featureNames,"featureNamesSet:\n",featureNamesSet,"labelList:\n",labelList)

#获取测试集

train= pd.read_csv("data/ex3data.csv")

test = pd.read_csv("data/ex3data.csv")

print("train:\n",train[:10])

print("test:\n",test[:10])

#生成决策树

t0 = time.time()

tree=createFullDecisionTree(dataTrain, featureNames,featureNamesSet,labelList)

t1 = time.time()

print("C4.5算法生成决策树的时间开销:",(t1 - t0)*(10**6),"us")

createPlot(tree,"fig/C45.png")

predictTrain = train.apply(lambda x: tree_predict(tree, x), axis=1)

label_list = train.iloc[:, -1]

score = accuracy_score(label_list, predictTrain)

print('训练补全分支准确率为:' + repr(score * 100) + '%')

#预测

y_predict = test.apply(lambda x: tree_predict(tree, x), axis=1)

label_list = test.iloc[:, -1]

score = accuracy_score(label_list, y_predict)

print('测试集补全分支准确率为:' + repr(score * 100) + '%')

if __name__ == "__main__":

main()

决策树是一种类似流程图的树结构,其中每个内部节点(非树叶节点)表示在一个属性上的测试,

每个分枝代表一个测试输出,而每个树叶节点存放一个类标号。

一旦建立好决策树,对于一个未给定类标号的元组,跟踪一条有根节点到叶节点的路径,该叶节点就存放着该元组的预测。

1.9 运行结果及分析

如上图显示dataTrain数据及我们训练的数据train

上图显示我们测试的数据及C4.5算法生成决策树的时间开销和训练不全分支准确率、测试集补全分支准确率

上图为程序运行结果图,我们可以根据是否周末、天气、是否有促销等特征判断销量的高低。

决策树算法(C4.5算法)相关推荐

  1. 【机器学习入门】(4) 决策树算法理论:算法原理、信息熵、信息增益、预剪枝、后剪枝、算法选择

    各位同学好,今天我向大家介绍一下python机器学习中的决策树算法的基本原理.内容主要有: (1) 概念理解:(2) 信息熵:(3) 信息增益:(4) 算法选择:(5) 预剪枝和后剪枝. python ...

  2. cart算法_ID3、C4.5、CART决策树算法

    本文主要介绍的主要内容如下: 概念 ID3 决策树算法 C4.5 决策树算法 CART 决策树算法 1. 概念 1.1 信息熵 信息熵(Entropy),随机变量的不确定性,也称为"系统混乱 ...

  3. 决策树C4.5算法 c语言实现,数据挖掘十大经典算法(1) C4.5_决策树算法

    数据挖掘十大经典算法(1) C4.5_决策树算法 机器学习中,决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每 ...

  4. 最常用的决策树算法(二)Random Forest、Adaboost、GBDT 算法

    决策树是一个非常常见并且优秀的机器学习算法,它易于理解.可解释性强,其可作为分类算法,也可用于回归模型.本文将分三篇介绍决策树,第一篇介绍基本树(包括 ID3.C4.5.CART),第二篇介绍 Ran ...

  5. 机器学习算法:决策树算法

    1.基本定义   决策树(Decision Tree)是一种基本的分类和回归算法.该算法模型呈树形结构,主要由结点和有向边组成.结点又分为两种类型:内部结点和叶子结点.内部结点表示在一个属性或特征上的 ...

  6. 机器学习算法(3)之决策树算法

    前言:首先,在了解树模型之前,自然想到树模型和线性模型有什么区别呢?其中最重要的是,树形模型是一个一个特征进行处理,之前线性模型是所有特征给予权重相加得到一个新的值.决策树与逻辑回归的分类区别也在于此 ...

  7. 浅谈决策树算法以及matlab实现ID3算法

    决策树方法在分类.预测.规则提取等领域有着广泛的应用.在20世纪70年代后期和80年代初期,机器学习研究者J.Ross Quinilan提出了ID3算法以后,决策树在机器学习.数据挖掘领域得到极大的发 ...

  8. 机器学习:决策树算法(ID3算法)的理解与实现

    机器学习:决策树算法(ID3算法)的理解与实现 文章目录 机器学习:决策树算法(ID3算法)的理解与实现 1.对决策树算法的理解 1.概述 2.算法难点 选择最优划分属性 1.信息熵 2.信息增益 2 ...

  9. 最常用的决策树算法!Random Forest、Adaboost、GBDT 算法

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 本文主要介绍基于集成学习的决策树,其主要通过不同学习框架生产基学习器,并综合所有基学习 ...

最新文章

  1. 山有木兮木有枝,心悦君兮君不知
  2. 1014. Best Sightseeing Pair
  3. CF--思维练习--CodeForces - 219C Color Stripe (思维)
  4. python的序列包括字符串列表和什么_Python基础:03序列:字符串、列表和元组
  5. (18)FPGA面试技能提升篇(CACHE、MMU、DMA)
  6. db2 快速清除表中所以的数据
  7. JAVA实现ATM源代码及感想
  8. 又一款主流勒索软件 Paradise 的源代码遭泄露
  9. android安全权限管理,Android 11 中的权限更新
  10. 博文视点读书节第十日丨大咖书单最终章技术分享双倍放送!
  11. bootdo mysql_iBootDo: 基于BootDo项目定制版,兼容MySQL、Oracle
  12. 金蝶K3 Cloud免密登陆
  13. Web Polygraph 安装
  14. PHP上传文件大小限制大全
  15. 解决Vue.directives is not a function报错
  16. Linux下安装Oracle 11g详细过程
  17. 内测“今视频”APP入局长视频,快手有钱之后“飘了”?
  18. 批量-跑批存在的意义
  19. ARMv8-M相比ARMv7-M架构优势在哪里?
  20. OpenWrt开发必备软件模块——无线技术与PPPoE

热门文章

  1. 六年级计算机考试实验操作,小学科学实验操作考试试题(六年级)
  2. 计算机网络知识点总结-第一章:概述
  3. SAP会计凭证相关表
  4. Xsens-MTI 670 ROS驱动安装及使用
  5. oracle数据库增加很快,scn增加很快,主要是什么原因?
  6. 起重机横跨梁结构ANSYS有限元分析
  7. 还不会使用Mysql中的 limit 吗?limit 用法详解看了就会了
  8. android togglebutton多次点击,Android ToggleButton使用笔记
  9. 亚洲运动会简称亚运会,2022年的第19届在中国杭州举办,迎接亚运做一个线上健步走小程序活动,ElementById(“yayun“).innerHTML = “你好 亚运“;
  10. 2023十大连锁店进销存软件排名(真实测评)