目录

  • 实验内容
    • 实验目的
    • 实验内容
  • Python代码
    • 实验代码
    • 绘制决策树代码
    • 运行结果
  • 参考

实验内容

实验目的

  1. 掌握信息熵与信息增益相关概念
  2. 掌握构建决策树⽅法(ID3)
  3. 掌握极⼤似然法选择节点

实验内容

  1. 编写loadDataSet() splitDataSet() 加载处理数据集
  2. 编写calcShannonEnt()计算信息熵
  3. 编写chooseBestFeatureToSplit() 计算信息增益,并返回最⼤特征
  4. 编写majorityCnt()统计classList中出现次数最多的元素(类标签)
  5. 编写createTree()实现ID3算法创建决策树
  6. 编写classify()实现分类预测
  7. 附加题了解并使⽤sklearn构建决策树、并完成可视化

Python代码

实验代码

from math import log
import operator
import pandas as pd
import csv
from  决策树 import treePlotter
#计算信息熵
def calcShannonEnt(dataSet):"""函数说明:计算给定数据集的信息熵(香农熵)Parameters:dataSet:数据集Returns:shannonEnt:信息熵"""numEntries = len(dataSet)       #样本数lable_Counts={}                 #该数据集每个类别的频数for featVec in dataSet:         #对每一行样本current_Lable = featVec[-1] #该样本的标签if current_Lable not in lable_Counts.keys():#如果标签没有放入统计次数的字典,添加进去lable_Counts[current_Lable] = 0lable_Counts[current_Lable] += 1shannonEnt = 0.0for key in lable_Counts:prob = float(lable_Counts[key])/numEntriesshannonEnt -= prob * log(prob, 2)return shannonEnt                                #返回信息熵#加载数据集
def loadDataSet():"""函数说明:加载数据集Parameters:无Returns:dataSet:数据集labels:分类属性"""#数据集file = pd.read_csv('loans.csv')dataSet = file.values.tolist()labels = ['grade', 'sub_grade', 'short_emp', 'emp_length_num', 'home_ownership', 'dti', 'purpose', 'term','last_delinq_none', 'last_major_derog_none', 'revol_util', 'total_rec_late_fee', 'safeloans']#分类属性#返回数据集和分类属性return dataSet, labels#按给定特征划分数据集
def splitDataSet(dataSet,axis,value):"""函数说明:按照给定特征划分数据集Parameters:dataSet:待划分的数据集axis:划分数据集的特征value:需要返回的特征值Returns:无"""#创建返回的数据集列表retDataSet=[]#遍历数据集for feat_vec in dataSet:if feat_vec[axis] == value:# 这两个语句最终结果就是去掉了列表中的axis特征# 把要选取的那个特征单独拎出来reduced_feat_vec = feat_vec[:axis]reduced_feat_vec.extend(feat_vec[axis+1:])# extend是去列表框然后添加,append是整个添加retDataSet.append(reduced_feat_vec)return retDataSetdef chooseBestFeatureToSplit(dataSet):"""函数说明:计算给定数据集的信息熵(香农熵)Parameters:dataSet:数据集Returns:shannonEnt:信息增益最大特征的索引值"""#特征数量numFeatures = len(dataSet[0]) - 1# 计数数据集的香农熵baseEntropy = calcShannonEnt(dataSet)   #调用calcShannonEnt()#信息增益bestInfoGain = 0.0#最优特征的索引值bestFeature = 1#遍历所有特征for i in range(numFeatures):#获取dataSet的第i个所有特征featlist = [example[i] for example in dataSet]#创建set集合{},元素不可重复uniqueVals = set(featlist)#经验条件熵newEntropy = 0.0#计算信息增益for value in uniqueVals:# subDataSet划分后的子集subDataSet = splitDataSet(dataSet, i, value) #调用splitDataSet()#计算子集的概率prob = len(subDataSet) / float(len(dataSet)) # 极大似然估计概率#根据公式计算经验条件熵newEntropy += prob * calcShannonEnt(subDataSet) #调用calcShannonEnt()#信息增益InfoGain = baseEntropy - newEntropy#打印每个特征的信息增益print("第%d个特征的信息增益为%.3f" % (i, InfoGain))#寻找信息增益的最大索引值if(InfoGain > bestInfoGain):#更新信息增益,找到最大信息增益bestInfoGain = InfoGain#记录信息增益最大的特征索引值bestFeature = i# 返回信息增益最大特征的索引值return bestFeaturedef majorityCnt(classList):"""函数说明:统计classList中出现次数最多的元素(类标签)Parameters:classList:类标签列表Returns:sortedClassCount[0][0]:出现次数最多的元素(类标签)"""classCount={}#统计classList中每个元素出现的次数for vote in classList:if vote not in classCount.keys(): classCount[vote] = 0classCount[vote] += 1# 根据字典的值降序排序sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]def createTree(dataSet, labels, featLabels):"""函数说明:创建决策树Parameters:dataSet:训练数据集labels:分类属性标签featLabels:存储选择的最优特征标签Returns:myTree:决策树"""#取分类标签(是否放贷:yes or no)classlist = [example[-1] for example in dataSet]#如果类别完全相同,则停止继续划分if classlist.count(classlist[0]) == len(classlist):return classlist[0]#遍历完所有特征时返回出现次数最多的类标签if len(dataSet[0]) == 1:return majorityCnt(classlist) #调用majorityCnt()#选择最优特征bestFeat = chooseBestFeatureToSplit(dataSet)  #调用choochooseBestFeatureToSplit()#最优特征的标签bestFeatLabel = labels[bestFeat]featLabels.append(bestFeatLabel)#根据最优特征的标签生成树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, featLabels)return myTreedef classify(inputTree, featLabels, testVec):"""函数说明:使用决策树分类提示:递归决策Parameters:inputTree - 已经生成的决策树featLabels - 存储选择的最优特征标签testVec - 测试数据列表,顺序对应最优特征标签Returns:classLabel - 分类结果"""classLabel = 'None'firstStr = next(iter(inputTree))    #获取决策树结点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 classLabeldef classifyAll(inputTree, featLabels, testDataSet):"""输入:决策树,分类标签,测试数据集输出:决策结果描述:跑决策树"""classLabelAll = []for testVec in testDataSet:classLabelAll.append(classify(inputTree, featLabels, testVec))return classLabelAlldef loadTestData():"""函数说明:加载测试数据集Parameters:无Returns:dataSet:测试数据集labels:分类属性"""file = pd.read_csv('test.csv')dataSet = file.values.tolist()test_label = ['grade', 'short_emp', 'dti']# 分类属性# 返回数据集和分类属性return dataSet, test_labeldef save_result(result):"""函数说明:存储决策结果到result.csv@param result:@return: 无"""file = open("result.csv",'w',newline='')csv_write = csv.writer(file)csv_write.writerow(['result'])for i in range(len(result)):csv_write.writerow([result[i]])file.close()if __name__=='__main__':dataSet, labels = loadDataSet()labels_tmp = labels[:]featLabels = []myTree = createTree(dataSet, labels_tmp, featLabels)print(myTree, end='\n')# 测试数据testSet, test_label = loadTestData()result = classifyAll(myTree, test_label, testSet)print(result, end='\n')print("result长度为:%d" % len(result), end='\n')print("存储预测结果中...")save_result(result)treePlotter.createPlot(myTree)

绘制决策树代码

import matplotlib.pyplot as plt#解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = FalsedecisionNode = dict(boxstyle="sawtooth", fc="0.8")
leafNode = dict(boxstyle="round4", fc="0.8")
arrow_args = dict(arrowstyle='<-')# 绘制结点
def plotNode(nodeTxt,centerPt,parentPt,nodeType):# annotate是关于一个数据点的文本# nodeTxt为要显示的文本,centerPt为文本的中心点,箭头所在的点,parentPt为指向文本的点createPlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords='axes fraction', xytext=centerPt, textcoords='axes fraction',\va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)# 创建绘图
def createPlot():# 类似于Matlab的figure,定义一个画布(暂且这么称呼吧),背景为白色fig = plt.figure(1,facecolor='white')# 把画布清空fig.clf()# createPlot.ax1为全局变量,绘制图像的句柄,subplot为定义了一个绘图,111表示figure中的图有1行1列,即1个,最后的1代表第一个图# frameon表示是否绘制坐标轴矩形createPlot.ax1 = plt.subplot(111,frameon=False)# 绘制结点,(0.1,0.5)指向(0.5,0.1)plotNode('a decision node',(0.5,0.1),(0.1,0.5),decisionNode)# 绘制结点plotNode('a leaf node',(0.8,0.1),(0.3,0.8),leafNode)plt.show()def getNumLeafs(myTree):numLeafs = 0 #numLeafs: 0firstStr = list(myTree.keys())[0] #firstStr: 'no surfacing'secondDict = myTree[firstStr]#secondDict: <class 'dict'>: {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}#第一次循环 key=0for key in secondDict.keys():if type(secondDict[key]).__name__ == 'dict':#0不是决策树结点,是叶子节点,不执行numLeafs += getNumLeafs(secondDict[key])else:#0是叶子节点numLeafs += 1return numLeafs# 获得决策树的深度
def getTreeDepth(myTree):# 定义树的深度maxDepth = 0# 获得myTree的第一个键值,即第一个特征,分割的标签firstStr = list(myTree.keys())[0]# 根据键值得到对应的值,即根据第一个特征分类的结果secondDict = myTree[firstStr]for key in secondDict.keys():# 如果secondDict[key]为一个字典if type(secondDict[key]).__name__ == 'dict':# 则当前树的深度等于1加上secondDict的深度,只有当前点为决策树点深度才会加1thisDepth = 1 + getTreeDepth(secondDict[key])# 如果secondDict[key]为叶子结点else:# 则将当前树的深度设为1thisDepth = 1# 如果当前树的深度比最大数的深度if thisDepth > maxDepth:maxDepth = thisDepth# 返回树的深度return maxDepth# 绘制中间文本
def plotMidText(cntrPt,parentPt,txtString):# 求中间点的横坐标xMid = (parentPt[0] - cntrPt[0])/2.0 + cntrPt[0]# 求中间点的纵坐标yMid = (parentPt[1] - cntrPt[1])/2.0 + cntrPt[1]# 绘制树结点createPlot.ax1.text(xMid,yMid,txtString)# 绘制决策树
def plotTree(myTree,parentPt,nodeTxt):# 定义并获得决策树的叶子结点数numLeafs = getNumLeafs(myTree)#depth =getTreeDepth(myTree)# 得到第一个特征firstStr = list(myTree.keys())[0]# 计算坐标,x坐标为当前树的叶子结点数目除以整个树的叶子结点数再除以2,y为起点cntrPt = (plotTree.xOff + (1.0 +float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)# 绘制中间结点,即决策树结点,也是当前树的根结点,这句话没感觉出有用来,注释掉照样建立决策树,理解浅陋了,理解错了这句话的意思,下面有说明plotMidText(cntrPt, parentPt, nodeTxt)# 绘制决策树结点plotNode(firstStr, cntrPt, parentPt, decisionNode)# 根据firstStr找到对应的值secondDict = myTree[firstStr]# 因为进入了下一层,所以y的坐标要变 ,图像坐标是从左上角为原点plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD# 遍历secondDictfor key in secondDict.keys():# 如果secondDict[key]为一棵子决策树,即字典if type(secondDict[key]).__name__ == 'dict':# 递归的绘制决策树plotTree(secondDict[key], cntrPt, str(key))# 若secondDict[key]为叶子结点else:# 计算叶子结点的横坐标plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW# 绘制叶子结点plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)# 这句注释掉也不影响决策树的绘制,自己理解的浅陋了,这行代码是特征的值plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))# 计算纵坐标plotTree.yOff = plotTree.yOff +1.0/plotTree.totalDdef createPlot(inTree):# 定义一块画布(画布是自己的理解)fig = plt.figure(1, facecolor='white')# 清空画布fig.clf()# 定义横纵坐标轴,无内容axprops = dict(xticks=[], yticks=[])# 绘制图像,无边框,无坐标轴createPlot.ax1 = plt.subplot(111, frameon=True, **axprops)# plotTree.totalW保存的是树的宽plotTree.totalW = float(getNumLeafs(inTree))# plotTree.totalD保存的是树的高plotTree.totalD = float(getTreeDepth(inTree))# 决策树起始横坐标plotTree.xOff = - 0.5 / plotTree.totalW #从0开始会偏右# 决策树的起始纵坐标plotTree.yOff = 1.0# 绘制决策树plotTree(inTree, (0.5, 1.0), '')# 显示图像plt.show()

运行结果



实验数据私信发QQ邮箱,主要是不会传数据到CSDN

参考

Python编程实验一 决策树实现结果预测
决策树(ID3算法)
python实现ID3决策树算法
机器学习实战之决策树算法笔记
ID3决策树原理分析及python实现
python实现ID3决策树分类算法
Python3《机器学习实战》学习笔记(三):决策树实战篇之为自己配个隐形眼镜

Python 决策树分类任务相关推荐

  1. python决策树分类鸢尾花_基于决策树—鸢尾花分类

    决策树算法广泛应用于:语音识别.医疗诊断.客户关系管理.模式识别.专家系统等,在实际工作中,必须根据数据类型的特点及数据集的大小,选择合适的算法. 本文选择经典案例--<鸢尾花分类> 一. ...

  2. python决策树分类案例_银行产品销售案例与决策树分类算法

    案例数据集来源于UCI网站.案例是基于一家葡萄牙金融机构的电话销售数据.营销目标是确认客户是否愿意认购银行发行的一款定期储蓄产品.该数据集内包含41188条记录和20个特征变量,和1个分类变量.变量包 ...

  3. python决策树分类案例_python实现决策树分类算法

    本文实例为大家分享了python实现决策树分类算法的具体代码,供大家参考,具体内容如下 1.概述 决策树(decision tree)--是一种被广泛使用的分类算法. 相比贝叶斯算法,决策树的优势在于 ...

  4. Python 决策树分类算法分析与实现

    决策树分类算法分析与实现 决策树分类算法是最为常见的一种分类算法,通过属性划分来建立一棵决策树,测试对象通过在树上由顶向下搜索确定所属的分类.决策树的构建主要需要解决两个问题: (1)树的每次成长,选 ...

  5. Python——决策树分类模型剪枝

    目录 1 决策树模型数据分类 2 决策树剪枝缓解过拟合问题 常见的决策树算法有ID3.C4.5和CART算法.ID3算法,是由澳大利亚计算机科学家Quinlan在1986年提出的,它是经典的决策树算法 ...

  6. python决策树分类 导入数据集_BPNN、决策树、KNN、SVM分类鸢尾花数据集Python实现...

    数据集处理 数据获取 使用sklearn的dataset获取数据 from sklearn import datasets from sklearn.model_selection import tr ...

  7. python决策树分类预测_数据分类预测之python决策树

    决策树是一种树状结构,它的每一个叶节点对应着一个分类,非叶节点对应着在某个属性上的划分,根据样本在该属性上的不同取值将其划分成若干个子集.对于非纯的叶节点,多数类的标号给出到达这个节点的样本所属的类. ...

  8. python决策树分类 导入数据集_python+sklearn实现决策树(分类树)

    整理今天的代码-- 采用的是150条鸢尾花的数据集fishiris.csv # 读入数据,把Name列取出来作为标签(groundtruth) import pandas as pd data = p ...

  9. python决策树怎么选择_【机器学习+python(8)】分类决策树的介绍与实现

    之前我们介绍过用逻辑回归根据鸢尾花萼片.花瓣的长度和宽度进行鸢尾花类别的判定:也通过朴素贝叶斯模型分享了如何根据男生专业和身高两大属性,判断其是否有女朋友.而本期我们将介绍另外一种有监督的机器学习分类 ...

最新文章

  1. VC连接SQL server2005
  2. Docker的4种网络模式
  3. 无法使用UI configuration的trouble shooting
  4. idea tomcat部署web项目_项目开发之部署帆软到Tomcat服务一
  5. java jdbc 操作_Java:JDBC操作
  6. 【强化学习】MOVE37-Introduction(导论)/马尔科夫链/马尔科夫决策过程
  7. J2EE (十) Java中多种方式实现单例模式
  8. html页面点击生成图片并可以下载图片
  9. 掌握一门计算机语言需要多长时间,学习一门语言需要多长时间?科学告诉你
  10. Sklearn聚类算法之Affinity Propagation
  11. 将java封装的实体类数据生成excel供下载
  12. NLP-知识搭建聊天系统详细教程
  13. ORACLE获取当天所在月份的所有日期和周几(每月类似台历显示)
  14. 955/965公司名单
  15. python教程40-财务自动生成财务报表
  16. selenium实现自动播放音乐
  17. 专家纵论谈大数据:认清本质 挖掘真价值
  18. 金属表面酸洗废水除锰除铬过滤装置,除铬树脂
  19. 墨客科普---MOAC分层分片技术
  20. 前后端分离 MVC 架构与 Java 接口规范,深入剖析必要性!

热门文章

  1. 《Python数据分析与挖掘实战》第7章——航空公司客户价值分析(kmeans)
  2. partial 函数之参数传入
  3. 520 | ChatGPT会是一个完美情人吗?
  4. 关于虚拟磁带库(转自51cto)
  5. linux ssl 双向认证 脚本,Linux配置Tomcat 实现双向SSL认证
  6. nfs-ganesha使用
  7. 使用Kali-linux快速 搭建vulfocus靶场
  8. Flutter自定义加载中的Loading
  9. 国际城市解决交通系统运行问题的经验及启示
  10. ASP.NET Web窗体(.NETFromWork应用程序) ADO.NET 实体数据模型 关于多表联查显示的实现