解答:
每个标记不同的数据特征向量都不相同,即树的每一条枝干(从根节点到叶子结点)就代表一种向量,这样的话决策树与训练集就是一致的了。


解答:
题目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 基本算法 1.2 信息熵 1.3 信息增益 2.ID3决策树 3.C4.5决策树 4.CART决策树 5.剪枝操作 6.连续与缺失值处理 7.多变量决策树 ...

  2. 随机过程及其在金融领域中的应用 第四章 习题 及 答案

    随机过程及其在金融领域中的应用 第四章 习题 及 答案 本文地址: http://blog.csdn.net/caroline_wendy/article/details/17021909 第1题: ...

  3. 周志华-机器学习西瓜书-第三章习题3.3 编程实现对率回归

    本文为周志华机器学习西瓜书第三章课后习题3.3答案,编程实现对率回归,数据集为书本第89页的数据 使用tensorflow实现过程 # coding=utf-8 import tensorflow a ...

  4. 西瓜书第六章笔记及答案——支持向量机

    目录 第6章 支持向量机 6.1间隔与支持向量 6.2对偶问题 6.3核函数 6.4软间隔与正则化 6.5支持向量回归 6.6核方法 习题 6.1试证明样本空间中任意点 x x x到超平面 ( w , ...

  5. 西瓜书第五章笔记及答案——神经网络

    目录 第5章 神经网络 5.1 神经元模型 5.2感知机和多层网络 5.3误差逆传播算法 5.4全局最小和局部极小 5.5其他常见神经网络 5.5.1RBF网络 5.5.2ART网络 5.5.3SOM ...

  6. 2008秋-计算机软件基础-第四章习题参考答案 P131 ,习题6之一

    Author: Eman Lee  P131,第6题之一 参考答案 (1)       直接插入排序 初始状态 [53] [87  12  61  70  68  27  65  21  35 ] 第 ...

  7. mysql数据库原理与应用武洪萍第三张答案_mysql数据库武洪萍版第四章习题与答案...

    一.选择题 1. 下面哪种数字数据类型不可以存储数据 256 ?( D ) A. bigint      B.  int       C.  Smallint       D.  tinyint 2. ...

  8. mysql数据库武洪萍版答案_mysql数据库武洪萍版第四章习题与答案

    一.选择题 1.下面哪种数字数据类型不可以存储数据256?(D) A. bigint B. int C. Smallint D. tinyint 2.下面是有关主键和外键之间的关系描述,正确的是(AC ...

  9. 《机器学习》西瓜书第四章 神经网络(南瓜书辅助)

    5.1 M-P神经元 M‑P神经元(一个用来模拟生物行为的数学模型):接收n个输入(通常是来自其他神经元),并给各个输入赋予权重计算加权和,然后和自身特有的阈值 进行比较(作减法),最后经过激活函数( ...

  10. 微型计算机原理答案第四章,微机原理第四章习题答案.doc

    微机原理第四章习题答案 1.8086语言指令的寻址方式有哪几类?用哪一种寻址方式的指令执行速度最快? 答:数据操作数的寻址方式有七种,分别为:立即寻址,寄存器寻址,直接寻址,寄存器间接寻址,寄存器相对 ...

最新文章

  1. UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP
  2. 书评 | 圈内大佬怎么看编程日历
  3. Spring Boot 到底是怎么做到自动配置的?
  4. 1037C. Equalize
  5. 【课程】MIT深度学习课程:架起理论与实践的桥梁
  6. android 自定义加载动画效果,Android 自定义View修炼-自定义加载进度动画LoadingImageView...
  7. dbf转成excel_DBF文件转换成excel工具(DbfToExcel)
  8. 算法图解第九章笔记与习题(动态规划)
  9. 封玩家IP和机器码以及解开被封的教程
  10. 计算机控制系统编程语言有哪些,PLC编程语言有哪些种类
  11. 三角函数和差公式的推导
  12. 蘑菇租房爆雷,房东围堵总部,CEO凌晨发公告
  13. 转载-计算机基础教程之屏蔽软件联网
  14. 安信可经验分享 | WiFi保持连接状态下低功耗的实现,适用于ESP32/ESP32C3/ESP32S3系列模组二次开发
  15. 二进制除法原理——两种简便方法
  16. Jikes 研究虚拟机(RVM)一 设计和实现问题
  17. 经管文本分析 | 基于年报文本构建管理层讨论与分析披露的信息含量
  18. 惠普z系列服务器,惠普Z8/Z6/Z4 G4新款工作站/服务器主机:Quadro P6000 48TB存储
  19. CVE-2021-1647:Microsoft Defender远程代码执行漏洞通告
  20. Ubuntu20.4系统下安装kvm并创建虚拟机

热门文章

  1. 2014年总结和2015年的规划
  2. java定义矩形的周长和面积_定义一个长方形类,定义 求周长和面积的方法实例
  3. 【Hadoop实训】统计文件中所有单词的平均长度
  4. 实验吧_网站综合渗透_Discuz!
  5. Android9 更改系统默认输入法
  6. nginx—动静分离
  7. 用了python之后笔记本卡了_干货!如何用Python在笔记本电脑上分析100GB数据(上)...
  8. 2020-12-28 微信支付二面
  9. HTML判断夏令时,美国夏令时,要记得拨钟表哦Daylight Saving Time
  10. 激光振镜误差校正算法C语言,一种基于双线性插值法的激光振镜图形校正算法的制作方法...