机器学习——决策树(三)预剪枝

观前提示:这是本人机器学习决策树内容的第三篇博客沿用了之前相关的代码,包括信息增益计算函数、结点类、预测函数和分类精度计算函数 

完整代码指路

DrawPixel/decisionTree.ipynb at main · ndsoi/DrawPixel (github.com)

前两篇博客详见“机器学习”专栏

使用方法:

方法一:一口气连接——执行是不会报错的

方法二:针对本节内容的代码块

notebook中我做了目录划分

与本节内容相关的代码块如下图:

本节没有用到的是 dotree函数和TreeGenerate函数,所以预剪枝的主要是替换了TreeGenerate的逻辑

1、含义

预剪枝:

剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点

作用:提高构建决策树的效率、防止过拟合、提高模型的鲁棒性

2、实现流程

算法流程:

  1. 划分好训练集和验证集;
  2. 初始化根节点,标记为叶结点,用验证集计算精度,对当然结点进行划分,再用验证集计算精度,如果精度提升,则对当前结点进行划分,若精度无提升则不划分。

用一个队列(名为waitcheck)维护要考虑划分的结点。

step1:初始化根结点,将根结点投入到waitcheck中;

step2:从waitcheck中取出一个结点:

①当前结点是一个叶结点,计算验证集的分类精度a

②考虑当前结点能否在划分:

        若该结点可以划分,则找出它划分的最优属性,进行划分,再计算划分后的验证集预测效果b

                比较a和b的大小:

                        如果b比a小,则不划分,将该结点标记为叶结点,继续考虑waitcheck

                        如果b比a大,则将该结点标记为非叶结点,新生成的子结点加入waitcheck

        不行则考虑下一结点

step3:重复step2,直到waitcheck为空

3、编程实现

1、划分训练集和验证集

按照西瓜书的数据划分:


dataSet = [# 1['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],# 2['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'],# 3['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],# 4['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'],# 5['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],# 6['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '好瓜'],# 7['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', '好瓜'],# 8['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', '好瓜'],# ----------------------------------------------------# 9['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜'],# 10['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '坏瓜'],# 11['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '坏瓜'],# 12['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '坏瓜'],# 13['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', '坏瓜'],# 14['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', '坏瓜'],# 15['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '坏瓜'],# 16['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', '坏瓜'],# 17['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜']]
Attr = ['色泽', '根蒂', '敲击', '纹理', '脐部', '触感']# 硬编码类别
class_dict = {'坏瓜':0,'好瓜':1}# 将数据合并格式
D = []
for i in range(len(dataSet)):d = {}for j in range(len(Attr)):d[Attr[j]] = dataSet[i][j]d['Class'] = class_dict[dataSet[i][-1]]D.append(d)print(D)

2、批量验证函数

# 精度计算
def calAccuracy(pred,data):n = len(data)re = 0for i in range(n):if pred[i] == data[i]['Class']:re+=1return re/n# 返回预测结果和精度
def predict_v4(root_4,val_data):re = []for i in range(len(val_data)):re.append(predict_v2(val_data[i],root_v4))return re,calAccuracy(re,val_data)

3、结点是否能继续划分

# 若是否有划分的资格
def CanDivide(node_v4):if node_v4.isSameClass() == True:return False,[]boolre,Attr = node_v4.isNoAttr()if boolre == False:return True,Attrreturn False,[]

4、初始数据集生成根结点、初始化waitcheck

import queue
# 找出初始数据集的最多类
max,cal_class = calMaxClass(train_data,class_num)
# 构造训练集的根结点
root_v4 = Node(train_data,Attr,max,cal_class,class_num) 
# 标记根结点位叶结点
root_v4.label = 1# 初始化waitcheck队列
waitcheck = queue.Queue()
waitcheck.put(root_v4)

5、预剪枝过程(核心) 

def train_v4(waitcheck,root_v4):node_v4 = waitcheck.get()# 用验证集算一下精度res_o,acc_o = predict_v4(root_v4,val_data) divide,Attr_Div = CanDivide(node_v4)if divide == False:# 考虑下一个结点print("考虑下一个结点")returnelse:# 先将当前结点的label改为0node_v4.label = 0# 尝试划分结点# 选取最优属性attr,info = node_v4.bestAttr()# 获取划分好的数据集SubDataSets = info[attr]['Dv']SubInfo = info[attr]['Dv_info']# 生成子node# 保持子nodesavesubnode = []Attr = copy.deepcopy(Attr_Div)Attr.remove(attr)st = 0for value,subds in SubDataSets.items():# 因为假设是离散属性,所以新的self.attr必然要去掉已经选出的attrsubnodeAttr = copy.deepcopy(Attr)# 获取已经算好的Dv的max和cal_classsubmax = SubInfo[st][0]subcal_class = SubInfo[st][1]st+=1# 生成新结点subnode = Node(subds,subnodeAttr,submax,subcal_class,class_num)subnode.setflag(attr)# 假设新结点都是叶子结点subnode.label = 1# 暂存取得的新结点,若确定要划分,才加入讨论队列savesubnode.append(subnode)# 父结点记录子结点的指引node_v4.addsubDs(subnode,value)# 验证集评估res_d,acc_d = predict_v4(node_v4,val_data)print(f"未划分时的分类精度:{acc_o},划分后的分类精度:{acc_d}")print(f"展示一下划分后的树")drawTree(root_v4)if acc_d>acc_o:# 划分后的精度更高,所以划分# 将新的子结点加入waitcheckfor i in savesubnode:# i.label = 0 不用改,取出来还要再令label=1waitcheck.put(i)else:# 划分后验证集的预测结果print("划分后验证集预测结果")print(res_d)# 最终还是不划分node_v4.label = 1

6、训练

while waitcheck.empty()==False:train_v4(waitcheck,root_v4)drawTree(root_v4)

4、结果显示

1)对原始数据集考虑划分:可以看到在计算机计算精度内,色泽和脐部属性的信息增益是一样的,但遍历的时候脐部在后,而要求是大于等于最大信息增益的属性就可以替换为最优,所以初次划分的最优属性是脐部

2)按照脐部划分后,验证集评估模型发现划分后的分类精度是0.75,划分前的精度是0.375,所以不剪枝,将新增的子结点加入waitcheck

3)继续考虑新的结点,按照添加顺序应该是“脐部=凹陷”的数据集,该数据集的最优属性划分(看蓝色箭头),在计算机精度内后来者居上最优的属性是“纹理”,然后看下方绿色线,发现按照“纹理”划分,精度又从0.75提升至0.875,因此又保留了“纹理”产生的分支

4)继续考虑waitcheck的数据,发现这些结点再划分都不会使得模型在验证集的精度提升,于是决策树模型完全形成

最终的决策树是:

5、讨论:

这个预剪枝的结果与《机器学习》上的并不一致

原因:就是在最优属性划分上:同样的信息增益,西瓜书的选择是“色泽”,我的程序选择的是“纹理”,当用验证集验证的时候,“色泽”划分会导致正确性下降,而纹理却能继续提升分类精度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/761838.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux学习-进程

目录 进程基本概念 进程相关命令 进程的创建 进程的调度 进程相关函数接口 进程的消亡 实例:创建九个子进程 目录 进程基本概念 进程相关命令 进程的创建 进程的调度 进程相关函数接口 进程的消亡 实例:创建九个子进程 exec函数…

人脸表情识别系统项目完整实现详解——(三)训练MobileNet深度神经网络识别表情

摘要:之前的表情识别系统升级到v3.0版本,本篇博客详细介绍使用PyTorch框架来构建并训练MobileNet V3模型以进行实现表情识别,给出了完整实现代码和数据集可供下载。从构建数据集、搭建深度学习模型、数据增强、早停等多种技术,到模…

计算联合体union的大小

一:联合类型的定义 联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体) 比如:共用了 i 这个较大的空间 二: 联合的特点 …

MySQL--Buffer Pool

虽然说 MySQL 的数据是存储在磁盘里的,但是也不能每次都从磁盘里面读取数据,这样性能是极差的。为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。 有了缓冲池后: …

Eclipse For ABAP:安装依赖报错

1.安装好Eclipse后需要添加依赖,这里的地址: https://tools.hana.ondemand.com/latest 全部勾选等待安装结束; 重启后报错:ABAP communication layer is not configured properly. This might be caused by missing Microsoft Visual C++ 2013 (x64) Runtime DLLs. Consu…

小程序云开发实战:通用企业产品信息展示小程序

之前做小程序都是自己搭建数据管理后台,比如我之前做的小程序:一搜就学,就是使用java来做管理后台,小程序做前端展示。但是对于简单的小程序来说,做一套管理后台有点拿大炮打蚊子,所以使用云开发就是不错的…

【开源】SpringBoot框架开发知识图谱构建系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 知识图谱模块2.2 知识点模块2.3 学生测评模块2.4 学生成绩模块 三、系统展示四、核心代码4.1 查询知识点4.2 新增知识点4.3 查询知识图谱4.4 查询学生成绩4.5 查询学生成绩 五、免责说明 一、摘要 1.1 项目介绍 基于J…

论文阅读:Forget-Me-Not: Learning to Forget in Text-to-Image Diffusion Models

Forget-Me-Not: Learning to Forget in Text-to-Image Diffusion Models 论文链接 代码链接 这篇文章提出了Forget-Me-Not (FMN),用来消除文生图扩散模型中的特定内容。FMN的流程图如下: 可以看到,FMN的损失函数是最小化要消除的概念对应的…

一文了解AI长文本工具:Kimi Chat;与ChatGPT比较对比

一文了解AI长文本工具:Kimi Chat;与ChatGPT比较对比 在人工智能领域,ChatGPT、Claude2.1和Kimi Chat都是备受关注的大型模型。它们在文本生成、理解和处理方面展现了强大的能力。本文将深入探讨这三个工具的核心功能、优劣势以及适用场景&am…

Markdown快速入门(常用技巧)

目录 说明常用书写技巧1.标题分级2.代码块3.字体4.引用语法5.分割线6.图片插入(本地/网络)7.超链接8.列表9.表格10.换行(两个空格)11.插入公式12.脚注 说明 markdown实际上类似于网页,可以根据喜欢设置其样式变化,创建…

iOS18系统中,苹果可能不再使用Siri,转用Gemini

生成式人工智能(Generative AI)是苹果公司近两年来默默投资的强大人工智能工具。 坊间流有多种传闻,官方最近终于曝光结果:苹果和谷歌正在谈判将 Gemini AI 引入 iPhone,预计将于今年在所有 iOS 18 设备上推出。 到目前…

GitHub Copilot怎么取消付费?

0. 前言 GitHub Copilot非常好用,还没有使用过的同学可以参考教程白嫖一个月:【保姆级】VsCode 安装GitHub Copilot实操教程 GitHub Copilot每月10美元的费用对于一些用户来说可能是一笔不小的开销。如果你已经完成了GitHub Copilot的免费试用&#xf…

【超详细图文讲解】如何利用VMware创建CentOS虚拟机(包括如何更改网络设置 + 远程访问虚拟机方法)

文章目录 前言1. 准备相关软件环境1.1 获取 ISO 镜像包1.2 VMware 的安装 2. 使用 VMware 安装 CentOS3. 初始化虚拟机4. 虚拟机网络的设置4.1 虚拟机的三种网络连接模式桥接模式NAT 模式仅主机模式 4.2 如何更改网络设置 5. 远程访问虚拟机的方法5.1 使用 cmd 进行访问5.2 使用…

React 系列 之 React Hooks(一) JSX本质、理解Hooks

借鉴自极客时间《React Hooks 核心原理与实战》 JSX语法的本质 可以认为JSX是一种语法糖,允许将html和js代码进行结合。 JSX文件会通过babel编译成js文件 下面有一段JSX代码,实现了一个Counter组件 import React from "react";export defau…

基于python+vue的幼儿园管理系统flask-django-php-nodejs

随着信息时代的来临,过去的传统管理方式缺点逐渐暴露,对过去的传统管理方式的缺点进行分析,采取计算机方式构建幼儿园管理系统。本文通过课题背景、课题目的及意义相关技术,提出了一种活动信息、课程信息、菜谱信息、通知公告、家…

网站安全:抵御网络攻击的几个安全措施

随着互联网的发展,网站安全成为每个企业和个人都必须重视的问题。黑客攻击不断增多,威胁着网站的稳定性和数据的安全。为了应对这一挑战,我们必须采取一系列的安全措施,确保网站的安全与稳定。 不过,关于在做好网络安全…

Docker基本操作

我们可以通过 docker --help 查看所有命令 我们可以通过docker hub 拉取 Docker hub官网链接 接着 输入 docker images 查看刚才拉取的nginx镜像 镜像常见操作 docker imagesdocker rmidocker pulldocker pushdocker savedocker load

Docker 搭建私人仓库

docker 搭建私人仓库有下面几种方式: 1、docker hub 官方私人镜像仓库2、本地私有仓库 官方私人镜像仓库搭建很简单(就是需要有魔法,否则就异步到第二种方法吧),只需要 login、pull、tag、push 几种命令就完事了。而本地私人镜像仓库则比较麻…

sentinel整合gateway实现服务限流

导入依赖: <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.csp</groupId><…

【Python脚本随手笔记】 ---基于鸿蒙系统LiteOS实现差分编译脚本(下篇)

💌 所属专栏:【Python脚本随手笔记】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘 文章目录 前言一、&…