16. 机器学习 - 决策树

在这里插入图片描述

Hi,你好。我是茶桁。

在上一节课讲SVM之后,再给大家将一个新的分类模型「决策树」。我们直接开始正题。

决策树

我们从一个例子开始,来看下面这张图:

Alt text

假设我们的x1 ~ x4是特征,y是最终的决定,打比方说是买东西和不买东西,0为不买,1为买东西,假设现在y是[0,0,1,0,1]

那么,我们应该以哪个特征为准去判断到底y是0还是1呢?

如果关注x3,那么x3为A的时候,即有0也有1,我们先放一边找找看有没有更合适的。

如果是x4的话,肉眼可见的,区分度是最准确的对吧?B的都是都是0,C的时候都是1,那么x4也就是区分度最大的。

我们现在换成人的思维过程来说,肯定是期望先找到那个最能区分它的,就是最能识别的特征。这个最能识别的特征在数学里面有一个专门的定义:Salient feature, 就是显著特征。

如果我们更改一下x4的值,变成[B,C,C,B,B], 那x4也就不那么显著了。这个时候最能区分的就是x2了,只在x2[1]的位置上判断错了一个。

这个时候,我们就需要客观的衡量一下,什么叫做最能区分,或者说是最能分割,最显著的区别。这就需要一个专门的数值来计算。

那我们就来看看,到底怎么样来做区分。我们现在根据一个值,将我们的数据分成了两堆,那咱们的期望就是这两堆数据尽可能是一样的。比如极端情况下,一堆全是0, 一堆全是1,当然,中间混进去一个不一样的也行,但是尽可能的「纯」:

Alt text

好,那我们该怎么定义这个「纯」呢?

我们大家应该都知道物理里有一个定义:「熵」,那熵在物理里是衡量物体的混乱程度的。

比如说一个组织、一个单位、公司或者个人,其内部的熵都是在呈现越来越混乱,而且熵的混乱具有不可逆性。这个呢,就是熵增定律,也叫「热力学第二定律」。是德国人克劳修斯提出的理论,最初用于揭示事物总是向无序的方向的发展、以及“孤立系统下热量从高温物体流向低温不可逆”的热力学定律(要不说看我的文章涨学问呢是吧)。

信息熵

好,说回咱们的机器学习。后来有一个叫「香农」的人要衡量一堆新息的混乱程度,就起了一个名字「信息熵」,也就成了衡量信息的复杂程度。

那么信息熵怎么求呢?

E n t r o p y = ∑ i = 1 n − p ( c i ) l o g 2 ( p ( c i ) ) \begin{align*} Entropy = \sum_{i=1}^n-p(c_i)log_2(p(c_i)) \end{align*} Entropy=i=1np(ci)log2(p(ci))

这个值越大,就说明了这个新息越混乱,相反的,越小就说明越有秩序。来,我们看一下代码演示,定义一个熵的方法:

import numpy as np
from icecream import ic
from collections import Counterdef pr(e, elements):counter = Counter(elements)return counter[e] / len(elements)# 信息熵
def entropy(elements):return -np.sum(pr(e, element) * np.log(pr(e, elements)) for e in elements)

然后我们具体的来看几组数据:

ic(entropy([1,1,1,1,1,0]))
ic(entropy([1,1,1,1,1,1]))
ic(entropy([1,2,3,4,5,8]))
ic(entropy([1,2,3,4,5,9]))
ic(entropy(['a','b','c','c','c','c','c']))
ic(entropy(['a','b','c','c','c','c','d']))---
ic| entropy([1,1,1,1,1,0]): 1.05829973151282
ic| entropy([1,1,1,1,1,1]): -0.0
ic| entropy([1,2,3,4,5,8]): 1.7917594692280547
ic| entropy([1,2,3,4,5,9]): 1.7917594692280547
ic| entropy(['a','b','c','c','c','c','c']): 1.7576608876629927
ic| entropy(['a','b','c','c','c','c','d']): 2.1130832934475294

我们可以看到,最「纯」的是第二行数据,然后是第一行,第三行和第四行是一样的。5,6行就更混乱一些。

那接下来的知识点是只关于Python的,我们看上面的代码是不是有点小问题?这个代码里有很多的冗余。一般情况下,会将counter改成全局变量,但是一般如果想要代码质量好一些,尽量不要轻易定义全局变量。我们来简单的修改一下:

def entropy(elements):# 信息熵def pr(es):counter = Counter(es)def _wrap(e):return counter[e] / len(elements)return _wrapp = pr(elements)return -np.sum(p(e) * np.log(p(e)) for e in elements)

这样写之后,我们再用刚才的数据来进行调用会看到结果完全一样。不过如果这样写之后,如果我们数据量很大的情况下,会发现会快很多。

Gini系数

除了上面这个信息熵之外,还有一个叫Gini系数,和信息熵很类似:

G i n i = 1 − ∑ i = 1 n p 2 ( C i ) \begin{align*} Gini = 1 - \sum_{i=1}^np^2(C_i) \\ \end{align*} Gini=1i=1np2(Ci)

假如说probability都是1,也就是最纯的情况,那么1减去1就等于0。如果它特别长,特别混乱,都很分散,那probability就会越接近于0,那么1减去0,那结果也就是越接近于1。

那么代码实现一下就是这样:

def geni(elements):return 1-np.sum(pr(e) ** 2 for e in set(elements))

好吧,这个时候我发现一个问题,之前我们将probability函数定义到熵函数内部了,为了让Gini函数能够调用,我们还得拿出来。在我们之前修改的初衷不变的情况下,我们来这样进行修改:

def pr(es):counter = Counter(es)def _wrap(e):return counter[e] / len(es)return _wrapdef entropy(elements):# 信息熵p = pr(elements)return -np.sum(p(e) * np.log(p(e)) for e in elements)

哎,这样就对了。优雅…

然后我们来修改Gini函数,让其调用pr函数:

def gini(elements):p = pr(elements)return 1 - np.sum(p(e) ** 2 for e in set(elements))

然后我们写一个衡量的方法:

pure_func = gini

然后我们将之前的调用都修改一下:

ic(pure_func([1,1,1,1,1,0]))
ic(pure_func([1,1,1,1,1,1]))
ic(pure_func([1,2,3,4,5,8]))
ic(pure_func([1,2,3,4,5,9]))
ic(pure_func(['a','b','c','c','c','c','c']))
ic(pure_func(['a','b','c','c','c','c','d']))---
ic| pure_func([1,1,1,1,1,0]): 0.2777777777777777
ic| pure_func([1,1,1,1,1,1]): 0.0
ic| pure_func([1,2,3,4,5,8]): 0.8333333333333333
ic| pure_func([1,2,3,4,5,9]): 0.8333333333333333
ic| pure_func(['a','b','c','c','c','c','c']): 0.44897959183673464
ic| pure_func(['a','b','c','c','c','c','d']): 0.6122448979591837

我们可以看到,Gini系数是把整个纯度压缩到了0~1之间,越接近于1就是越混乱,越接近0呢就是越有秩序。

其实除了数组之外,字符串也是一样可以衡量的:

ic(pure_func("probability"))
ic(pure_func("apple"))
ic(pure_func("boom"))---
ic| pure_func("probability"): 0.8760330578512396
ic| pure_func("apple"): 0.72
ic| pure_func("boom"): 0.625

在能够定义纯度之后,现在如果我们有很多数据,就比方说是我们最之前定义数据再增多一些:[x1, x2, x3, ..., xn],那么我们决策树会做什么呢?

根据x1对y做了分类,根据x2对y做了分类,做了分类之后,通过x1把y分成了两堆,一堆我们称呼其为m_left, 另外一堆我们称呼其为m_right,然后我们来定义一个loss函数:

l o s s = m l e f t n ⋅ G l e f t + m r i g h t m ⋅ G r i g h t \begin{align*} loss = \frac{m_{left}}{n} \cdot G_{left} + \frac{m_{right}}{m} \cdot G_{right} \end{align*} loss=nmleftGleft+mmrightGright

现在要让这个loss函数的值最小。在整个式子中,G代表的是纯度函数,这个纯度函数可以是Entropy,也可以是Gini。

loss函数的值最小的时候,就可以实现左右两边分的很均匀。我们把这个算法就叫做CART。

Alt text

CART算法其实就是classification and regression tree Algorithm, 也称为「分类和回归树算法」。

上面我们讲的所有内容可以实现分类问题,那么回归问题怎么解决呢?CART里可是包含了Regression的。

好,还是我们最之前给的数据,我们现在的y不是[0,0,1,0,1]了,我们将其更改为[1.3,1.4,0.5,0.8,1.9]。我们人类大脑中的直觉会怎么分类?会将[1.3,1.4,1.9]分为一类,而[0.5,0.8]分为一类对吧?(我说的是大部分人,少部分「天才」忽略)。

那么为了完成这样的一个分类,我们将之前公式里的纯度函数替换成MSE,那么函数就会变成如下这个样子:

J ( k , t k ) = m l e f t m ⋅ M S E l e f t + m r i g h t m M S E r i g h t J(k, t_k) = \frac{m_{left}}{m} \cdot MSE_{left} + \frac{m_{right}}{m}MSE_{right} J(k,tk)=mmleftMSEleft+mmrightMSEright

MSE是什么呢?其实就是均方误差。

M S E n o d e = ∑ i ∈ n o d e ( y ^ n o d e − y ( i ) ) 2 y ^ n o d e = 1 m n o d e ∑ i ∈ n o d e y ( i ) \begin{align*} MSE_{node} & = \sum_{i \in node}(\hat y_{node} - y^{(i)})^2 \\ \hat y_{node} & = \frac{1}{m_{node}}\sum_{i\in node}y^{(i)} \end{align*} MSEnodey^node=inode(y^nodey(i))2=mnode1inodey(i)

我们要取的,就是最小的那一个MSE。

决策树最大的优点就是在决策上我们需要更大的解释性的时候很直观,决策树可以将其分析过程以树的形式展现出来。一般在商业、金融上进行决策的时候我们都需要很高的解释性。就比如下面这个例子:

Alt text

第二呢,它可以来提取重要特征。决策术可能某一类问题上效果假设最多只能做到85%的准确度,我们期望换一种模型,希望用到的维度少一点。

比方说要做逻辑回归,我们期望的w.x+b乘以一个Sigmoid,原来的x是10维的,我们期望把它降到5维。那这个时候决策树的构建过程就从最显著的特征开始逐渐构建,我们就可以把它前五个特征给他保留下来,前五个特征就是最salience的feature。我们假如把它用到逻辑回归上,直接用这五个维度就可以了。

接着我们来个问题:本来是10维的我们期望把它变成5维,为什么我们希望降维呢?

还记得我们「拟合」这一节么?我们说过,过拟合最主要的原因是数据量过少或者模型过于复杂,那为什么数据量过少呢?不知道是否还记得我讲过的维度灾难。

多个维度就需要多个数量级的数据。在仅有这么多数据的情况下,维度越多需要更多数据来拟合,但是大部分时候我们并没有那么多数据。

这个问题其实是一个很经典的问题,为什么我们做各种机器学习的时候期望降维。如果能把这个仔仔细细的想清楚,其实机器学习原理基本上已经能够掌握清楚了。

接下来我们再说说它的缺点,其实也很明显,它的分类规则太过于简单。所以它最大的缺点就是因为简单,所以好解释,但正是因为简单,所以解决不了复杂问题。

和SVM一样,也可以给决策树加核函数,曾经有一段时间这也是很重要的一个研究领域。

好,在结束之前我们预告一下下一节课内容,我们还是讲决策树,讲讲决策树中的Adaboost等,以及决策树的升级版:随机森林。

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

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

相关文章

直流无刷电机(BLDC)六步换相驱动

直流无刷电机(BLDC)六步换相驱动 文章目录 直流无刷电机(BLDC)六步换相驱动1. 前言2. 六步换相原理3. 电角度与机械角度4. 动手实践4.1 霍尔输出表测量4.2 换向控制4.3 代码编写 5. 总结 1. 前言 直流无刷电机相对直流有刷电机具…

基于社交网络算法的无人机航迹规划-附代码

基于社交网络算法的无人机航迹规划 文章目录 基于社交网络算法的无人机航迹规划1.社交网络搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用社交网络算法来优化无人机航迹规划。 …

【Java 进阶篇】Java Session 原理及快速入门

大家好,欢迎来到本篇博客。今天,我们将探讨Java Web开发中一个重要而令人兴奋的概念,即Session(会话)。Session是一种在Web应用程序中跟踪用户状态和数据的机制。我们将深入了解Session的原理,并通过示例来…

鸿运主动安全云平台任意文件下载漏洞复习

简介 深圳市强鸿电子有限公司鸿运主动安全监控云平台网页存在任意文件下载漏洞,攻击者可通过此漏洞下载网站配置文件等获得登录账号密码 漏洞复现 FOFA语法:body"./open/webApi.html" 获取网站数据库配置文件 POC:/808gps/Mobile…

Winform 实现俄罗斯方块游戏(一)

第一步,先用GDI绘制小正方形方块,其它形状的用这个方块合成 如何绘制一个方块?先绘制两个正方形,如下: 然后四周用梯形填充,内部颜色用渐变,这样更有立体感,下篇介绍如何实现。

Observability:使用 OpenTelemetry 手动检测 .NET 应用程序

作者:David Hope 在快节奏的软件开发领域,尤其是在云原生领域,DevOps 和 SRE 团队日益成为应用程序稳定性和增长的重要合作伙伴。 DevOps 工程师不断优化软件交付,而 SRE 团队则充当应用程序可靠性、可扩展性和顶级性能的管理者。…

Apache Doris (五十一): Doris数据缓存

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1.

96. 不同的二叉搜索树

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n 3 输出:5示例 2: 输入:n 1 输出:1提…

PostCSS通过px2rem插件和lib-flexible将px单位转换为rem(root em)单位实现大屏适配

目录 文档postcss中使用postcss-plugin-px2rem安装postcss-plugin-px2rem示例默认配置 webpack中使用postcss-plugin-px2rem项目结构安装依赖文件内容 大屏适配参考文章 文档 类似的插件 postcss-plugin-px2rem https://www.npmjs.com/package/postcss-plugin-px2remhttps://g…

Docker容器技术实战4

11、docker安全 proc未被隔离,所以在容器内和宿主机上看到的东西是一样的 容器资源控制 cpu资源限制 top命令,查看cpu使用率 ctrlpq防止退出回收,容器会直接调用cgroup,自动创建容器id的目录 cpu优先级设定 测试时只保留一个cpu…

翻页电子杂志制作功略,快收藏,保管好用!

翻页电子杂志,我相信这对大家很熟悉吧,大家也都经常看电子杂志吧。它和我们的生活紧密相关,也极大地改变了我们的阅读方式。听到这“翻页电子杂志”,是不是觉得制作起来肯定很难很复杂,需要专业的人才能制作呢&#xf…

51单片机汇编-点亮一个led

文章目录 前言1.打开IDE2.设置编辑器3.设置输出4. 原理图5.编写代码6 编译7.下载8.其它代码1.LED闪烁2.跑马灯 前言 51单片机基础 本章主要介绍打开一个led,具体采用51汇编 1.打开IDE 选择STC89C52RC 后缀是.asm 2.设置编辑器 3.设置输出 4. 原理图 5.编写代码 ORG 00H;伪代…

「视频编码软件」Media Encoder(Me) 2024 Mac/win中文版下载安装

Adobe Media Encoder(Me) 2024是一款专业的视频编码工具,它可以将各种视频格式进行转换、压缩和编码,以满足不同媒体平台和设备的需求。 以下是 Media Encoder 2023 的主要功能和新增功能: 视频编码和转换:支持将各种视频格式进…

python脚本-网页爬虫获取网页图片

python脚本-网页爬虫获取网页图片 代码 import requests import re import time url"http://10.9.47.154/python-spider/" # 爬取网站的url headers {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

arcgis pro模型构建器

如果你不想部署代码包环境来写arcpy代码,还想实现批量或便携封装的操作工具,那么使用模型构建器是最好的选择。1.简介模型构建器 1.1双击打开模型构建器 1.2简单模型构建步骤 先梳理整个操作流程,在纸上绘制在工具箱中找到所需工具拖进来把…

C++初阶(八)类和对象

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、Static成员1、Static概念2、Static特性3、试题 二、友元1、友元的类型2、友元函数3、 友元…

strongswan:configure: error: OpenSSL Crypto library not found

引子 在配置strongswan时,有时会遇到以下错误(其实所有需要openssl的软件configure时都有可能遇到该问题): configure: error: OpenSSL Crypto library not found 解决方法 crypto是什么呢? 是OpenSSL 加密库(lib), 这个库需要op…

Linux多值判断利用case...esac判断

利用这个判断,一定要注意格式的运用,非常容易出错 case $1 in #判断变量的值 "hello") #双引号注意,右括号 echo " afdbab " #语句段,没啥说的 ;; #两个分号结束第一个判断&#xff0c…

持续进化,快速转录,Faster-Whisper对视频进行双语字幕转录实践(Python3.10)

Faster-Whisper是Whisper开源后的第三方进化版本,它对原始的 Whisper 模型结构进行了改进和优化。这包括减少模型的层数、减少参数量、简化模型结构等,从而减少了计算量和内存消耗,提高了推理速度,与此同时,Faster-Whi…

【LeetCode】第 370 场周赛

100115. 找到冠军 I 一场比赛中共有 n 支队伍&#xff0c;按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 < i, j < n - 1 且 i ! j 的所有 i, j &#xff1a;如果 grid[i][j] 1&#xff0c;那么 i 队比 j 队 强 &…