西瓜书第四章习题及答案
解答:
每个标记不同的数据特征向量都不相同,即树的每一条枝干(从根节点到叶子结点)就代表一种向量,这样的话决策树与训练集就是一致的了。
解答:
题目4.1中介绍了如果数据不含有冲突数据,那么就会产生绝对的过拟合现象,这也符合最小训练误差的准则,因此使用‘最小训练误差‘作为决策树划分选择准则的会产生在训练集上效果很好,而测试集上效果差的情况,即出现了过拟合现象。
分析:
表4.3属性数据值,有离散的有连续的,而基于信息熵进行属性划分只能是离散属性值,如果使用表4.3的数据集则需要对连续属性进行离散化-对应知识点-机器学习4.4连续与缺失值。
本实验采用去除表4.3中连续值的数据集西瓜数据集2.0。
解答:
第一部分-说在前面:
将数据集进行预处理(手动的 呜呜~ 要哭了!)
将离散的属性值进行数字化,将属性用英文代替青绿-0 乌黑-1 浅白-2;蜷缩 -0 稍蜷-1 硬挺-2浊响-0 沉闷-1 清脆-2清晰-0 稍糊-1 模糊-2凹陷-0 稍凹-1 平坦-2硬滑-0 软粘-1是-1 否 -0#texture 纹理 umbilical region---脐部labels = ['color', 'root', 'Knock sound', 'texture','umbilical region','touch']
第二部分-计算机数据集的信息熵:
def calcShannonEnt(dataSet):numEntries = len(dataSet)labelCounts = {}for featVec in dataSet: #the the number of unique elements and their occurancecurrentLabel = featVec[-1]if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1shannonEnt = 0.0for key in labelCounts:prob = float(labelCounts[key])/numEntriesshannonEnt -= prob * log(prob,2) #log base 2return shannonEnt
第三部分-划分数据集
创建数据集函数:
from math import log
import operator
def createDataSet():dataSet = [[0, 0, 0, 0, 0, 0, 'yes'], [1, 0, 1, 0, 0, 0, 'yes'], [1, 0, 0, 0, 0, 0, 'yes'],[0, 0, 1, 0, 0, 0, 'yes'],[2, 0, 0, 0, 0, 0, 'yes'], [0, 1, 0, 0, 1, 1, 'yes'],[1, 1, 0, 1, 1, 1, 'yes'],[1, 1, 0, 0, 1, 0, 'yes'], [1, 1, 1, 1, 1, 0, 'no'], [0, 2, 2, 0, 2, 1, 'no'], [2, 2, 2, 2, 2, 0, 'no'], [2, 0, 0, 2, 2, 1, 'no'], [0, 1, 0, 1, 0, 0, 'no'], [2, 1, 1, 1, 0, 0, 'no'], [1, 1, 0, 0, 1, 1, 'no'], [2, 0, 0, 2, 2, 0, 'no'],[0, 0, 1, 1, 1, 0, 'no']]labels = ['color', 'root', 'Knock sound', 'texture','umbilical region','touch'] #change to discrete valuesreturn dataSet, labels
按照给定特征划分数据集:
def splitDataSet(dataSet, axis, value):retDataSet = []for featVec in dataSet:if featVec[axis] == value:reducedFeatVec = featVec[:axis] #chop out axis used for splittingreducedFeatVec.extend(featVec[axis+1:])retDataSet.append(reducedFeatVec)return retDataSet
选择最好的数据集划分方式:
def chooseBestFeatureToSplit(dataSet):numFeatures = len(dataSet[0]) - 1 #the last column is used for the labelsbaseEntropy = calcShannonEnt(dataSet)bestInfoGain = 0.0; bestFeature = -1for i in range(numFeatures): #iterate over all the featuresfeatList = [example[i] for example in dataSet]#create a list of all the examples of this featureuniqueVals = set(featList) #get a set of unique valuesnewEntropy = 0.0for value in uniqueVals:subDataSet = splitDataSet(dataSet, i, value)prob = len(subDataSet)/float(len(dataSet))newEntropy += prob * calcShannonEnt(subDataSet) infoGain = baseEntropy - newEntropy #calculate the info gain; ie reduction in entropyif (infoGain > bestInfoGain): #compare this to the best gain so farbestInfoGain = infoGain #if better than current best, set to bestbestFeature = ireturn bestFeature
第四部分-递归构建决策树
创建树的函数代码:
def createTree(dataSet,labels):classList = [example[-1] for example in dataSet]if classList.count(classList[0]) == len(classList): return classList[0]#stop splitting when all of the classes are equalif len(dataSet[0]) == 1: #stop splitting when there are no more features in dataSetreturn majorityCnt(classList)bestFeat = chooseBestFeatureToSplit(dataSet)bestFeatLabel = labels[bestFeat]myTree = {bestFeatLabel:{}}del(labels[bestFeat])featValues = [example[bestFeat] for example in dataSet]uniqueVals = set(featValues)for value in uniqueVals:subLabels = labels[:] #copy all of labels, so trees don't mess up existing labelsmyTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)return myTree
将结果输出展示:
myDat, labels = createDataSet()
print(myDat)
print(labels)
运行结果如下所示:
Ent1 = calcShannonEnt(myDat)
print(Ent1)bestFeature = chooseBestFeatureToSplit(myDat)
print('最好的划分属性的下标为:{}'.format(bestFeature))
运行结果如下所示:
myTree = createTree(myDat, labels)
myTree
运行结果如下所示:
第五部分-使用matplotlib注解绘制树形图
使用文本注解绘制节点:
import matplotlib.pyplot as plt#定义文本框和箭头的形式
decisionNode = dict(boxstyle = 'sawtooth', fc = '0.8')
leafNode = dict(boxstyle = 'round4', fc = '0.8')
arrow_args = dict(arrowstyle = '<-')def plotNode(nodeTxt, centerPt, parentPt, nodeType):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():fig = plt.figure(1, facecolor='white')fig.clf()createPlot.ax1 = plt.subplot(111, frameon=False) #ticks for demo puropses 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()
createPlot()#运行结果如下所示
获取叶节点的数目:
def getNumLeafs(myTree):numLeafs = 0firstStr = list(myTree.keys())[0]secondDict = myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodesnumLeafs += getNumLeafs(secondDict[key])else: numLeafs +=1return numLeafs
获取树的层数:
#获取树的层数
def getTreeDepth(myTree):maxDepth = 0firstStr = list(myTree.keys())[0]secondDict = myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodesthisDepth = 1 + getTreeDepth(secondDict[key])else: thisDepth = 1if thisDepth > maxDepth: maxDepth = thisDepthreturn maxDepth
创建retrieveTree函数输出预先存储的树信息,避免每次测试代码时都要从数据中创建树的麻烦。(就是保结果复制过来保存一下)
def retrieveTree(i):listOfTrees =[{'texture': {0: {'root': {0: 'yes',1: {'color': {0: 'yes', 1: {'touch': {0: 'yes', 1: 'no'}}}},2: 'no'}},1: {'touch': {0: 'no', 1: 'yes'}},2: 'no'}},{'texture': {0: {'root': {0: 'yes',1: {'color': {0: 'yes', 1: {'touch': {0: 'yes', 1: 'no'}}}},2: 'no'}},1: {'touch': {0: 'no', 1: 'yes'}},2: 'no'}}]return listOfTrees[i]
运行上述代码并查看结果:
myTree = retrieveTree(0)
print(myTree)print(myTree.keys())
print(list(myTree.keys())[0])print('树叶节点的数目为:{}'.format(getNumLeafs(myTree)))
print('树的深度为:{}'.format(getTreeDepth(myTree)))
结果如下:
plotTree函数-由三个函数构成,从下往上调用函数。
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, va="center", ha="center", rotation=30)def plotTree(myTree, parentPt, nodeTxt):#if the first key tells you what feat was split onnumLeafs = getNumLeafs(myTree) #this determines the x width of this treedepth = getTreeDepth(myTree)firstStr = list(myTree.keys())[0] #the text label for this node should be thiscntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)plotMidText(cntrPt, parentPt, nodeTxt)plotNode(firstStr, cntrPt, parentPt, decisionNode)secondDict = myTree[firstStr]plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalDfor key in secondDict.keys():if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes plotTree(secondDict[key],cntrPt,str(key)) #recursionelse: #it's a leaf node print the leaf nodeplotTree.xOff = plotTree.xOff + 1.0/plotTree.totalWplotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD
#if you do get a dictonary you know it's a tree, and the first element will be another dictdef createPlot(inTree):fig = plt.figure(1, facecolor='white')fig.clf()axprops = dict(xticks=[], yticks=[])createPlot.ax1 = plt.subplot(111, frameon=False, **axprops) #no ticksplotTree.totalW = float(getNumLeafs(inTree))plotTree.totalD = float(getTreeDepth(inTree))plotTree.xOff = -0.5/plotTree.totalW; plotTree.yOff = 1.0;plotTree(inTree, (0.5,1.0), '')###11111111plt.show()
myTree = retrieveTree(0)
createPlot(myTree)
最终运行的结果图:
第六部分-说明
虽然输出的结果丑了点,也确实花费了不少时间(谁让我那么菜呐),所以有写的不好的地方还请各位大佬支出,大家共同进步哈。
今后如果有能力的话,会将最终的决策树美化一下,处理数据的文本样式而不是现在的0 1,再将连续型的属性值也加上去。
第七部分-参考书籍及文章
机器学习-西瓜书
机器学习实战-Peter Harrington
西瓜书第四章习题及答案相关推荐
- 西瓜书第四章阅读笔记
西瓜书第四章阅读笔记 1.基本概念 1.1 基本算法 1.2 信息熵 1.3 信息增益 2.ID3决策树 3.C4.5决策树 4.CART决策树 5.剪枝操作 6.连续与缺失值处理 7.多变量决策树 ...
- 随机过程及其在金融领域中的应用 第四章 习题 及 答案
随机过程及其在金融领域中的应用 第四章 习题 及 答案 本文地址: http://blog.csdn.net/caroline_wendy/article/details/17021909 第1题: ...
- 周志华-机器学习西瓜书-第三章习题3.3 编程实现对率回归
本文为周志华机器学习西瓜书第三章课后习题3.3答案,编程实现对率回归,数据集为书本第89页的数据 使用tensorflow实现过程 # coding=utf-8 import tensorflow a ...
- 西瓜书第六章笔记及答案——支持向量机
目录 第6章 支持向量机 6.1间隔与支持向量 6.2对偶问题 6.3核函数 6.4软间隔与正则化 6.5支持向量回归 6.6核方法 习题 6.1试证明样本空间中任意点 x x x到超平面 ( w , ...
- 西瓜书第五章笔记及答案——神经网络
目录 第5章 神经网络 5.1 神经元模型 5.2感知机和多层网络 5.3误差逆传播算法 5.4全局最小和局部极小 5.5其他常见神经网络 5.5.1RBF网络 5.5.2ART网络 5.5.3SOM ...
- 2008秋-计算机软件基础-第四章习题参考答案 P131 ,习题6之一
Author: Eman Lee P131,第6题之一 参考答案 (1) 直接插入排序 初始状态 [53] [87 12 61 70 68 27 65 21 35 ] 第 ...
- mysql数据库原理与应用武洪萍第三张答案_mysql数据库武洪萍版第四章习题与答案...
一.选择题 1. 下面哪种数字数据类型不可以存储数据 256 ?( D ) A. bigint B. int C. Smallint D. tinyint 2. ...
- mysql数据库武洪萍版答案_mysql数据库武洪萍版第四章习题与答案
一.选择题 1.下面哪种数字数据类型不可以存储数据256?(D) A. bigint B. int C. Smallint D. tinyint 2.下面是有关主键和外键之间的关系描述,正确的是(AC ...
- 《机器学习》西瓜书第四章 神经网络(南瓜书辅助)
5.1 M-P神经元 M‑P神经元(一个用来模拟生物行为的数学模型):接收n个输入(通常是来自其他神经元),并给各个输入赋予权重计算加权和,然后和自身特有的阈值 进行比较(作减法),最后经过激活函数( ...
- 微型计算机原理答案第四章,微机原理第四章习题答案.doc
微机原理第四章习题答案 1.8086语言指令的寻址方式有哪几类?用哪一种寻址方式的指令执行速度最快? 答:数据操作数的寻址方式有七种,分别为:立即寻址,寄存器寻址,直接寻址,寄存器间接寻址,寄存器相对 ...
最新文章
- UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP
- 书评 | 圈内大佬怎么看编程日历
- Spring Boot 到底是怎么做到自动配置的?
- 1037C. Equalize
- 【课程】MIT深度学习课程:架起理论与实践的桥梁
- android 自定义加载动画效果,Android 自定义View修炼-自定义加载进度动画LoadingImageView...
- dbf转成excel_DBF文件转换成excel工具(DbfToExcel)
- 算法图解第九章笔记与习题(动态规划)
- 封玩家IP和机器码以及解开被封的教程
- 计算机控制系统编程语言有哪些,PLC编程语言有哪些种类
- 三角函数和差公式的推导
- 蘑菇租房爆雷,房东围堵总部,CEO凌晨发公告
- 转载-计算机基础教程之屏蔽软件联网
- 安信可经验分享 | WiFi保持连接状态下低功耗的实现,适用于ESP32/ESP32C3/ESP32S3系列模组二次开发
- 二进制除法原理——两种简便方法
- Jikes 研究虚拟机(RVM)一 设计和实现问题
- 经管文本分析 | 基于年报文本构建管理层讨论与分析披露的信息含量
- 惠普z系列服务器,惠普Z8/Z6/Z4 G4新款工作站/服务器主机:Quadro P6000 48TB存储
- CVE-2021-1647:Microsoft Defender远程代码执行漏洞通告
- Ubuntu20.4系统下安装kvm并创建虚拟机
热门文章
- 2014年总结和2015年的规划
- java定义矩形的周长和面积_定义一个长方形类,定义 求周长和面积的方法实例
- 【Hadoop实训】统计文件中所有单词的平均长度
- 实验吧_网站综合渗透_Discuz!
- Android9 更改系统默认输入法
- nginx—动静分离
- 用了python之后笔记本卡了_干货!如何用Python在笔记本电脑上分析100GB数据(上)...
- 2020-12-28 微信支付二面
- HTML判断夏令时,美国夏令时,要记得拨钟表哦Daylight Saving Time
- 激光振镜误差校正算法C语言,一种基于双线性插值法的激光振镜图形校正算法的制作方法...