决策树的生成与剪枝

决策树的生成与剪枝

  • 决策树的生成
    • 生成决策树的过程
    • 决策树的生成算法
  • 决策树的剪枝
    • 决策树的损失函数
    • 决策树的剪枝算法
  • 代码

决策树的生成

生成决策树的过程

为了方便分析描述,我们对上节课中的训练样本进行编号,每个样本加一个ID值,如图所示:
在这里插入图片描述
从根结点开始生成决策树,先将上述训练样本(1-9)全部放在根节点中。

然后选择信息增益或信息增益比最大的特征向下分裂,按照所选特征取值的不同将训练样本分发到不同的子结点中。

例如所选特征有3个取值,则分裂出3个子结点,然后在子结点中重复上述过程,直到所有特征的信息增益(比)很小或者没有特征可选为止,完成决策树的构建,如下图所示:
在这里插入图片描述
图中的决策树共有2个内部结点和3个叶子结点,每个结点旁边的编号代表训练样本的 ID 值。内部结点代表样本的特征,叶子结点代表样本的预测类别,我们将叶子节点中训练样本占比最大的类作为决策树的预测标记。

在使用构建好的决策树在测试数据上分类时,只需要从根节点开始依次测试内部结点代表的特征即可得到测试样本的预测分类。

决策树的生成算法

下面我们先来总结一下 ID3分类决策树的生成算法:

输入:训练数据集 D 、特征集合 A 的信息增益阈值 ;输出:决策树 T

  1. 若 D 中的训练样本属于同一类,则 T 为单结点树,返回 D 中任意样本的类别。

  2. 若 A 中的特征为空,则 T 为单结点树,返回 D 中数量最多的类别。

  3. 使用信息增益在 A 中进行特征选择,若所选特征 A_i 的信息增益小于设定的阈值,则 T 为单结点树,返回 D 中数量最多的类别。

  4. 否则根据 A_i 的每一个取值,将 D 分成若干子集 D_i,将 D_i 中数量最多的类作为标记值,构建子结点,返回 T。

  5. 以 D_i 为训练集,{A - A_i} 为特征集,递归地调用上述步骤,得到子树 T_i,返回 T。

使用 C4.5 算法进行决策树的生成只需要将信息增益改成信息增益比即可。

决策树的剪枝

决策树的损失函数

决策树的叶子节点越多,模型越复杂。决策树的损失函数考虑了模型复杂度,我们可以通过优化其损失函数来对决策树进行剪枝。决策树的损失函数计算过程如下:

  1. 计算叶子结点 t 的样本类别经验熵
    在这里插入图片描述
    对于叶子结点 t 来说,其样本类别的经验熵越小, t 中训练样本的分类误差就越小。当叶子结点 t 中的训练样本为同一类别时,经验熵为零,分类误差为零。

  2. 计算决策树 T 在所有训练样本上的损失之和 C(T)
    在这里插入图片描述
    对于叶子结点 t 中的每一个训练样本,其类别标记都是随机变量 Y 的一个取值,这个取值的不确定性用信息熵来衡量,且可以用经验熵来估计。由上文可知,经验熵在一定程度上可以反映决策树在该样本上的预测损失,累加所有叶子结点上的训练样本损失即上图中的计算公式。

  3. 计算考虑模型复杂度的的决策树损失函数

在这里插入图片描述
决策树的叶子结点个数表示模型的复杂度,通过最小化上面的损失函数,一方面可以减少模型在训练样本上的预测误差,另一方面可以控制模型的复杂度,保证模型的泛化能力。

决策树的剪枝算法

  1. 计算决策树中每个结点的样本类别经验熵:
    在这里插入图片描述
    如上图所示,对于本课示例中的决策树,需要计算 5 个结点的经验熵。

  2. 遍历非叶子结点,剪枝相当于去除其子结点,自身变为叶子结点:

在这里插入图片描述
对于图中的非叶子结点(有工作?),剪枝后变为叶子结点,并通过多数表决的方法确定其类别标记。

以上就是这节课的所有内容了,实际上还有一种决策树算法:分类与回归树(classification and regression tree,简称 CART),它既可以用于分类也可以用于回归,同样包含了特征选择、决策树的生成与剪枝算法。

关于 CART 算法的内容,我们将在最后一章 XGBoost 中进行学习,下面请你来做一道关于信息增益比的题目,顺便回顾一下前面所学的知识

代码

## 1. 创建数据集import pandas as pd
data = [['yes', 'no', '青年', '同意贷款'],['yes', 'no', '青年', '同意贷款'],['yes', 'yes', '中年', '同意贷款'],['no', 'no', '中年', '不同意贷款'],['no', 'no', '青年', '不同意贷款'],['no', 'no', '青年', '不同意贷款'],['no', 'no', '中年', '不同意贷款'],['no', 'no', '中年', '不同意贷款'],['no', 'yes', '中年', '同意贷款']]# 转为 dataframe 格式
df = pd.DataFrame(data)
# 设置列名
df.columns = ['有房?', '有工作?', '年龄', '类别']## 2. 经验熵的实现from math import log2
from collections import Counter
def H(y):'''y: 随机变量 y 的一组观测值,例如:[1,1,0,0,0]'''# 随机变量 y 取值的概率估计值probs = [n/len(y) for n in Counter(y).values()]# 经验熵:根据概率值计算信息量的数学期望return sum([-p*log2(p) for p in probs])## 3. 经验条件熵的实现def cond_H(a):'''a: 根据某个特征的取值分组后的 y 的观测值,例如:[[1,1,1,0],[0,0,1,1]]每一行表示特征 A=a_i 对应的样本子集'''# 计算样本总数sample_num = sum([len(y) for y in a])# 返回条件概率分布的熵对特征的数学期望return sum([(len(y)/sample_num)*H(y) for y in a])## 4. 特征选择函数
def feature_select(df,feats,label):'''df:训练集数据,dataframe 类型feats:候选特征集label:df 中的样本标记名,字符串类型'''# 最佳的特征与对应的信息增益比best_feat,gainR_max = None,-1# 遍历每个特征for feat in feats:# 按照特征的取值对样本进行分组,并取分组后的样本标记数组group = df.groupby(feat)[label].apply(lambda x:x.tolist()).tolist()# 计算该特征的信息增益:经验熵-经验条件熵gain = H(df[label].values) - cond_H(group)# 计算该特征的信息增益比gainR = gain / H(df[feat].values)# 更新最大信息增益比和对应的特征if gainR > gainR_max:best_feat,gainR_max = feat,gainRreturn best_feat,gainR_max ## 5. 决策树的生成函数
import pickle
def creat_tree(df,feats,label):'''df:训练集数据,dataframe 类型feats:候选特征集,字符串列表label:df 中的样本标记名,字符串类型'''# 当前候选的特征列表feat_list = feats.copy()# 若当前训练数据的样本标记值只有一种if df[label].nunique()==1:# 将数据中的任意样本标记返回,这里取第一个样本的标记值return df[label].values[0]# 若候选的特征列表为空时if len(feat_list)==0:# 返回当前数据样本标记中的众数,各类样本标记持平时取第一个return df[label].mode()[0]# 在候选特征集中进行特征选择feat,gain = feature_select(df,feat_list,label)# 若选择的特征信息增益太小,小于阈值 0.1if gain<0.1:# 返回当前数据样本标记中的众数return df[label].mode()[0]# 根据所选特征构建决策树,使用字典存储tree = {feat:{}}# 根据特征取值对训练样本进行分组g = df.groupby(feat)# 用过的特征要移除feat_list.remove(feat)# 遍历特征的每个取值 ifor i in g.groups:# 获取分组数据,使用剩下的候选特征集创建子树tree[feat][i] = creat_tree(g.get_group(i),feat_list,label)# 存储决策树pickle.dump(tree,open('tree.model','wb'))return tree# 6. 决策树的预测函数
def predict(tree,feats,x):'''tree:决策树,字典结构feats:特征集合,字符串列表x:测试样本特征向量,与 feats 对应'''# 获取决策树的根结点:对应样本特征root = next(iter(tree))# 获取该特征在测试样本 x 中的索引i = feats.index(root)# 遍历根结点分裂出的每条边:对应特征取值for edge in tree[root]:# 若测试样本的特征取值=当前边代表的特征取值if x[i]==edge:# 获取当前边指向的子结点child = tree[root][edge]# 若子结点是字典结构,说明是一颗子树if type(child)==dict:# 将测试样本划分到子树中,继续预测return predict(child,feats,x)# 否则子结点就是叶子节点else:# 返回叶子节点代表的样本预测值return child## 7. 在样例数据上测试# 获取特征名列表
feats = list(df.columns[:-1])
# 获取标记名
label = df.columns[-1]
# 创建决策树(此处使用信息增益比进行特征选择)
T = creat_tree(df,feats,label)
# 计算训练集上的预测结果
preds = [predict(T,feats,x) for x in df[feats].values]
# 计算准确率
acc = sum([int(i) for i in (df[label].values==preds)])/len(preds)
# 输出决策树和准确率
print(T,acc)

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

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

相关文章

ES6中的map和set

Set ES6 提供了新的数据结构 Set。它类似于数组&#xff0c;但是成员的值都是唯一的&#xff0c;没有重复的值。 Set本身是一个构造函数&#xff0c;用来生成 Set 数据结构。 以下代码 const s new Set();[2, 3, 5, 4, 5, 2, 2].forEach(x > s.add(x));for (let i of s…

C# 用语句初始化数据库,创建库和表 MySQL示例

目录 简要说明 代码实现 简要说明 有时候项目中&#xff0c;在部署过程中&#xff0c;单独用工具去创建数据库和表&#xff0c;会消耗很多人力和时间&#xff0c;也不利于后期程序迭代去增加数据表&#xff0c; 那可以在程序启动的时候&#xff0c;去判断数据库和表是否存在…

基于SpringBoot的疫苗在线预约功能实现十二

一、前言介绍&#xff1a; 1.1 项目摘要 随着全球公共卫生事件的频发&#xff0c;如新冠疫情的爆发&#xff0c;疫苗成为了预防和控制传染病的重要手段。传统的疫苗预约方式&#xff0c;如人工挂号或电话预约&#xff0c;存在效率低、易出错、手续繁琐等问题&#xff0c;无法…

java技术点

1 mysql的索引下推: 就是从减少服务层的的回表操作&#xff0c;在引擎层实现联表查询 2 可重入锁: 就是当前:z线程可重复获取锁&#xff0c;比如递归函数里有锁&#xff0c;防止死锁 3 解决redis脑裂: 参数 持久化 优化网络和硬件 4 加密&#xff1a; MD5 不可解 对称算法…

MySQL基础 -----MySQL数据类型

目录 INT类型 tinyint类型 类型大小范围 测试tinyint类型数据 float类型 测试&#xff1a; 测试正常数据范围的数据 测试插入范围超过临界值的数据&#xff1a; 测试float类型的四舍五入 ​编辑 decimal类型 同样测试&#xff1a; 字符串类型 char类型 测试&…

代码开发相关操作

使用Vue项目管理器创建项目&#xff1a;&#xff08;vue脚手架安装一次就可以全局使用&#xff09; windowR打开命令窗口&#xff0c;输入vue ui&#xff0c;进入GUI页面&#xff0c;点击创建-> 设置项目名称&#xff0c;在初始化git下面输入&#xff1a;init project&…

Pandas系列|第一期:列值的前N码模糊匹配

背景&#xff1a;物料清单&#xff08;BOM&#xff09;在做关键器件筛选时&#xff0c;需要筛选出编码的前N码模糊匹配给定的前缀list的所有bom行 关键点&#xff1a;前N码模糊匹配 df[col].str.startswith(tuple(item_prefix_list)&#xff09; 解决方法&#xff1a; impor…

如何在 Ubuntu 22.04 上安装和使用 Rust 编程语言环境

简介 Rust 是一门由 Mozilla 开发的系统编程语言&#xff0c;专注于性能、可靠性和内存安全。它在没有垃圾收集的情况下实现了内存安全&#xff0c;这使其成为构建对性能要求苛刻的应用程序&#xff08;如操作系统、游戏引擎和嵌入式系统&#xff09;的理想选择。 接下来&…

MybatisPlus-配置加密

配置加密 目前配置文件中的很多参数都是明文&#xff0c;如果开发人员发生流动&#xff0c;很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。 我们以数据库的用户名和密码为例。 生成秘钥 首先&#xff0c;我们利用AES工具生成一个随机秘钥&#…

记录:virt-manager配置Ubuntu arm虚拟机

virt-manager&#xff08;Virtual Machine Manager&#xff09;是一个图形用户界面应用程序&#xff0c;通过libvirt管理虚拟机&#xff08;即作为libvirt的图形前端&#xff09; 因为要在Linux arm环境做测试&#xff0c;记录下virt-manager配置arm虚拟机的过程 先在VMWare中…

艾体宝案例丨CircleCI 助力 ANA Systems 打造高效 CI/CD 模型

在现代软件开发领域&#xff0c;效率和可靠性是企业在竞争中取胜的关键。本文将深入探讨 ANA Systems 如何通过引入业界领先的 CI/CD 平台——CircleCI&#xff0c;克服传统开发流程的瓶颈&#xff0c;实现开发运营效率的全面提升。同时&#xff0c;本文还将详细解析 CircleCI …

Linux dd 命令详解:工作原理与实用指南(C/C++代码实现)

这段代码是一个模仿 Linux dd 命令的工具&#xff0c;它用于在不同文件之间复制数据。dd 是一个非常强大的命令行工具&#xff0c;可以用于数据备份、转换和复制。下面我将详细解释这段代码的原理、实现方式以及如何运行和测试。 Linux dd 命令的工作原理 dd 命令是 Unix 和 …

ChatGPT客户端安装教程(附下载链接)

用惯了各类AI的我们发现每天打开网页还挺不习惯和麻烦&#xff0c;突然发现客户端上架了&#xff0c;懂摸鱼的人都知道这里面的道行有多深&#xff0c;话不多说&#xff0c;开整&#xff01; 以下是ChatGPT客户端的详细安装教程&#xff0c;适用于Windows和Mac系统&#xff1a…

《C 语言携手 PaddlePaddle C++ API:开启深度学习开发新征程》

在深度学习领域&#xff0c;PaddlePaddle 作为一款强大的深度学习框架&#xff0c;为开发者提供了丰富的功能和高效的计算能力。而 C 语言&#xff0c;凭借其高效性和广泛的应用场景&#xff0c;与 PaddlePaddle 的 C API 相结合&#xff0c;能够为深度学习开发带来独特的优势。…

ARM CCA机密计算安全模型之固件启动

安全之安全(security)博客目录导读 目录 1、安全启动(Verified boot) 2、镜像格式和签名方案 3、防回滚 4、离线启动(Off-line boot) 5、CCA HES固件启动流程 6、CCA系统安全域启动过程 7、应用程序PE启动过程 8、稳健性 本节定义了将CCA固件引导至可证明状态的要…

Element@2.15.14-tree checkStrictly 状态实现父项联动子项,实现节点自定义编辑、新增、删除功能

背景&#xff1a;现在有一个新需求&#xff0c;需要借助树结构来实现词库的分类管理&#xff0c;树的节点是不同的分类&#xff0c;不同的分类可以有自己的词库&#xff0c;所以父子节点是互不影响的&#xff1b;同样为了选择的方便性&#xff0c;提出了新需求&#xff0c;选择…

【ALSA】snd_pcm_avail 接口

目录 简介使用场景注意事项函数签名代码示例 简介 snd_pcm_avail 是 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09;库中的一个函数&#xff0c;用于获取 PCM&#xff08;Pulse Code Modulation&#xff09;设备环形缓冲区中可用的音频数据量。这个函数对于音…

计算机网络——期末复习(1)背诵

背诵 交换机与路由器&#xff1a;交换机连接同一子网&#xff0c;利用帧中的目的物理地址转发帧&#xff0c;工作在数据链路层&#xff1b;路由器连接不同子网&#xff0c;利用IP数据报中的目的IP地址转发IP数据报&#xff0c;工作在网络层。五层的任务&#xff1a;&#xff0…

概率论得学习和整理27:关于离散的数组 随机变量数组的均值,方差的求法3种公式,思考和细节。

目录 1 例子1&#xff1a;最典型的&#xff0c;最简单的数组的均值&#xff0c;方差的求法 2 例子1的问题&#xff1a;例子1只是1个特例&#xff0c;而不是普遍情况。 2.1 例子1各种默认假设&#xff0c;导致了求均值和方差的特殊性&#xff0c;特别简单。 2.2 我觉得 加权…

【HarmonyOS NEXT】Web 组件的基础用法以及 H5 侧与原生侧的双向数据通讯

关键词&#xff1a;鸿蒙、ArkTs、Web组件、通讯、数据 官方文档Web组件用法介绍&#xff1a;文档中心 Web 组件加载沙箱中页面可参考我的另一篇文章&#xff1a;【HarmonyOS NEXT】 如何将rawfile中文件复制到沙箱中_鸿蒙rawfile 复制到沙箱-CSDN博客 目录 如何在鸿蒙应用中加…