机器学习实验二---决策树python

2023-11-15


一、了解一下决策树吧

决策树(decision tree)是一类常见的机器学习方法.以二分类任务为例,我们希望从给定训练数据集学得一个模型用以对新示例进行分类,这个把样本分类的任务,可看作对“当前样本属于正类吗?”这个问题的“决策”或“判定”过程.顾名思义,决策树是基于树结构来进行决策的,这恰是人类在面临决策问题时一种很自然的处理机制.

决策树基本流程

一般的,一棵决策树包含一个根结点、若干个内部结点和若干个叶结点;叶结点对应于决策结果,其他每个结点则对应于一个属性测试;每个结点包含的样本集合根据属性测试的结果被划分到子结点中;根结点包含样本全集.从根结点到每个叶结点的路径对应了一个判定测试序列.决策树学习的目的是为了产生一棵泛化能力强,即处理未见示例能力强的决策树,其基本流程遵循简单且直观的“分而治之”(divide-and-conquer)策略,如图:
在这里插入图片描述

信息增益

划分数据集的大原则是:将无需的数据变得更加有序;
“信息嫡”(information entropy)是度量样本集合纯度最常用的一种指标.假定当前样本集合D中第k类样本所占的比例为pk (k = 1,2,…,|y|),则D的信息嫡定义为
在这里插入图片描述

Ent(D)的值越小,则D的纯度越高.值越高信息越混乱。

假定离散属性a有V个可能的取值{a1 , a2,… . ,aV},若使用a来对样本集D进行划分,则会产生V个分支结点,其中第v个分支结点包含了D中所有在属性a上取值为av的样本,记为D”.我们可根据上式计算出Dv的信息嫡,再考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重|Dv|/|D|,即样本数越多的分支结点的影响越大,于是可计算出用属性α对样本集D进行划分所获得的“信息增益”(information gain)
在这里插入图片描述

一般而言,信息增益越大,则意味着使用属性α来进行划分所获得的“纯度提升”越大.因此,我们可用信息增益来进行决策树的划分属性选择,即在上式算法选择属性a*= argmaxGain(D,a)、著名的ID3决策树学习算就是以信息增益为准则来选择划分属性.

决策树的优缺点

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感;
缺点:可能产生过度匹配问题

二.数据处理

使用上次实验的数据,每个列分别表示:[‘卷面成绩’,‘班级排名’,‘综测分’,‘奖学金等级’]
其中 奖学金等级 为我们将要预测的标签。
在这里插入图片描述
可以看到属性的数据类型都为连续型,由于连续属性的可取值数目不再有限,因此不能直接对连续型属性的可取值来对节点进行划分,接下来要将数据离散化 。
最简单暴力的方法,排序后按比例划分n类(暂时不考虑信息增益):

#离散化数据
#data数据 axis待划分属性 num划分几类
def discretedata(data,axis,num):
    len_data=len(data)
    #求该属性的最大值和最小值
    max=0;min=100
    for i in range(len_data):
        if data[i][axis]>max:
            max=data[i][axis]
        if data[i][axis]<min:
            min=data[i][axis] 
    #划分区间
    degree=(max-min)*1.0/num
    limit=[min]
    for i in range(num):
        limit.append(min+degree*(i+1))
    print(limit)
   #修改对应的值,1代表最低级     
    for one_data in data:
        for i in range(len(limit)-1):
            if one_data[axis]>=limit[i] and one_data[axis]<=limit[i+1] :
                one_data[axis]=i+1 
    print(data)

可以看到第一个属性被分为5个等级(根据数据集实际情况调整),接下来对剩余属性进行相同操作
在这里插入图片描述

    mydata=createData('./ch1/grade.txt')
    for i in range(3):
        discretedata(mydata,i,6)#这里分为6个等级
    print(mydata)

在这里插入图片描述
这里所有属性都分为6个等级,可以根据实践情况再调整。

三.决策树的构建

计算给定数据集的香农熵

#计算给定数据的熵
def calcEnt(data):
    num=len(data)#获取数据的行数
    labels={}
    #遍历数据的所有行
    for featVec in data:
        #为所有可能分类创建字典
        currentLabel=featVec[-1]
        if currentLabel not in labels.keys():#如果字典中不存在该键则创建并初始化为0
            labels[currentLabel]=0
        labels[currentLabel]+=1#统计每个类别
    Ent=0.0
    for key in labels:
        prob=float(labels[key])/num
        Ent-=prob*log2(prob)
    return Ent
print("计算当前数据的熵",calcEnt(mydata))

在这里插入图片描述

按照给定特征划分数据集

#按照给定特征划分数据集
def splitDataSet(dataSet,axis,value):# 待划分的数据集 划分数据集的特征 需要返回的特征的值
    retDataSet=[]
    for featVec in dataSet:
        if featVec[axis] ==value:
            reducedFeatVec=featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])#放列表中的元素
            retDataSet.append(reducedFeatVec)#把整个列表放入
    return retDataSet
if __name__=='__main__':
    labels=['卷面成绩','班级排名','综测分','奖学金等级']
    mydata=createData('./ch1/grade.txt')
    for i in range(3):
        discretedata(mydata,i,6)
    print("计算当前数据的熵",calcEnt(mydata))
    print("按奖学金为1划分测试:",splitDataSet(mydata,3,1))

在这里插入图片描述

选择最好的数据划分方式:

def chooseBest(dataset):
    num=len(dataset[0])-1 #除去标签剩余数量
    baseEnt=calcEnt(dataset)#计算整个数据的香农熵
    bestGain=0.0 
    bestFeature=-1
    for i in range(num):#0 1 2
        #创建唯一的分类标签列表
        featlist=[example[i] for example in dataset]#对每行数据取i列放入featlist
        uniqueVals=set(featlist)#集合去重复
        newEnt=0.0
        for value in uniqueVals:
            #计算每种划分方式的信息熵
            subDataSet=splitDataSet(dataset,i,value)
            prob=len(subDataSet)/float(len(dataset))
            newEnt+=prob*calcEnt(subDataSet)
        inforGain=baseEnt-newEnt
        #计算最好的信息熵
        if (inforGain>bestGain):
            bestGain=inforGain
            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)
    print(sortedClassCount)
    return sortedClassCount[0][0]

创建树的代码:
使用python语句中的字典类型存储树的信息

def createTree(dataSet,labels):
    #类别完全相同则停止划分
    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)
    bestFeat=chooseBest(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[:] #复制一份
        myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels)
    return myTree
if __name__=='__main__':
    labels=['卷面成绩','班级排名','综测分','奖学金等级']
    mydata=createData('./ch1/grade.txt')
    for i in range(3):
        discretedata(mydata,i,6)
    mytree=createTree(mydata,labels)
    print(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.axl.annotate(nodeTxt,xy=parentPt,xycoords='axes fraction',
    xytext=centerPt,
    textcoords='axes fraction',
    va="center",ha="center",bbox=nodeType,arrowprops=arrow_args)

#获取叶节点的数目和树的层数
def getNumLeafs(myTree):
    numLeafs=0
#  firstStr=myTree.keys()[0]
    firstStr=list(myTree.keys())[0]
    secondDict=myTree[firstStr]
    for key in secondDict.keys():
        if type(secondDict[key]).__name__=='dict':
            numLeafs+=getNumLeafs(secondDict[key])
        else:
            numLeafs+=1
    return numLeafs

def getTreeDepth(myTree):
    maxDepth=0
    firstStr=list(myTree.keys())[0]
    secondDict=myTree[firstStr]
    for key in secondDict.keys():
        if type(secondDict[key]).__name__=='dict':
            thisDepth=1+getTreeDepth(secondDict[key])
        else:
            thisDepth=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.axl.text(xMid,yMid,txtString)

def plotTree(mytree,parentPt,nodeTxt):
    numLeafs=getNumLeafs(mytree)
    depth=getTreeDepth(mytree)
    firstStr=list(mytree.keys())[0]
    cntrPt=(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.totalD
    for key in secondDict.keys():
        if type(secondDict[key]).__name__=='dict':
            plotTree(secondDict[key],cntrPt,str(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.totalD


def createPlot(inTree):
    fig=plt.figure(1,facecolor='white')
    fig.clf()
    axprops=dict(xticks=[],yticks=[])
    createPlot.axl=plt.subplot(111,frameon=False,**axprops)
    plotTree.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),'')
    plt.show()


当直接采用3等级暴力划分的决策树
在这里插入图片描述

五.总结

出现的问题及解决办法:

  1. ‘dict’ object has no attribute ‘iteritems’
    在这里插入图片描述
    python3.x以上iteritems()已改为items()
    解决办法:
    在这里插入图片描述
  2. ‘numpy.ndarray’ object has no attribute ‘extend’
    在这里插入图片描述
    在递归过程中,有时数据类型变为numpy,将其改为python列表
    解决办法:增加两行代码
    在这里插入图片描述
    3.‘dict_keys’ object does not support indexing
    字面意思,字典不支持索引,可能python2.x可以,3.x以上不行了
    在这里插入图片描述
    解决办法:转化为列表
    在这里插入图片描述

实验结果分析

从数据划分上看:班级排名越低越好;综测分越高越好;卷面成绩越高越好
1.在绘制的决策树中可以看出,班级排名为首选分类属性(越低表示班级排名越高,越容易拿到奖学金),这也符合实际。
2.第二个属性为综测分,最右边的节点可以看出,当综测分等级为3时(最高),综测分低于2等级的都不可能拿到奖学金(分支下所有实例都具有相同类别),等于3时有可能拿到3等奖学金

3.后期可以根据熵来处理连续型属性,当前采用3等级划分已经符合实际了,下次实验有待改进。


2022/11/12

附上本次完整代码和数据集:link

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习实验二---决策树python 的相关文章

  • 安装 Pillow 和 PIL

    I have Ubuntu 12 04 http en wikipedia org wiki List of Ubuntu releases Ubuntu 12 04 LTS 28Precise Pangolin 29 Precise Pa
  • 将 for 循环转换为列表理解

    我有一个for循环 将字符串列表中每个元素的子字符串与另一个字符串列表中的元素进行比较 mylist for x in list1 mat False for y in list2 if x 14 in y mat True if not
  • 如何使用Python从pdf文件中删除页面?

    我有一些超过 500 页的 pdf 文件 但每个文件中只需要几页 有必要保留文档的标题页 我确切地知道程序应该删除的页数 如何使用安装在 MS Visual Studio 上的 Python 2 7 环境来完成此操作 尝试使用PyPDF2
  • 如何在Python中绘制“Trace Explorer”?

    我需要重新创建一个情节 踪迹浏览器 https www bupar net trace explorer html与下面在 R 中创建的类似 我希望使用 matplotlib 但找不到任何有关如何执行这样的跟踪资源管理器的示例或参考 有人能
  • 将 Python 脚本导入另一个脚本?

    我正在阅读 Zed Shaw 的 艰难学习 Python 正在学习第 26 课 在本课中 我们必须修复一些代码 这些代码从另一个脚本调用函数 他说我们不必导入它们来通过测试 但我很好奇我们将如何做到这一点 课程链接 http learnpy
  • 如何在 PyCharm 社区版中运行 Django 项目的调试服务器?

    有人在 PyCharm 社区版中为 Django 项目设置调试配置时遇到问题吗 IDE 的社区版缺少项目设置中的项目类型选项 然后当我设置 调试 或 运行配置 时 它会要求我提供应该运行的脚本 Django 需要什么脚本 manage py
  • 到底什么是序列?

    蟒蛇docs https docs python org 3 glossary html term sequence有点模棱两可 sequence 一个可迭代对象 支持通过以下方式使用整数索引进行有效的元素访问 getitem 特殊方法并定
  • 按自定义年度频率重新采样

    我知道我可以使用 AS JUL 从 7 月 1 日开始每年重新采样 但在不同的日期之前我该如何做 In 11 df Out 11 value date 2005 07 02 4 2005 09 20 7 2005 11 12 4 2005
  • 查找提供的 Sum 值的组合

    我有一系列这样的数字 myvar 57 71 87 97 99 101 103 113 114 115 128 129 131 137 147 156 163 186 现在我想计算所有这些可能的组合 长度为1到20 其总和等于给定的数字m
  • Django:在管理界面中显示多对多项目的列表

    这可能是一个简单的问题 但我似乎无法理解 我在 models py 中有两个简单的模型 Service 和 Host Host services 与 Service 具有 m2m 关系 换句话说 一台主机有多个服务 一个服务可以驻留在多个主
  • 有一些 numpy.map 吗?

    我可能在这里遗漏了一些明显的东西 但我遗漏了一个功能numpy map 这与 Python 的相同map函数 但将输出收集在numpy大批 例如 我可以有一个图像生成器genImage i 生成 2D 图像 大小 m n 基于单个输入 我想
  • 如何获取 Flask 中当前的基本 URI? [复制]

    这个问题在这里已经有答案了 在下面的代码中 我想将 URL 存储在变量中以检查发生 URL 错误的错误 app route flights methods GET def get flight flight data mongo db fl
  • PyCrypto:生成受 DES3 密码保护的 RSA 密钥

    我已经能够使用 DES3 创建受密码保护的 RSA 密钥 嗯 I think因为我对这个加密世界非常陌生 使用以下命令 openssl genrsa out tmp myKey pem passout pass f00bar des3 20
  • 保持 WebSocket 连接处于活动状态

    我正在研究 WebSocket 协议 并尝试在后端使用 Python 实现一个简单的 ECHO 服务 它似乎工作正常 但连接建立后立即断开 这是我的客户
  • 如何为 matplotlib 中已绘制的线设置标签?

    在我的代码中我已经执行了 ax plot x y b 并且需要能够在事后设置相应行的标签 以达到与我相同的效果 ax plot x y b label lbl 有没有办法在 Matplotlib 中做到这一点 如果你抓住了line2D创建对
  • 合法 .xlsx 文件上的 openpyxl load_workbook() 会导致 zipfile.BadZipFile 错误

    我试图做的是将数据帧数据附加到现有的合法 Excel 文件中 我使用了 openpyxl 中的 load workbook 函数 但它系统地返回错误 这是一些在我的机器上崩溃的代码 from openpyxl import load wor
  • 带过滤器的 SQLAlchemy func.count

    我正在使用一个进行分页的框架 如下所示 def get count query self return self session query func count select from self model def paginate se
  • 打开 PDF 到书签/指定目标?

    我正在尝试使用 python 打开特定书签的 PDF 到目前为止 我可以在命令提示符中运行以下命令并得到我想要的 last是 PDF test pdf 中指定目的地的名称 C Program Files x86 Adobe Reader 1
  • 在 Django 1.7 中使用 html 发送电子邮件

    In 发送邮件 我们有一个新参数 html message Docs https docs djangoproject com en dev topics email send mail I have 电子邮件 html文件 我想发送我的消
  • python函数中的Return语句不返回任何内容[重复]

    这个问题在这里已经有答案了 我不明白退货和打印之间的区别 有人告诉我应该在函数语句中使用 return 但它不会返回任何内容 所以我一直在函数中使用 print 但我想了解为什么我的函数中的 return 语句不起作用 def triang

随机推荐

  • 如何使用BurpSuite(后续)

    前面那篇文章是我前几天写的 我发现我把简单的问题弄得复杂了 今天我给大家再写一篇关于BurpSuite的使用 1 下载安装免费版或者收费版 这里就不演示了 2 运行软件 一直NEXT就可以 3 打开工具 此时拦截状态显示OFF 4 在打开的
  • Python中类成员变量与实例成员变量相互影响的原因超详细解释

    今天在看python学习手册时看到了两句话 一 第26章中 类对象提供默认行为 二 第26章中 实例对象是具体的元素 书中给的例子是这样的 但上网查了一下好像第二句话不是非常准确 如下面的文章 原文 https www jb51 net a
  • 优化算法学习(LM算法)

    文章目录 推荐书籍 理论理解 程序实现 ceres安装 代码 推荐书籍 建议学习 METHODS FOR NON LINEAR LEAST SQUARES PROBLEMS http www2 imm dtu dk pubdb views
  • Eclipse导入Maven项目,实在算得上是历经千辛万苦

    私下接触了一个项目 架构师那边用的是idea 并且是一个Maven项目 架构师说他那边idea可以自动将Maven项目转换为Web项目 但我已经习惯用Eclipse了 所以还需要自己动手试一试 这一试 一上午的时间算是过去了 尤其是中间遇到
  • 商品关联度分析(关联三度,附Python实战) 我的钱就是这么没的,不只有皮尔森系数的相关分析

    引言 上一年组织烧烤活动买食材时 我在超市的货架29买了一个烧烤架 然后到货架27买了瓶1 5L的可乐 最后在货架25找到了我需要的塑料小碗 今年再去那家超市的时候 特地再去烧烤架所在的货架查看了一下 看看有没有什么值得记录的灵感 果不其然
  • Mybatis处理枚举

    Springboot 集成 Mybatis 处理枚举 mybatis自带了两个处理枚举的 类 EnumTypeHandler EnumOrdinalTypeHandler 一个使用枚举的name 一个使用枚举的下标 做项目时 会节省数据库资
  • 业务逻辑漏洞总结

    业务逻辑漏洞总结
  • 纯前端实现excel表格导入导出

    前言 github https github com stardew516 以往做excel表格下载功能的时候 都是后端生成好表格后 存储在某个地方 然后给前端一个链接 前端使用a标签加download下载 或者使用node 其实纯前端也是
  • CSP 202209-1 如此编码

    答题 题目就是字多 include
  • ARIMA序列分析

    1 什么是平稳序列 stationary series 基本上不存在趋势的序列 各观察值基本上在某个固定的水平上波动或虽有波动 但并不存在某种规律 而其波动可以看成是随机的 2 ARMA模型 ARIMA的优缺点 优点 模型十分简单 只需要内
  • 关于谷歌浏览器安装油猴插件失败的解决方法

    今天拿到了一台二手电脑 刷完之后开始安装需要的程序 在给谷歌浏览器安装油猴插件的时候出现了很多错误 现在一一道来 希望对大家有所帮助 一 不知道如何找油猴插件 上某度搜了一下 都是exe执行文件 运行一下不知道会带来多少 兄弟姐妹 官网又没
  • 刷脸支付为高效便捷的生活这样应运而生

    科技让我们的生活更加便捷 没有人会拒绝更加高效便捷的生活 刷脸支付便是这样应运而生 拿我们的爷爷奶奶举例 他们并不精通手机 扫码支付对他们来说十分繁琐 甚至还没现金支付来的方便 因此刷脸支付便替他们解决了这一难题 不需任何操作 也无需记住密
  • java中的异常

    异常 什么是异常 运行时异常和编译时异常 编译时异常 运行时异常 异常处理及其语法 异常的产生及处理 try catch语句 finally语句 抛出异常 throws关键字 throw关键字 自定义异常类 什么是异常 java中的异常是指
  • 使用openssl的md5库

    http blog csdn net hepeng597 article details 8984797 在linux机器上 有一个命令可以计算出文件的md5值 那就是md5sum 如果没有的话 就需要安装RPM包 coreutils 现在
  • 嵌入式Ai方案介绍

    原文 https blog 51cto com zjbintsystem 2147975 utm source oschina app 公司玩了大半年的嵌入式AI平台 现在产品进入量产模式 也接触了很多嵌入式方案 有了一些心得体会 本人不才
  • 每天200亿次查询 – MongoDB在奇虎360

    每天200亿次查询 MongoDB在奇虎360 时间 2015 03 11 18 19 35 MongoDB中文社区 原文 http www mongoing com archives 715 主题 MongoDB 100 多个应用 1 5
  • 看完这篇 教你玩转渗透测试靶机Vulnhub——DriftingBlues-6

    Vulnhub靶机driftingblues6 vh渗透测试详解 Vulnhub靶机介绍 Vulnhub靶机下载 Vulnhub靶机漏洞详解 信息收集 开始目录爆破 暴力破解zip 上传WebShell 脏牛提权 获取flag Vulnhu
  • Jquery——Day4(Ajax进阶:加载请求、错误请求、请求全局事件、json/jsonp)

    1 加载请求 jQuery提供了两种全局事件 ajaxStart ajaxStop 只要用户触发了Ajax 请求开始时 未完成其他请求 激活ajaxStart 请求结束时激活ajaxStop loading ajaxStart functi
  • Swift如何使用Vision来识别获取图片中的文字(OCR),通过SwiftUI视图和终端命令行,以及一系列注意事项

    在过去的一年里 我发现苹果系统中的 文字搜图片 功能非常好用 这个功能不光 iPhone iPad Mac 也有 找一些图片真的很好用 但是遇到了一个问题 这个功能需要一段时间才能找到新的图片 而且没法手动刷新 这对于外接硬盘里的图片来说不
  • 机器学习实验二---决策树python

    机器学习实验二 决策树python 一 了解一下决策树吧 决策树基本流程 信息增益 决策树的优缺点 二 数据处理 三 决策树的构建 计算给定数据集的香农熵 按照给定特征划分数据集 选择最好的数据划分方式 递归构建决策树 四 使用Matplo