日撸java三百行day61-62

news2024/11/23 8:56:55

文章目录

  • 说明
  • Day61 决策树
    • 1.什么是决策树
    • 2.什么是熵
    • 3.什么是信息增益
    • 4.详细例子
      • 1. weather样本
      • 2.第一次决策
      • 3.第二次决策
      • 4.最终决策树
    • 4. 代码理解
      • 4.1 变量理解
      • 4.2 代码中主要方法理解

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

Day61 决策树

结合老师的文章去理解决策树中的一种决策算法:ID3算法

1.什么是决策树

决策树是一种基于树型结构的机器学习算法,叶子结点表示一个类别(即预测值),非叶结点表示特征。这篇文章构建决策树采用的是ID3算法,主要是根据信息增益(或条件信息熵)来划分特征。

2.什么是熵

在决策树中,熵是一种衡量数据集纯度或混乱度的指标。熵的值越高,表示数据集的混乱程度越高; 熵的值越低,表示数据集的纯度越高。(具体知识可网上查阅)

  • 熵计算公式:
    H ( X ) = − ∑ i n p ( x i ) l o g p ( x i ) H(X)=-\sum_{i}^{n}p(x_{i})logp(x_{i}) H(X)=inp(xi)logp(xi)

  • 条件熵的计算公式
    H ( Y ∣ X ) = − ∑ i n p ( x ) H ( Y ∣ X = x ) H(Y|X)=-\sum_{i}^{n}p(x)H(Y|X=x) H(YX)=inp(x)H(YX=x)

3.什么是信息增益

熵是衡量数据集的不确定性的度量,而条件熵是在已知某个属性的条件下,数据集的不确定性。信息增益表示使用某个特征进行划分后,整个数据集的熵减少的程度,即通过划分所获得的信息量。信息增益越大,表示使用特征 A A A进行划分后,数据集的确定性更高, 特征A对训练数据集D的信息增益g(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)

4.详细例子

这个例子计算主要是结合了文章中的代码思路来的。

1. weather样本

在这里插入图片描述

2.第一次决策

计算每个特征值的条件熵,筛选最优的特征作为根结点。
在这里插入图片描述
计算Outlook 他每个属性的熵:
H ( p l a y ∣ O u t l o o k = S u n n y ) = − 3 5 log ⁡ 3 5 − 2 5 log ⁡ 2 5 = 0.6730 H(play|Outlook = Sunny)=-\frac{3}{5}\log \frac{3}{5}-\frac{2}{5}\log \frac{2}{5}=0.6730 H(playOutlook=Sunny)=53log5352log52=0.6730
H ( p l a y ∣ O u t l o o k = O v e r c a s t ) = − 0 log ⁡ 0 − 1 log ⁡ 1 = 0.0 H(play|Outlook = Overcast)=-0\log 0-1\log1=0.0 H(playOutlook=Overcast)=0log01log1=0.0
H ( p l a y ∣ O u t l o o k = R a i n ) = − 2 5 log ⁡ 2 5 − 3 5 log ⁡ 3 5 = 0.6730 H(play|Outlook = Rain)=-\frac{2}{5}\log \frac{2}{5}-\frac{3}{5}\log \frac{3}{5}=0.6730 H(playOutlook=Rain)=52log5253log53=0.6730
计算Outlook 的条件熵:
H ( p l a y ∣ O u t l o o k ) = − 5 14 ∗ 0.6730 − 4 14 ∗ 0.0 − 5 14 ∗ 0.6730 = 0.4807 H(play|Outlook)=-\frac{5}{14}*0.6730 -\frac{4}{14}*0.0-\frac{5}{14}*0.6730 = 0.4807 H(playOutlook)=1450.67301440.01450.6730=0.4807

在这里插入图片描述
计算Temperature他每个属性的熵:
H ( p l a y ∣ T e m p e r a t u r e = H o t ) = − 2 4 log ⁡ 2 4 − 2 4 log ⁡ 2 4 = 0.6931 H(play|Temperature= Hot)=-\frac{2}{4}\log \frac{2}{4}-\frac{2}{4}\log \frac{2}{4}=0.6931 H(playTemperature=Hot)=42log4242log42=0.6931
H ( p l a y ∣ T e m p e r a t u r e = M i l d ) = − 2 6 log ⁡ 2 6 − 4 6 log ⁡ 4 6 = 0.6365 H(play|Temperature= Mild)=-\frac{2}{6}\log \frac{2}{6}-\frac{4}{6}\log \frac{4}{6}=0.6365 H(playTemperature=Mild)=62log6264log64=0.6365
H ( p l a y ∣ T e m p e r a t u r e = C o o l ) = − 1 4 log ⁡ 1 4 − 3 4 log ⁡ 3 4 = 0.5623 H(play|Temperature= Cool)=-\frac{1}{4}\log \frac{1}{4}-\frac{3}{4}\log \frac{3}{4}=0.5623 H(playTemperature=Cool)=41log4143log43=0.5623
计算Temperature的条件熵:
H ( p l a y ∣ T e m p e r a t u r e ) = − 4 14 ∗ 0.6730 − 6 14 ∗ 0.0 − 4 14 ∗ 0.6730 = 0.6315 H(play|Temperature)=-\frac{4}{14}*0.6730 -\frac{6}{14}*0.0-\frac{4}{14}*0.6730 = 0.6315 H(playTemperature)=1440.67301460.01440.6730=0.6315
同理可得Humidity和Windy的条件熵:
H ( p l a y ∣ H u m i d i t y ) = 0.5465 H(play|Humidity)=0.5465 H(playHumidity)=0.5465
H ( p l a y ∣ W i n d y ) = 0.6183 H(play|Windy)=0.6183 H(playWindy)=0.6183
所以在第一轮的决策中,我们根据最大化信息增益, 与最小化条件信息熵,选择条件熵最小的Outlook作为决策的根结点进行分裂。
在这里插入图片描述

3.第二次决策

我们在第一次决策后,分了三个分支,他的子问题和原问题一样的,又进行递归建树

  • Outlook-Sunny结点

    • Temperature
      H ( p l a y ∣ T e m p e r a t u r e = H o t ) = − 0 log ⁡ 0 − 1 log ⁡ 1 = 0.0 H(play|Temperature= Hot)=-0\log 0-1\log 1=0.0 H(playTemperature=Hot)=0log01log1=0.0
      H ( p l a y ∣ T e m p e r a t u r e = M i l d ) = − 1 2 log ⁡ 1 2 − 1 2 log ⁡ 1 2 = 0.6931 H(play|Temperature= Mild)=-\frac{1}{2}\log \frac{1}{2}-\frac{1}{2}\log \frac{1}{2}=0.6931 H(playTemperature=Mild)=21log2121log21=0.6931
      H ( p l a y ∣ T e m p e r a t u r e = C o o l ) = − 0 log ⁡ 0 − 1 log ⁡ 1 = 0.0 H(play|Temperature= Cool)=-0\log 0-1\log 1=0.0 H(playTemperature=Cool)=0log01log1=0.0
      H ( p l a y ∣ T e m p e r a t u r e ) = − 2 5 ∗ 0.0 − 2 5 ∗ 0.6931 − 1 5 ∗ 0.0 = 0.2772 H(play|Temperature)=-\frac{2}{5}*0.0 -\frac{2}{5}*0.6931-\frac{1}{5}*0.0 = 0.2772 H(playTemperature)=520.0520.6931510.0=0.2772
    • Humidity
      H ( p l a y ∣ H u m i d i t y ) = 0.0 H(play|Humidity)=0.0 H(playHumidity)=0.0
    • Windy
      H ( p l a y ∣ W i n d y ) = 0.6591 H(play|Windy)=0.6591 H(playWindy)=0.6591
      选择条件熵最小的Humidity作为决策进行分裂,然后再往里面递归
  • Outlook-Overcast结点
    在Overcast结点熵所有的play都是P,说明他的数据很纯,不用分裂了。

  • Outlook-Rain结点同理可得。
    至于进一步的递归如上面一样

4.最终决策树

在这里插入图片描述

4. 代码理解

4.1 变量理解

在代码的实现中,很多存储都是利用的数据存储的索引,而不是存具体的数据,这样不仅减少空间开销,还减小了逻辑的复杂度。

  • numClasses; availableInstances; availableAttributes
    通过这张图就基本可以理解这三个变量主要存储的值是那些

在这里插入图片描述

  • splitAttribute,ID3[] children
    即每次建树时,选择那个特征值作为来进行划分子集。例如splitAttribute=0,代表选择Outlook来划分子集

在这里插入图片描述

  • label
    基于规定的数据集,判断数据集中出现类别最多的值赋值给lable。
    如下规定的5个数据集中,N出现最多则label赋值为N的索引值。

在这里插入图片描述

4.2 代码中主要方法理解

如果能自己去手动模拟一次,代码就很好理解。如果去计算过一遍在ID3算法中,buildTree()方法是算法核心。

 public void buildTree() {
        //判断实例索引
        if (pureJudge(availableInstances)) {
            return;
        }
        if (availableInstances.length <= smallBlockThreshold) {
            return;
        }

        //划分孩子
        selectBestAttribute();
        int[][] tempSubBlocks = splitData(splitAttribute);
        children = new ID3[tempSubBlocks.length];

        // Construct the remaining attribute set.
        int[] tempRemainingAttributes = new int[availableAttributes.length - 1];
        for (int i = 0; i < availableAttributes.length; i++) {
            if (availableAttributes[i] < splitAttribute) {
                tempRemainingAttributes[i] = availableAttributes[i];
            } else if (availableAttributes[i] > splitAttribute) {
                tempRemainingAttributes[i - 1] = availableAttributes[i];
            }
        }

        // Construct children.
        for (int i = 0; i < children.length; i++) {
            if ((tempSubBlocks[i] == null) || (tempSubBlocks[i].length == 0)) {
                children[i] = null;
                continue;
            } else {
                // System.out.println("Building children #" + i + " with
                // instances " + Arrays.toString(tempSubBlocks[i]));
                children[i] = new ID3(dataset, tempSubBlocks[i], tempRemainingAttributes);

                // Important code: do this recursively
                children[i].buildTree();
            }
        }
    }

  • 调用pureJudge方法 判断他们的类别是否够纯,若类别都是一样的,则直接返回;反之跳过。
    例如availableInstances目前传入的是weather样本中14个实例,很明显play有N,有P,直接跳过。

在这里插入图片描述

  • 判断我们在建树的实例是否小于smallBlockThreshold,若小于这个树,划分出来的结果不一定好,反而会适得其反。(避免过拟合)
  • 调用selectBestAttribute方法。这个方法就是在每次建树时选择(可选的特征值中熵最小的)。conditionalEntropy方法就是计算每个特征值的条件信息熵,具体的算法就是上面的公式。(我觉得这个方法是核心)
  • 调用splitData方法。根据选择最小的特征值作为根结点划分子集。
  • buildTree方法中第一个for循环是去掉已经被选择的特征值
  • buildTree方法中第二个for循环是开始递归建树啦,在递归时构建ID3对象时,我们可以当作是要重新构建一颗新(子)树,传参方式有变化,是因为paraAvailableInstances, paraAvailableAttributes我们设置为成员变量,他的作用域是整个类都可用,如不更新则会导致数据出错。
 /**
     * Select the best attribute.
     * @return The best attribute index.
     */
    public int selectBestAttribute() {
        splitAttribute = -1;
        double tempMinimalEntropy = 10000;
        double tempEntropy;
        //循环遍历每个特征值,计算其条件熵
        for (int i = 0; i < availableAttributes.length; i++) {
            tempEntropy = conditionalEntropy(availableAttributes[i]);
            if (tempMinimalEntropy > tempEntropy) {
                tempMinimalEntropy = tempEntropy;
                splitAttribute = availableAttributes[i];
            }
        }
        return splitAttribute;
    }

    /**
     * Compute the conditional entropy of an attribute.
     * @param paraAttribute The given attribute
     * @return The entropy.
     */
    public double conditionalEntropy(int paraAttribute) {
        // Step 1. Statistics.
        int tempNumClasses = dataset.numClasses();
        int tempNumValues = dataset.attribute(paraAttribute).numValues();
        int tempNumInstances = availableInstances.length;
        double[] tempValueCounts = new double[tempNumValues];
        double[][] tempCountMatrix = new double[tempNumValues][tempNumClasses];

        int tempClass, tempValue;
        for (int i = 0; i < tempNumInstances; i++) {
            tempClass = (int) dataset.instance(availableInstances[i]).classValue();
            tempValue = (int) dataset.instance(availableInstances[i]).value(paraAttribute);
            tempValueCounts[tempValue]++;
            tempCountMatrix[tempValue][tempClass]++;
        }

        // Step 2.
        double resultEntropy = 0;
        double tempEntropy, tempFraction;
        for (int i = 0; i < tempNumValues; i++) {
            if (tempValueCounts[i] == 0) {
                continue;
            }
            tempEntropy = 0;
            for (int j = 0; j < tempNumClasses; j++) {
                tempFraction = tempCountMatrix[i][j] / tempValueCounts[i];
                if (tempFraction == 0) {
                    continue;
                }
                double entropy  = -tempFraction * Math.log(tempFraction);
                tempEntropy += entropy;
            }
            double  resultEntropyTest =  tempValueCounts[i] / tempNumInstances * tempEntropy;
            resultEntropy += resultEntropyTest;
        }

        return resultEntropy;
    }

运行结果:
在这里插入图片描述

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

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

相关文章

深入源码分析RecyclerView缓存复用原理

文章目录 前言四级缓存 源码分析缓存一级缓存&#xff08;mChangedScrap和mChangedScrap&#xff09;二级缓存&#xff08;mCachedViews&#xff09;三级缓存四级缓存&#xff08;mRecyclerPool&#xff09;缓存池mRecyclerPool结构理解四级缓存简单小结 缓存流程图 复用复用流…

分布式项目15 用户注册,单点登陆dubbo来实现

分析&#xff1a;当用户填写完成注册信息之后,将请求发送给前台服务器.之后前台消费者利用dubbo框架实现RPC调用。之后将用户信息传递给jt-sso服务提供者.之后完成数据的入库操作。 01.页面url分析 02.查看页面JS $.ajax({ type : "POST", url : "/user/doRe…

MMPose安装及推理验证

MMPose安装 依赖环境 1.创建虚拟环境并激活 conda create --name openmmlab python3.8 -y conda activate openmmlab2.安装pytorch conda install pytorch torchvision torchaudio pytorch-cuda11.7 -c pytorch -c nvidia报错&#xff1a; InvalidArchiveError(‘Error wit…

quartus下联合modelsim_Altera仿真

vivado工程转换到quartus下联合modelsim仿真_内有小猪卖的博客-CSDN博客 这个博客是用单独的modelsim仿真&#xff0c;而下面的流程是使用quartus自带的modelsim-altera仿真。 版本为&#xff1a;quartus ii 13.1 64-bit 以fpga实现数码管和流水灯编码为例。数码管为1时&#x…

Spring中Bean加载流程

上面是跟踪了 getBean 的调用链创建的流程图&#xff0c;为了能够很好地理解 Bean 加载流程&#xff0c;省略一些异常、日志和分支处理和一些特殊条件的判断。 从上面的流程图中&#xff0c;可以看到一个 Bean 加载会经历这么几个阶段&#xff08;用绿色标记&#xff09;&…

机器学习算法分类(三)

在机器学习中&#xff0c;又分为监督学习、无监督学习、半监督学习、强化学习和深度学习。 监督、无监督、半监督学习 机器学习根据数据集是否有标签&#xff0c;又分为监督学习、无监督学习、半监督学习。 监督学习&#xff1a;训练数据集全部都有标签无监督学习&#xff1a…

grep命令的使用

grep命令是Linux中常用的文本搜索工具&#xff0c;它可以根据用户指定的模式&#xff0c;在文件或标准输入中查找匹配的文本行并返回。 下面是grep命令的一些常见选项&#xff1a; -i&#xff1a;忽略大小写-n&#xff1a;显示匹配行的行号-v&#xff1a;显示不匹配的行-r&am…

【新版】系统架构设计师 - 计算机系统基础知识

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 计算机系统基础知识考点摘要计算机系统计算机硬件组成浮点数Flynn分类法CISC与RISC流水线技术超标量流水线存储系统层次化存储结构CacheCache的命中率Cache的页面淘汰主存编址磁盘管理&#xff08…

《MySQL(四):基础篇- 约束》

文章目录 4. 约束4.1 概述4.2 约束演示4.3 外键约束4.3.1 介绍4.3.2 语法4.3.3 删除/更新行为 4. 约束 4.1 概述 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 目的&#xff1a;保证数据库中数据的正确、有效性和完整性。 分类: 约…

YOLOv5白皮书-第Y6周:模型改进

目录 一、改进网络结构设计1 改进的注意力机制2 多尺度特征融合3 改进的激活函数 二 数据增强和数据平衡1 数据增强2 数据平衡3 注意事项 三、模型融合策略1 投票策略2 加权平均策略3 特征融合策略4 其他模型融合策略 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中…

protobuf实现原理

文章目录 一、前言二、概述三、数据存储方式&#xff1a;Varints(一)原理(二)举例(三)缺点 四、协议的数据结构(一)原理(二)举例 一、前言 最近刚刚从一家公司离职&#xff0c;在职的时候使用到了go语言的grpc库&#xff0c;了解了除了json之外的另一个专门用于远程调用的序列…

二本计算机专业学长经验之谈

2023.6.9 今年的行情对我们这些双非大学、二本真的太难了&#xff0c;菜鸟今年感觉毕业找的工作真的又苦逼钱又少&#xff0c;准备跳槽的&#xff0c;结果满大街投简历&#xff0c;连个毛都没有&#xff0c;唯一一个给了个海笔&#xff0c;然后就没然后… 所以希望大家真的要好…

Element的Select分组全选模式

Select 选择器选择器的分组&#xff0c;如上图所示&#xff0c;我们希望做到的效果是&#xff0c;点击“热门城市”或“城市名”的时候全选分组的options。 思路 思路一&#xff1a;目前的Select 选择器分组OptionGroup的Title只是一个文本DOM&#xff0c;没用其他东西&#…

详解基于罗德里格斯(Rodrigues)公式由旋转向量到旋转矩阵的 Python 实现

文章目录 旋转向量 rotation vector旋转矩阵 rotation matrix罗德里格斯公式 Rodrigues formula基于 Python 和 NumPy 实现 Rodrigues 公式 旋转向量 rotation vector 任何一个旋转都可以通过一个 旋转轴 加一个 旋转角 进行描述, 即围绕 旋转轴 旋转一个 旋转角. 此时可以通过…

javascript 中的 URL 解码

文章目录 需要URL编解码JavaScript 中的 URL 解码使用 unescaped() 方法解码编码的 URL使用 decodeURI() 方法解码编码的 URL使用 decodeURIComponent() 方法解码编码的 URL 总结 本文着眼于 URL 解码以及如何使用 JavaScript 对编码的 URL 进行解码。 需要URL编解码 URL 应具…

政企HTTPS加密国产化替代的四要素

信创产业是数字经济、信息安全发展的基础&#xff0c;也是“新基建”的重要内容&#xff0c;将成为拉动中国经济增长的重要抓手之一。随着国资委79号文的发布&#xff0c;国央企落实信息化系统的信创国产化改造的步伐加快&#xff0c;贯彻“28N”战略&#xff0c;从党政机关扩展…

Doris学习笔记

1.数据模型 数据模型 - Apache Doris 1.1 Aggregate 模型(聚合&#xff09; 可以发现&#xff0c;user_id、date、age ...等没有设置 AggregationType, 那么这几个字段就成了一个key了。设置了 AggregationType 字段&#xff0c;说明该列的属性已经成value了。 我们导入一张…

Linux·Binder机制原理

目录 前言 目录 1. Binder到底是什么&#xff1f; 2. 知识储备 2.1 进程空间划分 2.2 进程隔离 & 跨进程通信&#xff08; IPC &#xff09; 2.5 内存映射 3. Binder 跨进程通信机制 模型 3.1 模型原理图 3.3 模型原理步骤说明 3.4 额外说明 4. Binder机制 在An…

自学黑客(网络安全),一般人我劝你还是算了

写在开篇 笔者本人 17 年就读于一所普通的本科学校&#xff0c;20 年 6 月在三年经验的时候顺利通过校招实习面试进入大厂&#xff0c;现就职于某大厂安全联合实验室。 我为啥说自学黑客&#xff0c;一般人我还是劝你算了吧&#xff01;因为我就是那个不一般的人。 ​ 首先我…

elementui tree 支持虚拟滚动和treeLine (下)

​ 由于我之前没有发布过npm 包&#xff0c;这里还得现学一下。 参考资料&#xff1a; 链接: 如何写一个vue组件发布到npm&#xff0c;包教包会&#xff0c;保姆级教学链接: vue组件发布npm最佳实践 按照上面的步骤&#xff0c;我通过 vue-sfc-rollup 生成了项目&#xff0c;…