决策树(Decison Tree)—有监督学习方法、概率模型、生成模型、非线性模型、非参数化模型、批量学习

定义

ID3算法
输入:训练数据集(T= { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } \left\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\right\} {(x1,y1),(x2,y2),,(xN,yN)}),特征集A阀值 ε \varepsilon ε

输出:决策树T

(1)若D中所有实例属于同一类 C k C_k Ck,则T为单节点树,并将 C k C_k Ck作为该节点的类标记,返回T;

(2)若A= ∅ \varnothing ,则T为单节点树,并将D中实例数最大的类 C k C_k Ck作为该节点的类标记,返回T;

(3)否则,需要计算A中各特征对D的信息增益,选择信息增益最大的特征 A g A_g Ag

(4)如果 A g A_g Ag的信息增益小于阀值 ε \varepsilon ε,则置T为单节点树,并将D中实例数最大的类 C k C_k Ck作为该节点的类标记,返回T;

(5)否则,对 A g A_g Ag的每一可能值 a i a_i ai,依 A g = a i A_g=a_i Ag=ai将D分割为若干非空子集 D i D_i Di,将 D i D_i Di中实例最大的类作为标记,构建子节点,由节点及其子节点构成树T,返回T;

(6)对第i个字节点,以 D i D_i Di为训练集,以 A − A g A-{A_g} AAg为特征集,递归地调用步骤(1)~(5),得到子树 T i T_i Ti,返回 T i T_i Ti

输入空间

T= { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } \left\{(x_1,y_1),(x_2,y_2),\dots,(x_N,y_N)\right\} {(x1,y1),(x2,y2),,(xN,yN)}

import numpy as npdef loadData(fileName,lines=60000):'''加载文件:param fileName:要加载的文件路径 下载地址:https://download.csdn.net/download/nanxiaotao/89720991):return: 数据集和标签集'''#存放数据及标记dataArr = []; labelArr = []#读取文件fr = open(fileName)#遍历文件中的每一行for line in fr.readlines():curLine = line.strip().split(',')dataArr.append([int(int(num) > 128) for num in curLine[1:]])labelArr.append(int(curLine[0]))#返回数据集和标记return dataArr, labelArr
# 获取训练集
trainDataList, trainLabelList = loadData('../Mnist/mnist_train.csv')
np.shape(trainDataList)
Epsilon = 0.1

特征空间(Feature Space)

trainDataList[0][0:784]

统计学习方法

模型

决策树 T T T

策略

m a x ( g ( D , A ) ) max(g(D,A)) max(g(D,A))

算法

H ( D ) = − ∑ k = 1 K ∣ C k ∣ ∣ D ∣ l o g 2 ∣ C k ∣ ∣ D ∣ H(D)=-\sum_{k=1}^K \dfrac{ \left| C_k \right| }{ \left| D \right|}log_2 \dfrac{ \left| C_k \right| }{ \left| D \right|} H(D)=k=1KDCklog2DCk

def calc_H_D(trainLabelArr):'''计算数据集D的经验熵:param trainLabelArr:当前数据集的标签集:return: 经验熵'''#初始化为0H_D = 0trainLabelSet = set([label for label in trainLabelArr])#遍历每一个出现过的标签for i in trainLabelSet:p = trainLabelArr[trainLabelArr == i].size / trainLabelArr.size#对经验熵的每一项累加求和H_D += -1 * p * np.log2(p)#返回经验熵return H_D

H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H ( D i ) H(D|A)=\sum_{i=1}^n \dfrac{ \left| D_i \right| }{ \left| D \right|}H(D_i) H(DA)=i=1nDDiH(Di)

def calcH_D_A(trainDataArr_DevFeature, trainLabelArr):'''计算经验条件熵:param trainDataArr_DevFeature:切割后只有feature那列数据的数组:param trainLabelArr: 标签集数组:return: 经验条件熵'''#初始为0H_D_A = 0#在featue那列放入集合中,是为了根据集合中的数目知道该feature目前可取值数目是多少trainDataSet = set([label for label in trainDataArr_DevFeature])#对于每一个特征取值遍历计算条件经验熵的每一项for i in trainDataSet:#计算H(D|A)#trainDataArr_DevFeature[trainDataArr_DevFeature == i].size / trainDataArr_DevFeature.size:|Di| / |D|#calc_H_D(trainLabelArr[trainDataArr_DevFeature == i]):H(Di)H_D_A += trainDataArr_DevFeature[trainDataArr_DevFeature == i].size / trainDataArr_DevFeature.size \* calc_H_D(trainLabelArr[trainDataArr_DevFeature == i])#返回得出的条件经验熵return H_D_A

g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)H(DA)

m a x ( g ( D , A ) ) max(g(D,A)) max(g(D,A))

def majorClass(labelArr):'''找到当前标签集中占数目最大的标签:param labelArr: 标签集:return: 最大的标签'''#建立字典,用于不同类别的标签技术classDict = {}#遍历所有标签for i in range(len(labelArr)):if labelArr[i] in classDict.keys():# 若在字典中存在该标签,则直接加1classDict[labelArr[i]] += 1else:#若无该标签,设初值为1,表示出现了1次了classDict[labelArr[i]] = 1#对字典依据值进行降序排序classSort = sorted(classDict.items(), key=lambda x: x[1], reverse=True)#返回最大一项的标签,即占数目最多的标签return classSort[0][0]
def getSubDataArr(trainDataArr, trainLabelArr, A, a):'''更新数据集和标签集:param trainDataArr:要更新的数据集:param trainLabelArr: 要更新的标签集:param A: 要去除的特征索引:param a: 当data[A]== a时,说明该行样本时要保留的:return: 新的数据集和标签集'''#返回的数据集retDataArr = []#返回的标签集retLabelArr = []#对当前数据的每一个样本进行遍历for i in range(len(trainDataArr)):#如果当前样本的特征为指定特征值aif trainDataArr[i][A] == a:#那么将该样本的第A个特征切割掉,放入返回的数据集中retDataArr.append(trainDataArr[i][0:A] + trainDataArr[i][A+1:])#将该样本的标签放入返回标签集中retLabelArr.append(trainLabelArr[i])#返回新的数据集和标签集return retDataArr, retLabelArr
def calcBestFeature(trainDataList, trainLabelList):'''计算信息增益最大的特征:param train_dataSet: 数据集:return: 信息增益最大的特征及最大信息增益值'''#将数据集和标签集转换为数组形式trainDataArr = np.array(trainDataList)trainLabelArr = np.array(trainLabelList)#获取当前特征数目,也就是数据集的横轴大小featureNum = trainDataArr.shape[1]#初始化最大信息增益maxG_D_A = -1#初始化最大信息增益的特征maxFeature = -1#1.计算数据集D的经验熵H(D)H_D = calc_H_D(trainLabelArr)#对每一个特征进行遍历计算for feature in range(featureNum):trainDataArr_DevideByFeature = np.array(trainDataArr[:, feature].flat)#计算信息增益G_D_A = H_D - calcH_D_A(trainDataArr_DevideByFeature, trainLabelArr)#不断更新最大的信息增益以及对应的featureif G_D_A > maxG_D_A:maxG_D_A = G_D_AmaxFeature = featurereturn maxFeature, maxG_D_A

创建决策树 T T T

def createTree(*dataSet):'''递归创建决策树:param dataSet:return:新的子节点或该叶子节点的值'''trainDataList = dataSet[0][0]trainLabelList = dataSet[0][1]classDict = {i for i in trainLabelList}if len(classDict) == 1:return trainLabelList[0]if len(trainDataList[0]) == 0:#返回当前标签集中占数目最大的标签return majorClass(trainLabelList)Ag, EpsilonGet = calcBestFeature(trainDataList, trainLabelList)#如果Ag的信息增益比小于阈值Epsilon,则置T为单节点树,并将D中实例数最大的类Ck#作为该节点的类,返回Tif EpsilonGet < Epsilon:return majorClass(trainLabelList)#否则,对Ag的每一可能值ai,依Ag=ai将D分割为若干非空子集Di,将Di中实例数最大的# 类作为标记,构建子节点,由节点及其子节点构成树T,返回TtreeDict = {Ag:{}}#特征值为0时,进入0分支#getSubDataArr(trainDataList, trainLabelList, Ag, 0):在当前数据集中切割当前feature,返回新的数据集和标签集treeDict[Ag][0] = createTree(getSubDataArr(trainDataList, trainLabelList, Ag, 0))treeDict[Ag][1] = createTree(getSubDataArr(trainDataList, trainLabelList, Ag, 1))return treeDict
# 获取测试集
testDataList, testLabelList = loadData('../Mnist/mnist_test.csv')#创建决策树
tree = createTree((trainDataList, trainLabelList))
print('tree is:', tree)

假设空间(Hypothesis Space)

{ f ∣ f ( x ) = m a x ( g ( D , A ) ) } \left\{f|f(x) = max(g(D,A)) \right\} {ff(x)=max(g(D,A))}

输出空间

y {\tt y} y = { c 1 , c 2 , ⋯ , c k } = \{c_1,c_2,\cdots,c_k \} ={c1,c2,,ck}

模型评估

训练误差(Training Error)

testDataList, testLabelList = loadData('../Mnist/mnist_test.csv')
np.shape(testDataList)
def predict(testDataList, tree):'''预测标签:param testDataList:样本:param tree: 决策树:return: 预测结果'''while True:(key, value), = tree.items()#如果当前的value是字典,说明还需要遍历下去if type(tree[key]).__name__ == 'dict':dataVal = testDataList[key]del testDataList[key]tree = value[dataVal]if type(tree).__name__ == 'int':#返回该节点值,也就是分类值return treeelse:#如果当前value不是字典,那就返回分类值return value
def model_test(testDataList, testLabelList, tree):'''测试准确率:param testDataList:待测试数据集:param testLabelList: 待测试标签集:param tree: 训练集生成的树:return: 准确率'''errorCnt = 0for i in range(len(testDataList)):if testLabelList[i] != predict(testDataList[i], tree):errorCnt += 1#返回准确率return 1 - errorCnt / len(testDataList)
accur = model_test(testDataList, testLabelList, tree)
print('the accur is:', accur)

测试误差(Test Error)

模型选择

过拟合

正则化

泛化能力

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

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

相关文章

Java代码审计篇 | ofcms系统审计思路讲解 - 篇1 | 环境搭建、路由机制

文章目录 Java代码审计篇 | ofcms系统审计思路讲解 - 篇1 | 环境搭建、路由机制1. 前言2. 项目环境搭建3. 项目路由机制3.1. 1&#xff09;先搜索pom.xml文件&#xff0c;看看使用了什么框架3.2. 2&#xff09;确定是否是spring的路由机制3.3. 3&#xff09;确定自写路由机制的…

golang学习笔记05——golang协程池,怎么实现协程池?

推荐学习文档 golang实战大纲golang优秀开发常用开源库汇总golang学习笔记01——基本数据类型golang学习笔记02——gin框架及基本原理golang学习笔记03——gin框架的核心数据结构golang学习笔记04——如何真正写好Golang代码&#xff1f; 协程池是一种用于高效处理任务的机制&…

面试—JavaSE

目录 面向对象三大特征 重载和重写的区别 final和static修饰符 接口和抽象类的区别 String、StringBuilder、StringBuffer的区别 面向对象三大特征 封装、继承、多态 封装 将对象的属性和方法放入到一个类中&#xff0c;通过访问修饰符来控制对类的访问权限 继承 继承是…

【ruby java】登陆功能/邮件发送模版240903

Rails 风格登录系统添加全面而详细的注释&#xff0c;解释每个部分的功能和用途。​​​​​​​​​ 详细注释&#xff0c;解释了每个文件和代码块的功能。以下是一些关键点的总结&#xff1a; 1. 控制器&#xff08;Controllers&#xff09;: - ApplicationController: …

苏茵茵:以时尚之名,诠释品质生活

在女性追求个性化与自我表达的今天&#xff0c;时尚早已超越了简单的穿着打扮&#xff0c;它成为女性展现自我风格、彰显独特魅力的重要方式。从广泛的兴趣爱好到精心雕琢的个人风格&#xff0c;每一处细节都闪耀着女性对个性独特与自我表达的深切渴望。正是这股不可阻挡的潮流…

强化学习指南:训练过程与评估过程的区别

强化学习指南&#xff1a;训练过程与评估过程的区别 在强化学习&#xff08;RL&#xff09;中&#xff0c;训练和评估是两个截然不同但密切相关的过程。本指南将详细解释这两个过程的区别&#xff0c;以及如何正确实施它们。 1. 训练过程 训练是RL中最核心的部分&#xff0c…

Java 中常用内置接口函数

在 Java 8 及以后的版本中&#xff0c;引入了许多函数式编程的特性&#xff0c;其中最重要的就是内置的函数式接口。这些接口使得编写更简洁、可读性更强的代码成为可能。今天我将介绍四个常用的内置接口&#xff1a;Predicate、Function、Consumer 和 Supplier&#xff0c;并提…

static 变量和 static 函数各有什么特点?

static 关键字在 C、C 等编程语言中用于指定变量和函数的存储类型和可见性&#xff0c;其特点如下&#xff1a; static 变量 作用域&#xff1a; 局部静态变量&#xff1a;在函数内部声明&#xff0c;作用域限制在该函数内&#xff0c;但其生命周期贯穿程序整个运行过程。它只…

关于schneider施耐德140模块

SCHNEIDER 140模块是施耐德电气&#xff08;Schneider Electric&#xff09;公司生产的一系列工业自动化和控制产品&#xff0c;这些模块通常用于Quantum系列PLC&#xff08;可编程逻辑控制器&#xff09;系统中&#xff0c;以实现各种自动化和控制任务。以下是对SCHNEIDER 140…

2024.9.9 Python,有效的括号,三数之和,回溯算法解决括号生成

1.有效的括号 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。…

使用Protocol Buffers传输数据

使用 Google Protocol Buffers&#xff08;ProtoBuf&#xff09;与 Kafka 结合来定义和传输数据&#xff0c;可以确保传输数据的结构性、可扩展性和高效性。以下是一个简单的步骤指南&#xff0c;帮助你实现生产者和消费者。 1. 定义 ProtoBuf 消息格式 首先&#xff0c;你需…

笔记整理—内核!启动!—kernel部分(3)init进程—进程1

内核态下干了什么——构建内核。 在init进程中&#xff0c;一个进程有两种状态。1为内核态&#xff0c;init属于内核进程。2.用户态&#xff0c;自己将init转为用户态。从进程1之后的进程就都可以工作在用户态。 内核态中重点干了一件事情&#xff0c;挂载rootfs&#xff0c;找…

ffmpeg 视频编码及基本知识

理论 H264编码原理&#xff08;简略&#xff09; 1. 视频为什么需要进行编码压缩 降低视频数据大小&#xff0c;方便存储和传输 2. 为什么压缩的原始数据采用YUV格式 彩色图像的格式是 RGB 的&#xff0c;但RGB 三个颜色是有相关性的。 采用YUV格式&#xff0c;利用人对图像的…

【C语言必学知识点七】什么?还有人不知道什么是柔性数组?还不速来!!!

动态内存管理——详细解读柔性数组 导读一、什么是柔性数组二、柔性数组的特点三、柔性数组的使用四、柔性数组的优势结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们介绍了C/C程序中的内存分区&#xff0c;在C/C…

C++11 --- 可变参数模板

序言 不知道大家有没有细细研究过在 C 语言 中的 printf 函数&#xff0c;也许我们经常使用他&#xff0c;但是我们可能并不是那么了解他。先看一下调用格式&#xff1a;int printf ( const char * format, ... );&#xff0c;在这里的 format 代表我们的输出格式&#xff0c;后…

欧拉下搭建第三方软件仓库—docker

1.创建新的文件内容 切换目录到etc底下的yum.repos.d目录&#xff0c;创建docker-ce.repo文件 [rootlocalhost yum.repos.d]# cd /etc/yum.repos.d/ [rootlocalhost yum.repos.d]# vim docker-ce.repo 编辑文件,使用阿里源镜像源&#xff0c;镜像源在编辑中需要单独复制 h…

华为防火墙 nat64

如果设备接收到的IPv6报文的前缀是设备为NAT64定义的前缀&#xff0c;说明报文的目的地址是IPv4网络&#xff0c;报文将经过NAT64处理后被转发至IPv4网络。 如果设备接收到的IPv6报文的前缀不是设备为NAT64定义的前缀&#xff0c;说明报文的目的地址是IPv6网络&#xff0c;报文…

java直接实例化对象和使用接口实例化对象之间的区别(java小知识点)

文章目录 1.定义一个MyClass类和一个 MyInterface接口2.具体使用场景3.如何调用 MyClass 自己的特有方法&#xff1f;4.总结 1.定义一个MyClass类和一个 MyInterface接口 public interface MyInterface {void doSomething(); // 权限修饰符默认是public }public class MyClass…

设计模式 | 单例模式

定义 单例设计模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。这种模式常用于需要控制对某些资源的访问的场景&#xff0c;例如数据库连接、日志记录等。 单例模式涉…

网站钓鱼——挂马技术手段介绍

更多网安实战内容&#xff0c;可前往无问社区查看http://wwlib.cn/index.php/artread/artid/10194.html 网站挂马目前已经成为流氓软件以及红队人员快速获取目标主机权限的常用手段之一&#xff0c;在长时间的实战中也是出现了层出不穷的钓鱼方法&#xff0c;这次分享一下实际…