决策树算法例题_决策树算法比较

决策树算法例题_决策树算法比较上一节介绍了决策树的一些基本概念,诸如树的基本结构,信息熵等。这次就用一个例子,来看看ID3决策树的具体运行过程吧~~

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前情提要:
通俗地说决策树算法(一)基础概念介绍

一. 概述

上一节,我们介绍了决策树的一些基本概念,包括树的基本知识以及信息熵的相关内容,那么这次,我们就通过一个例子,来具体展示决策树的工作原理,以及信息熵在其中承担的角色。

有一点得先说一下,决策树在优化过程中,有3个经典的算法,分别是ID3,C4.5,和CART。后面的算法都是基于前面算法的一些不足进行改进的,我们这次就先讲ID3算法,后面会再说说它的不足与改进。

二. 一个例子

众所周知,早上要不要赖床是一个很深刻的问题。它取决于多个变量,下面就让我们看看小明的赖床习惯吧。

季节 时间已过 8 点 风力情况 要不要赖床
spring no breeze yes
winter no no wind yes
autumn yes breeze yes
winter no no wind yes
summer no breeze yes
winter yes breeze yes
winter no gale yes
winter no no wind yes
spring yes no wind no
summer yes gale no
summer no gale no
autumn yes breeze no

OK,我们随机抽了一年中14天小明的赖床情况。现在我们可以根据这些数据来构建一颗决策树。

可以发现,数据中有三个属性会影响到最终的结果,分别是,季节,时间是否过8点,风力情况。

如何选择分枝

要构建一颗决策树,首先我们要找到它的根,按照上一节所说,我们需要计算每一个属性的信息熵

在计算每一个属性的信息熵之前,我们需要先根据历史数据,计算没有任何属性影响下的赖床信息熵。从数据我们可以知道,14天中,有赖床为8天,不赖床为6天。则

p(赖床) = 8 / 12.
p(不赖床) = 6 / 12.

信息熵为

H(赖床) = -(p(赖床) * log(p(赖床)) + p(不赖床) * log(p(不赖床))) = 0.89

接下来就可以来计算每个属性的信息熵了,这里有三个属性,即季节,是否过早上8点,风力情况,我们需要计算三个属性的每个属性在不同情况下,赖床和不赖床的概率,以及熵值。

说得有点绕,我们先以风力情况这一属性来计算它的信息熵是多少,风力情况有三种,我们分别计算三种情况下的熵值。
风力情况的熵值

风力情况为 breeze 时,有 4 / 5 的概率会赖床,而 1 / 5 的概率不会赖床,它的熵为 entropy(breeze) = -(p(breeze,赖床) * log(p(breeze,赖床)) + p(breeze,不赖床) * log(p(breeze,不赖床))) 0.722。

风力情况为 no wind 时,和上面一样的计算,熵值为 entropy(no wind) = 0.811

风力情况为 gale 时,熵值为  entropy(gale) = 0.918

最终,风力情况这一属性的熵值为其对应各个值的熵值乘以这些值对应频率。

H(风力情况) = 5/12 * entropy(breeze) + 4/12 * entropy(no wind) + 3/12 * entropy(gale) = 0.801

还记得吗,一开始什么属性没有,赖床的熵是H(赖床)=0.89。现在加入风力情况这一属性后,赖床的熵下降到了0.801。这说明信息变得更加清晰,我们的分类效果越来越好。
减小信息熵

以同样的计算方式,我们可以求出另外两个属性的信息熵:

H(季节) = 0.56
H(是否过 8 点) = 0.748

通过它们的信息熵,我们可以计算出每个属性的信息增益。没错,这里又出现一个新名词,信息增益。不过它不难理解,信息增益就是拿上一步的信息熵(这里就是最原始赖床情况的信息熵)减去选定属性的信息熵,即

信息增益 g(季节) = H(赖床) – H(季节) = 0.33

这样我们就能计算每个属性的信息增益,然后选取信息增益最大的那个作为根节点就行了,在这个例子中,很明显,信息增益最大的是季节这个属性。

选完根节点怎么办?把每个节点当作一颗新的树,挑选剩下的属性,重复上面的步骤就可以啦。
选择其他分枝的过程

当全部都遍历完之后,一颗完整的树也就构建出来了,这个例子中,我们最终构造的树会是这个样子的:
完整的一颗决策树

三. 过拟合与剪枝

在构建决策树的时候,我们的期望是构建一颗最矮的决策树,为什么需要构建最矮呢?这是因为我们要避免过拟合的情况。

什么是过拟合呢,下图是一个分类问题的小例子,左边是正常的分类结果,右边是过拟合的分类结果。

过拟合

在现实世界中,我们的数据通常不会很完美,数据集里面可能会有一些错误的数据,或是一些比较奇葩的数据。如上图中的蓝色方块,正常情况下我们是允许一定的误差,追求的是普适性,就是要适应大多数情况。但过拟合的时候,会过度追求正确性,导致普适性很差。

剪枝,即减少树的高度就是为了解决过拟合,你想想看,过拟合的情况下,决策树是能够对给定样本中的每一个属性有一个精准的分类的,但太过精准就会导致上面图中的那种情况,丧失了普适性。

而剪枝又分两种方法,预剪枝干,和后剪枝。这两种方法其实还是蛮好理解的,一种是自顶向下,一种是自底向上。我们分别来看看。

预剪枝

预剪枝其实你可以想象成是一种自顶向下的方法。在构建过程中,我们会设定一个高度,当达构建的树达到那个高度的时候呢,我们就停止建立决策树,这就是预剪枝的基本原理。

后剪枝

后剪枝呢,其实就是一种自底向上的方法。它会先任由决策树构建完成,构建完成后呢,就会从底部开始,判断哪些枝干是应该剪掉的。

注意到预剪枝和后剪枝的最大区别没有,预剪枝是提前停止,而后剪枝是让决策树构建完成的,所以从性能上说,预剪枝是会更块一些,后剪枝呢则可以更加精确。

ID3决策树算法的不足与改进

ID3决策树不足

用ID3算法来构建决策树固然比较简单,但这个算法却有一个问题,ID3构建的决策树会偏袒取值较多的属性。为什么会有这种现象呢?还是举上面的例子,假如我们加入了一个属性,日期。一年有365天,如果我们真的以这个属性作为划分依据的话,那么每一天会不会赖床的结果就会很清晰,因为每一天的样本很少,会显得一目了然。这样一来信息增益会很大,但会出现上面说的过拟合情况,你觉得这种情况可以泛化到其他情况吗?显然是不行的!

C4.5决策树

针对ID3决策树的这个问题,提出了另一种算法C4.5构建决策树。
C4.5决策树中引入了一个新的概念,之前不是用信息增益来选哪个属性来作为枝干嘛,现在我们用增益率来选!

计算公式1

计算公式2

这里面,IV(a)这个,当属性可选的值越多(比如一年可取365个日期)的时候,它的值越大。
而IV(a)值越大,增益率显然更小,这就出现新问题了。C4.5决策树跟ID3决策树反过来,它更偏袒属性可选值少的属性。这就很麻烦了,那么有没有一种更加公正客观的决策树算法呢?有的!!

CART 决策树

上面说到,ID3决策树用信息增益作为属性选取,C4.5用增益率作为属性选取。但它们都有各自的缺陷,所以最终提出了CART,目前sklearn中用到的决策树算法也是CART。CART决策树用的是另一个东西作为属性选取的标准,那就是基尼系数
计算公式3

计算公式4

第一条公式中pk表示的是每个属性的可选值,将这些可选值计算后累加。这条公式和信息增益的结果其实是类似的,当属性分布越平均,也就是信息越模糊的时候,基尼系数值会更大,反之则更小。但这种计算方法,每次都只用二分分类的方式进行计算。比如说上面例子中的季节属性,有春夏秋冬四个可选值(春,夏,秋,冬)。那么计算春季的时候就会按二分的方式计算(春,(夏,秋,冬))。而后面其他步骤与ID3类似。通过这种计算,可以较好得规避ID3决策树的缺陷。

所以如果用CART算法训练出来的决策树,会和我们上面ID3训练出来的决策树有些不一样。在下一篇文章就会用sklearn来使用CART算法训练一颗决策树,并且会将结果通过画图的方式展现。


推荐阅读:
Scala 函数式编程指南(一) 函数式思想介绍
Actor并发编程模型浅析
大数据存储的进化史 –从 RAID 到 Hadoop Hdfs
C,java,Python,这些名字背后的江湖!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/166987.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • oracle删除表时索引是否删除_oracle索引类型

    oracle删除表时索引是否删除_oracle索引类型DML性能低下,其中最严重的原因之一是无用索引的存在。所有SQL的插入,更新和删除操作在它们需要在每一行数据被改变时修改大量索引的时候会变得更慢。许多Oracle管理人员只要看见在一个SQL查询的WHERE语句出现了一列的话就会为它分配索引。虽然这个方法能够让SQL运行得更快速,但是基于功能的Oracle索引使得数据库管理人员有可能在数据表的行上过度分配索引。过度分配索引会严重影响关键Oracl…

  • 字符串全排列cpp_输出字符串的全排列

    字符串全排列cpp_输出字符串的全排列String对象描述字符串是JavaScript的一种基本的数据类型String类定义了大量操作字符串的方法,例如从字符串中提取字符或子串,或者检索字符或子串。需要注意的是:JavaScript的字符串是不可变的(immutable),String类定义的方法都不能改变字符串的内容。像String.toUpperCase()这样的方法,返回的是全新的字符串,而不是修改原始字符串。String对象属性属性描述constructor对创建该对象的函数的引用

    2022年10月30日
  • 逻辑漏洞之越权、支付漏洞「建议收藏」

    逻辑漏洞之越权、支付漏洞「建议收藏」目录逻辑漏洞Web安全渗透三大核心方向输入输出登录体系、权限认证业务逻辑漏洞分类1、登录体系安全暴力破解cookie安全加密测试登录验证绕过任意注册2、业务一致性安全手机号篡改邮箱和用户名更改订单ID更改商品编号更改用户ID篡改流程顺序3、业务数据篡改金额数据篡改商品数量篡改最大数限制突破金额&优惠组合修改4、密码找回漏洞分析数据包,定位敏感信息分析找回机制修改数据包验证任意密码找回5、验证码突破暴力破解时间、次数突破回显测试验证码绕过测试验证检验机制猜解6、会话权限安全未授权访问水平&垂直

  • 金山词霸2003闪烁问题。

    金山词霸2003闪烁问题。

  • Virtualenv介绍、基本使用及在Pycharm下配置环境[通俗易懂]

    Virtualenv介绍、基本使用及在Pycharm下配置环境[通俗易懂]Virtualenv是一个创建独立Python运行环境的工具,主要解决Python软件开发过程中版本和依赖性问题。本文对Virtualenv做了简单的介绍、如何建立虚拟环境以及如何在Pycharm下配置Virtualenv环境

  • FDD与TDD的区别

    FDD与TDD的区别LTE通常分为FDDLTE和TDDLTEFDD,频分双工(FrequencyDivisionDuplexing)我和你通信,像广播一样,只能我说你听,是单工;像对讲机一样,同一时间只能一方说,另一方听,就是半双工;如果双方可以同时说和听,就是全双工。TDD:收发共用一个射频频点,上、下行链路使用不同的时隙来进行通信FDD:收发使用不同的射频频点来进行通信…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号