决策树入门、sklearn实现、原理解读和算法分析

news2024/11/17 1:32:09

文章目录

  • 决策树入门
  • 决策树sklean实现
  • 决策树算法
    • 单/多变量决策树
    • CART分类树算法
  • 决策树分析
    • 复杂度控制
    • 特征重要性
    • 决策树特点

决策树入门

总算来到心心念念的决策树了。工作中一直在用xgb模型,今天开始,终于可以尝试去理解其背后的算法原理了。不过xgb较为复杂,还是先从最基础的模型入门吧:决策树。

决策树是怎么解决机器学习的问题呢?其本质是通过多层if/else去把训练集做拆分,最终得到预测结果。

举个例子说一下。我们要区分以下4种动物:熊、鹰、企鹅和海豚。此时,我们可以先做第一层if拆分: 动物是否有羽毛?有羽毛的可能是鹰或企鹅,没有羽毛的则是熊或海豚。针对有羽毛的情况,我们再做一层if判断: 动物会不会飞?会飞的是鹰,不会飞的是企鹅;针对没有羽毛的情况,我们新的if逻辑是:有没有鳍?有鳍的是海豚,没有鳍的是熊。以下为if/else操作的图示。

如果用机器学习的语言来描述,就是为了区分鹰、企鹅、海豚和熊这四种动物,我们使用三个特征:“有没有羽毛”、“会不会飞”和“有没有鳍”,来构建一个分类模型。

嗯,看起来还挺简单的。

决策树sklean实现

上述区分动物的实例,虽然有助于我们入门决策树,但本质是个多分类问题,和我们平时研究的二分类问题还是有些不太一样的。为了便于理解决策树的具体原理,我们最好还是找个二分类的实例。本文所使用的二分类实例的代码如下所示。

from sklearn.datasets import make_moons


def two_moons():
    # make_blobs: sklearn内置单标签类数据集
    features, labels = make_moons(n_samples=100,  noise=0.25, random_state=3)

    # discrete_scatter:数据集可视化
    plt.scatter(features[labels == 0][:, 0], features[labels == 0][:, 1])
    plt.scatter(features[labels == 1][:, 0], features[labels == 1][:, 1])
    plt.legend(['Class0', 'Class1'], loc=4)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()

    return features, labels


if __name__ == '__main__':
    X, y = two_moons()

运行代码后,可以得到下图。该问题中,有两个特征: x x x y y y;分类结果有两个:class0和class1,分别对应蓝色和黄色圆点,样本数量均为50个。

如果要使用sklearn决策树算法对该问题进行分类,可以使用以下的代码实现:

from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import matplotlib.pyplot as plt


if __name__ == '__main__':

    X, y = two_moons()
    # 3层决策树
    dtc = DecisionTreeClassifier(max_depth=3)
    dtc_tree = dtc.fit(X, y)

    # 文本形式显示决策树规则
    text_representation = tree.export_text(dtc_tree)
    print(text_representation)

    # 决策树可视化
    fig = plt.figure(figsize=(25, 20))
    _ = tree.plot_tree(
        dtc,
        filled=True
    )
    fig.savefig("decision_tree.png")

代码中,包含三段内容:(1)构造深度为3的决策树;(2)打印决策树规则;(2)决策树可视化。

运行代码后,得到决策树规则如下:

|--- feature_1 <= 0.06
|   |--- feature_0 <= -0.42
|   |   |--- class: 0
|   |--- feature_0 >  -0.42
|   |   |--- class: 1
|--- feature_1 >  0.06
|   |--- feature_0 <= 1.20
|   |   |--- feature_1 <= 0.50
|   |   |   |--- class: 0
|   |   |--- feature_1 >  0.50
|   |   |   |--- class: 0
|   |--- feature_0 >  1.20
|   |   |--- feature_0 <= 1.67
|   |   |   |--- class: 1
|   |   |--- feature_0 >  1.67
|   |   |   |--- class: 1

可视化效果如下:

上面的结果暂时不多做解释,主要是先对分类结果有个印象。为了更容易理解分类过程,这里依次描述和绘制第1、2和3层的分类结果:

当深度只有1的时候,模型沿着 y = 0.06 y = 0.06 y=0.06水平方向,将区域分为两块,上半部分为class0,下半部分为class1。

当深度为2时,模型在已有结果的基础上继续细化:上半部分沿着 x = 1.20 x=1.20 x=1.20垂直方向拆分,左边仍为class0,但是右边变为class1;下半部分沿着 x = − 0.42 x=-0.42 x=0.42垂直方向拆分,左边变为class0。

当深度变为3后,上半部分的2块区域还可以继续分割,具体方式直接看图,此处不再赘述。
在这里插入图片描述

决策树算法

通过第2节的描述,我们可以发现,构造决策树的核心内容至少包含两个方面:(1)每一次的区域切割方向;(2)最佳切割点。这其实是和优化思路非常类似——分别对应迭代方向和迭代步长。

单/多变量决策树

先分析清楚切割方向。从sklearn的分类流程不难看出,切割方向只会沿着x轴或者y轴,所以是“轴平行”的,专业名词为:单变量决策树。这种方式下,决策树每次只会沿着某一个特征进行拆分,而其他特征则保持不变。这就导致在遇到边界比较复杂的分类问题时,需要多次划分才可能得到比较好的近似。针对下图的实例,需要4次划分才能完全分开。

如果可以不限定沿着某个坐标轴,而是允许沿着任意方向进行切割,则可能更快完成完美的分类。如下图所示,2次便可以完成全部划分。该方式学名为多变量决策树,或斜决策树。相比单变量决策树,多变量决策树的可选切割范围有了巨大的拓展,但是最佳切割方向的寻找,也会变得更加困难。

CART分类树算法

然后再看一下最佳切割点的选取,这里需要用到一个算法:CART分类树算法。

在CART分类树算法中,使用gini(基尼系数)来衡量某一结点的纯度。结点中的样本越多属于同类,那么这个结点越“纯”,gini指标就会越小,所以gini指标也称为gini不纯度。

假设 A j ( j = 1 , 2 ) Aj (j=1, 2) Aj(j=1,2)为将样本分类后的两个部分, w j w_j wj为这两部分的各自占比, p i p_i pi为样本属于第 i i i类的概率, n n n为分类的总个数,那么结点 A j A_j Aj的gini不纯度可以表示为:
gini ( A j ) = 1 − ∑ i = 1 n p i 2 \text{gini}(A_j)=1-\sum_{i=1}^np_i^2 gini(Aj)=1i=1npi2
整体的gini值为
gini ( A ) = ∑ j = 1 2 w j ∗ gini ( A j ) \text{gini}(A)=\sum_{j=1}^2w_j * \text{gini}(A_j) gini(A)=j=12wjgini(Aj)
在sklearn中,实际使用是如下的一种优化版本:
gini = ∑ i = 1 2 w i ∗ ( 1 − w i ) \text{gini}=\sum_{i=1}^2 w_i*(1-w_i) gini=i=12wi(1wi)
回顾第2节的可视化效果图,我们计算一下第1和2层中的每个结点的gini值:
gini 1 = 50 / 100 ∗ ( 1 − 50 / 100 ) ∗ 2 = 0.5 \text{gini}_1=50 / 100 * (1 - 50 / 100) * 2=0.5 gini1=50/100(150/100)2=0.5
gini 2 左 = 2 / 34 ∗ ( 1 − 2 / 34 ) + 32 / 34 ∗ ( 1 − 32 / 34 ) = 0.1107 \text{gini}_{2左}=2 / 34 * (1 - 2 / 34) + 32 / 34 * (1 - 32 / 34)=0.1107 gini2=2/34(12/34)+32/34(132/34)=0.1107
gini 2 右 = 48 / 66 ∗ ( 1 − 48 / 66 ) + 18 / 66 ∗ ( 1 − 18 / 66 ) = 0.3967 \text{gini}_{2右}=48/66 * (1 - 48/66) + 18/66 * (1 - 18/66)=0.3967 gini2=48/66(148/66)+18/66(118/66)=0.3967
可以发现,该结果和sklearn可视化图中的gini结果,完全一致。

至此,我们可以将sklearn决策树求解分类问题的算法过程理解为:首先使用单变量决策树逻辑,对所有特征逐一尝试分割;然后使用CART分类树算法确定最佳分割点,得到最小gini值,完成一次分割。此后再逐渐增加树的深度,不断细化分割,直至gini=0。

决策树分析

复杂度控制

理论上来说,决策树可以一直分割到所有叶结点都是纯的叶结点。但这很容易导致模型变得非常复杂,并且对训练数据高度过拟合。还是以文章中的实例为例:depth=3时,右上角区域被分割为了两个区域;但从我们朴素的认知来看,该区域内的class0更像是一个异常值,完全可以不再分割。

防止过拟合有两种常见的策略:一种是及早停止树的生长,也叫预剪枝,具体策略包括:限制树的最大深度、叶结点的最大数目、规定结点中数据点的最小数据等;另一种是先构造树,但随后删除或折叠信息量很少的结点,也叫后剪枝或剪枝。

需要注意的是,在sklearn中,只有预剪枝,没有后剪枝。

特征重要性

如果决策树比较深,那么查看整个树可能会比较费劲。此时,我们可以通过特征重要性来判断每个特征对树的决策的重要性。对于任意一个特征来说,它都是一个介于0和1之间的数字,其中0表示“根本没用到”,1表示“完美预测目标值”。

sklearn计算特征重要性的方式,比较简单,只需要一行代码:

# 特征重要性
feat_importance = dtc_tree.tree_.compute_feature_importances(normalize=False)

运行后,可以得到特征 x x x y y y的重要性值分别为0.1477和0.2139。

接下来,我们主要看一看特征重要性的计算原理:
N t / N × ( gini − N t L / N t gini L − N t R / N t gini R ) N_t / N\times(\text{gini}- N_{tL} / N_t\text{gini}_L - N_{tR} / N_t \text{gini}_R) Nt/N×(giniNtL/NtginiLNtR/NtginiR)
其中,N_t是当前结点的样本数目,N是样本的总数, gini \text{gini} gini是当前结点的基尼系数, gini L \text{gini}_L giniL gini R \text{gini}_R giniR分别是结点左和右孩子的基尼系数, N t L N_{tL} NtL N t R N_{tR} NtR是对应的样本数目。

在本文的分类实例中,3次用到 x x x,2次用到 y y y。首先计算特征 x x x的重要性
F i x 1 = 34 / 100 ∗ ( 0.111 − 0 − 0 ) Fi_{x1}=34 / 100 * (0.111-0-0) Fix1=34/100(0.11100)
F i x 2 = 66 / 100 ∗ ( 0.397 − 0.249 ∗ 55 / 66 − 0.165 ∗ 11 / 66 ) Fi_{x2}=66 / 100 * (0.397 - 0.249 * 55 / 66 - 0.165 * 11 / 66) Fix2=66/100(0.3970.24955/660.16511/66)
F i x 3 = 11 / 100 ∗ ( 0.165 − 0.375 ∗ 4 / 11 ) Fi_{x3}=11 / 100 * (0.165 - 0.375 * 4 / 11) Fix3=11/100(0.1650.3754/11)
因此特征 x x x的重要性为
F i x = F i x 1 + F i x 2 + F i x 3 = 0.1478 Fi_x=Fi_{x1}+Fi_{x2}+Fi_{x3}=0.1478 Fix=Fix1+Fix2+Fix3=0.1478
照葫芦画瓢,可以得到特征 y y y的重要性为
F i y 1 = 100 / 100 ∗ ( 0.5 − 0.111 ∗ 34 / 100 − 0.397 ∗ 66 / 100 ) Fi_{y1}=100 / 100 * (0.5 - 0.111 * 34 / 100 -0.397 * 66 / 100) Fiy1=100/100(0.50.11134/1000.39766/100)
F i y 2 = 55 / 100 ∗ ( 0.249 − 0.408 ∗ 21 / 55 − 0.111 ∗ 34 / 55 ) Fi_{y2}=55 / 100 * (0.249 - 0.408 * 21 / 55 - 0.111 * 34 / 55) Fiy2=55/100(0.2490.40821/550.11134/55)
F i y = F i y 1 + F i y 2 = 0.2138 Fi_y=Fi_{y1}+Fi_{y2}=0.2138 Fiy=Fiy1+Fiy2=0.2138
显然,和sklearn的重要性值结果是相同的。

决策树特点

相比其他机器学习算法,决策树的优点有两个:(1)模型很容易可视化,可以输出特征重要性值,非专家也很容易理解;(2)算法不受数据缩放的影响,因此无需对数据进行归一化等预处理操作。

决策树的一个重要特质是不能外推,即无法在训练数据之外生成”新的”数据。以下图为例,横轴是年份,纵轴是当年1兆字节(MB)RAM的价格。训练集中包含了2000年前的历史数据,目前要预测2000年后的价格。如果使用线性模型,会得到价格持续降低的结果;而如果使用决策树模型,此后价格会维持2000年的价格不变。显然,从合理性的角度来看,线性模型比决策树模型更适合求解该问题。

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

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

相关文章

软件开发全套文档案例分享

写在前面 在日常项目开发过程中&#xff0c;会产生大量的过程文档&#xff0c;比如开发过程中的文档、管理过程中的文档、产品相关文档等等&#xff0c;那这些文档我们日常怎么去管理呢&#xff1f;怎么去做规划呢&#xff1f;如何做成通用标准呢&#xff1f;小编特地整理了一…

问卷中多选题如何分析?

一、案例与问卷 本研究选取大学生作为研究对象&#xff0c;旨在通过理财认知、理财现状、理财偏好三个方面&#xff0c;对大学生理财产品了解情况、使用需求进行调查。本次问卷共分为四个部分&#xff1a;第一部分共5道题&#xff0c;为基本信息题&#xff1b;第二部分共3道题…

换肤实现及LayoutInflater原理

文章目录 背景实现换肤步骤解析插件 apk 的包信息获取插件 apk 的 Resources 对象替换资源 简单的插件化换肤实现和存在的问题换肤如何动态刷新&#xff1f;控件换肤刷新的性能考虑如何降低 xml 布局中 View 的替换成本LayoutInflater 原理LayoutInflater.Factory2 替换 View 小…

antDesignPro6: 如何设置环境变量,取值自动根据不同环境,动态修改(3步)。

官网文档&#xff1a;环境变量 - Ant Design Pro Pro 脚手架默认使用 Umi 作为底层框架&#xff0c;在 Umi 内可通过指定 UMI_ENV 环境变量来区分不同环境的配置文件&#xff0c;UMI_ENV 需要在 package.json 内配置。当 UMI_ENV 为 test 时&#xff0c;则必须在 config 目录下…

二十、线索关联市场活动(二):关联

功能需求 用户在线索明细页面,点击"关联市场活动"按钮,弹出线索关联市场活动的模态窗口; 用户在线索关联市场活动的模态窗口,输入搜索条件,每次键盘弹起,根据名称模糊查询市场活动,把所有符合条件的市场活动显示到列表中; 用户选择要关联的市场活动,点击"关联…

电销CRM客户关系管理系统开发12大核心功能

电销CRM管理系统软件是一款专门针对电销行业开发的客户关系管理软件&#xff0c;它能够帮助企业实现对顾客信息的可视化&#xff0c;智能化&#xff0c;自动化管理&#xff0c;提高电销效率和客户满意度。电销行业在传统互联网营销&#xff0c;新媒体营销&#xff0c;短视频营销…

PINNs与DeepXDE:加速物理计算模型

《AIScience系列&#xff08;一&#xff09;&#xff1a;飞桨加速CFD&#xff08;计算流体力学&#xff09;原理与实践》 https://baijiahao.baidu.com/s?id1728002499252273827&wfrspider&forpc 前言 AIScience专栏由百度飞桨科学计算团队出品&#xff0c;给大家带来…

dubbogo中将kubernetes作为注册中心 -- 阅读官方文档

Kubernetes服务发现模型 为了明确 K8s 在服务接入管理提供的解决方案&#xff0c;我们以 kube-apiserver 提供的 API(HTTPS) 服务为例。K8s 集群为该服务分配了一个集群内有效的 ClusterIP &#xff0c;并通过 CoreDNS 为其分配了唯一的域名 kubernetes 。如果集群内的 Pod 需…

不用先存盘直接显示附件内容

大家好&#xff0c;才是真的好。 有些需求总是很小众&#xff0c;但是还是被人需要。 Notes从来可以满足这种需求。 其实使用Notes客户机可以直接打开嵌入到文档中的附件&#xff0c;例如Txt文本、Word或PDF附件等。 不过有人提出&#xff0c;能否直接从Notes文档中的附件读…

CDGP|数据监管越来越严,数据治理发展何去何从?

尽管数据监管越来越严格&#xff0c;但仍然存在许多机会。事实上&#xff0c;数据监管的加强可能会促进金融科技行业更好地运用数据&#xff0c;激发金融科技行业更多的创新和合作,创造更多的价值和机会。 推动金融机构重视数据安全和隐私保护 促使他们采取更严格的安全措施&a…

尚硅谷大数据技术Spark教程-笔记05【SparkCore(核心编程,累加器、广播变量)】

视频地址&#xff1a;尚硅谷大数据Spark教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据技术Spark教程-笔记01【SparkCore&#xff08;概述、快速上手、运行环境、运行架构&#xff09;】尚硅谷大数据技术Spark教程-笔记02【SparkCore&#xff08;核心编程&#xff0c;RDD-核…

系统日志管理审核

系统日志管理 系统日志记录协议 &#xff08;syslog&#xff09; 旨在标准化网络设备用于与日志服务器通信的消息格式。网络上的路由器、交换机、防火墙和 Unix/Linux 服务器等许多设备都支持它&#xff0c;从而更轻松地管理这些设备生成的日志。系统日志监控和管理对于每个组…

基于GPT-4的 IDEA 神仙插件,无需魔法,亲测好用!

近日&#xff0c;Intellij IDEA的插件商店&#xff0c;悄然上线了一个新的插件——Bito&#xff0c;据说可以基于GPT-4和ChatGPT来写代码。短短几天&#xff0c;已经有50多K的下载量了。 我帮大家试用了一下&#xff0c;亲测好用&#xff01; 根据插件介绍显示&#xff0c;Bito…

《面向基于人工智能的学习健康系统,使用心电图进行人群水平的死亡率预测》阅读笔记

目录 一、摘要 二、十个问题 Q1论文试图解决什么问题&#xff1f; Q2这是否是一个新的问题&#xff1f; Q3这篇文章要验证一个什么科学假设&#xff1f; Q4有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一课题在领域内值得关注的研究员&#xff1f; Q5论文中提到…

Zynq-7000、国产zynq-7000的GPIO控制(三)

本文主要对在Linux下使用zynq-7000或者FMQL45T900控制MIO/EMIO 首先内核配置项 如下&#xff0c;这个不用太多关注&#xff0c;一般都是默认打开的 CONFIG_GPIO_SYSFSy CONFIG_SYSVIPCy CONFIG_GPIO_ZYNQy两者的控制都是流程都是一样的&#xff0c;在细节上又区别 首先都在…

第一章 安装Unity

使用Unity开发游戏的话&#xff0c;首先要安装Unity Hub和Unity Editor两个软件。大家可以去官方地址下载&#xff1a;https://unity.cn/releases/full/2020 &#xff08;这里我们选择的是2020版本&#xff09; Unity Hub 是安装 Unity Editor、创建项目、管理帐户和许可证的主…

mall-swarm微服务商城系统

mall-swarm是一套微服务商城系统&#xff0c;采用了 Spring Cloud 2021 & Alibaba、Spring Boot 2.7、Oauth2、MyBatis、Docker、Elasticsearch、Kubernetes等核心技术&#xff0c;同时提供了基于Vue的管理后台方便快速搭建系统。mall-swarm在电商业务的基础集成了注册中心…

陆游和辛弃疾都是南宋主战爱国的大才子,而且生活在同一个时代,有没有交集?

辛弃疾和陆游&#xff0c;都是宋朝著名的爱国诗人。但是这两位都没怎么做过正儿八经的大官&#xff0c;按照现代人的说法&#xff0c;他们总是在基层打嘴炮&#xff0c;对于朝廷的决策&#xff0c;他们是无能为力的。 这两位大诗人可以说生活在同一个年代&#xff0c;他们究竟…

【数据结构】算法的时间复杂度和空间复杂度详解

文章目录 一、算法的效率1.1 如何衡量一个算法的好坏1.2 算法的复杂度的概念 二、大O的渐进表示法三、时间复杂度2.1 时间复杂度的概念2.2常见时间复杂度计算举例 四、空间复杂度2.1 空间复杂度的概念2.2常见空间复杂度计算举例五、解决问题的思路LeetCode-exercise 总结 一、算…

Html5惯性小鸟游戏制作与分享(经典游戏)

当年电子词典中的经典游戏&#xff0c;后来出了无数变种的玩法。这里还原了最初的玩法与操作。实现了这一款有点难度“的怀旧经典游戏。 玩法也很简单&#xff0c;不用碰到任何东西、持续下去。。。 可以进行试玩&#xff0c;手机玩起来效果会更好些。 点击试玩 还有很多变种…