CART树算法解析加举例

article/2025/9/24 15:59:49

算法步骤

CART假设决策树是二叉树,内部结点特征的取值为“是”和“否”,左分支是取值为“是”的分支,右分支是取值为“否”的分支。这样的决策树等价于递归地二分每个特征,将输入空间即特征空间划分为有限个单元,并在这些单元上确定预测的概率分布,也就是在输入给定的条件下输出的条件概率分布。

CART算法由以下两步组成:

  1. 决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大; 
    决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时损失函数最小作为剪枝的标准。
  2. CART决策树的生成就是递归地构建二叉决策树的过程。CART决策树既可以用于分类也可以用于回归。本文我们仅讨论用于分类的CART。对分类树而言,CART用Gini系数最小化准则来进行特征选择,生成二叉树。 CART生成算法如下:

输入:训练数据集D,停止计算的条件: 
输出:CART决策树。

根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树:

设结点的训练数据集为D,计算现有特征对该数据集的Gini系数。此时,对每一个特征A,对其可能取的每个值a,根据样本点对A=a的测试为“是”或 “否”将D分割成D1和D2两部分,计算A=a时的Gini系数。 
在所有可能的特征A以及它们所有可能的切分点a中,选择Gini系数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。 
对两个子结点递归地调用步骤l~2,直至满足停止条件。 
生成CART决策树。 
算法停止计算的条件是结点中的样本个数小于预定阈值,或样本集的Gini系数小于预定阈值(样本基本属于同一类),或者没有更多特征。

Gini指数的计算

其实gini指数最早应用在经济学中,主要用来衡量收入分配公平度的指标。在决策树算CART算法中用gini指数来衡量数据的不纯度或者不确定性,同时用gini指数来决定类别变量的最优二分值得切分问题。

在分类问题中,假设有K个类,样本点属于第k类的概率为Pk,则概率分布的gini指数的定义为: 
这里写图片描述

如果样本集合D根据某个特征A被分割为D1,D2两个部分,那么在特征A的条件下,集合D的gini指数的定义为: 
这里写图片描述 
gini指数Gini(D,A)表示特征A不同分组的数据集D的不确定性。gini指数值越大,样本集合的不确定性也就越大,这一点与熵的概念比较类似。

所以在此,基于以上的理论,我们可以通过gini指数来确定某个特征的最优切分点(也即只需要确保切分后某点的gini指数值最小),这就是决策树CART算法中类别变量切分的关键所在。是不是对于决策树的CART算法有点小理解啦!其实,这里可以进一步拓展到我们对于类别变量的粗分类应用上来。比如我某个特征变量下有20多个分组,现在我只想要5个大类,如何将这个20多个类合并为5个大类,如何分类最优,以及如何找到最优的分类。这些建模初期的数据预处理问题其实我们都可以用gini指数来解决。

例子

这里写图片描述

首先对数据集非类标号属性{是否有房,婚姻状况,年收入}分别计算它们的Gini系数增益,取Gini系数增益值最大的属性作为决策树的根节点属性。根节点的Gini系数

Gini(是否拖欠贷款)=1−(3/10)^2−(7/10)^2=0.42

当根据是否有房来进行划分时,Gini系数增益计算过程为

这里写图片描述

Gini(左子节点)=1−(0/3)^2−(3/3)^2=0

Gini(右子节点)=1−(3/7)^2−(4/7)^2=0.4898

Δ{是否有房}=0.42−710×0.4898−310×0=0.077

若按婚姻状况属性来划分,属性婚姻状况有三个可能的取值{married,single,divorced},分别计算划分后的

  • {married} | {single,divorced}
  • {single} | {married,divorced}
  • {divorced} | {single,married}

的Gini系数增益。 
当分组为{married} | {single,divorced}时,Sl表示婚姻状况取值为married的分组,Sr表示婚姻状况取值为single或者divorced的分组

Δ{婚姻状况}=0.42−4/10×0−6/10×[1−(3/6)^2−(3/6)^2]=0.12

当分组为{single} | {married,divorced}时, 
Δ{婚姻状况}=0.42−4/10×0.5−6/10×[1−(1/6^)2−(5/6)^2]=0.053

当分组为{divorced} | {single,married}时, 
Δ{婚姻状况}=0.42−2/10×0.5−8/10×[1−(2/8)^2−(6/8)^2]=0.02

对比计算结果,根据婚姻状况属性来划分根节点时取Gini系数增益最大的分组作为划分结果,也就是{married} | {single,divorced}。 
最后考虑年收入属性,我们发现它是一个连续的数值类型。我们在前面的文章里已经专门介绍过如何应对这种类型的数据划分了。对此还不是很清楚的朋友可以参考之前的文章,这里不再赘述。

对于年收入属性为数值型属性,首先需要对数据按升序排序,然后从小到大依次用相邻值的中间值作为分隔将样本划分为两组。例如当面对年收入为60和70这两个值时,我们算得其中间值为65。倘若以中间值65作为分割点。Sl作为年收入小于65的样本,Sr表示年收入大于等于65的样本,于是则得Gini系数增益为

Δ(年收入)=0.42−1/10×0−9/10×[1−(6/9)^2−(3/9)^2]=0.02

其他值的计算同理可得,我们不再逐一给出计算过程,仅列出结果如下(最终我们取其中使得增益最大化的那个二分准则来作为构建二叉树的准则): 
这里写图片描述

注意,这与我们之前在《数据挖掘十大算法之决策树详解(1)》中得到的结果是一致的。最大化增益等价于最小化子女结点的不纯性度量(Gini系数)的加权平均值,之前的表里我们列出的是Gini系数的加权平均值,现在的表里给出的是Gini系数增益。现在我们希望最大化Gini系数的增益。根据计算知道,三个属性划分根节点的增益最大的有两个:年收入属性和婚姻状况,他们的增益都为0.12。此时,选取首先出现的属性作为第一次划分。

接下来,采用同样的方法,分别计算剩下属性,其中根节点的Gini系数为(此时是否拖欠贷款的各有3个records) 
Gini(是否拖欠贷款)=1−(3/6)^2−(3/6)^2=0.5

与前面的计算过程类似,对于是否有房属性,可得 
Δ{是否有房}=0.5−4/6×[1−(3/4)^2−(1/4)^2]−2/6×0=0.25

对于年收入属性则有: 
这里写图片描述

最后我们构建的CART如下图所示: 
这里写图片描述

最后我们总结一下,CART和C4.5的主要区别:

  • C4.5采用信息增益率来作为分支特征的选择标准,而CART则采用Gini系数;
  • C4.5不一定是二叉树,但CART一定是二叉树。

关于过拟合以及剪枝

决策树很容易发生过拟合,也就是由于对train数据集适应得太好,反而在test数据集上表现得不好。这个时候我们要么是通过阈值控制终止条件避免树形结构分支过细,要么就是通过对已经形成的决策树进行剪枝来避免过拟合。另外一个克服过拟合的手段就是基于Bootstrap的思想建立随机森林(Random Forest)。关于剪枝的内容可以参考文献【2】以了解更多,如果有机会我也可能在后续的文章里讨论它。

参考文献

【1】Wu, X., Kumar, V., Quinlan, J.R., Ghosh, J., Yang, Q., Motoda, H., McLachlan, G.J., Ng, A., Liu, B., Philip, S.Y. and Zhou, Z.H., 2008. Top 10 algorithms in data mining. Knowledge and information systems, 14(1), pp.1-37. (http://www.cs.uvm.edu/~icdm/algorithms/10Algorithms-08.pdf) 
【2】李航,统计学习方法,清华大学出版社


http://chatgpt.dhexx.cn/article/9sBU0BcV.shtml

相关文章

ID3、C4.5与CART树的联系与区别

ID3、C4.5与CART树的联系与区别: 参考博客: 链接1 链接2 特征选择准则: ID3的特征选择准则为信息增益,即集合D的经验熵H(D)与给定特征A下条件经验熵H(D|A)之差,即: H(D)表现了数据集D进行分类的不确定性…

决策树构建算法—ID3、C4.5、CART树

决策树构建算法—ID3、C4.5、CART树 决策树构建算法—ID3、C4.5、CART树 构建决策树的主要算法ID3C4.5CART三种算法总结对比 决策树构建算法—ID3、C4.5、CART树 构建决策树的主要算法 ID3C4.5CART (Classification And Rsgression Tree) ID3 ID3算法…

3-6 决策树、CART树、GBDT、xgboost、lightgbm一些关键点梳理

目录 1、决策树 2、CART树 2.1 CART分类树-输入样本特征;输出样本对应的类别(离散型) 2.2 CART回归树-输入样本特征;输出样本的回归值(连续型) 3、GBDT 3.1 提升树 3.2 GBDT 4、xgboost 4.1 损失函数及节点展开 4.2 精确贪心算法及相关近似算法…

CART树回归

说明:本博客是学习《python机器学习算法》赵志勇著的学习笔记,其图片截取也来源本书。 基于树的回归算法是一类基于局部的回归算法,通过将数据集切分成多份,在每一份数据中单独建模。与局部加权线性回归不同的是,基于…

剪枝、cart树

一、剪枝 1. 为什么要剪枝 在决策树生成的时候,更多考虑的是训练数据,而不是未知数据,这会导致过拟合,使树过于复杂,对于未知的样本不准确。 2. 剪枝的依据——通过极小化决策树的损失函数 损失函数的定义为&#x…

【机器学习】决策树——CART分类回归树(理论+图解+公式)

🌠 『精品学习专栏导航帖』 🐳最适合入门的100个深度学习实战项目🐳🐙【PyTorch深度学习项目实战100例目录】项目详解 数据集 完整源码🐙🐶【机器学习入门项目10例目录】项目详解 数据集 完整源码&…

CART树(分类回归树)

主要内容 (1)CART树简介 (2)CART树节点分裂规则 (3)剪枝 --------------------------------------------------------------------------------------------------------------------- 一、简介 CART…

CART树

算法概述 CART(Classification And Regression Tree)算法是一种决策树分类方法。 它采用一种二分递归分割的技术,分割方法采用基于最小距离的基尼指数估计函数,将当前的样本集分为两个子样本集,使得生成的的每个非叶子节点都有两个分支。因此…

Pytorch之view,reshape,resize函数

对于深度学习中的一下数据,我们通常是要变成tensor格式,并且需要对其调整形状,很多时候我们往往只关注view之后的结果(比如输出的尺寸),而不关心过程。但有时候还是要关注一下这个到底是怎么变换过来的&…

OpenCV-Python图像处理:插值方法及使用resize函数进行图像缩放

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 图像缩放用于对图像进行缩小或扩大,当图像缩小时需要对输入图像重采样去掉部分像素,当图像扩大时需要在输入图像中根据算法生成部分像素,二者都会利用插值算法来实现。 一…

vector的resize函数和reserve函数

博客原文:C基础篇 -- vector的resize函数和reserve函数_VampirEM_Chosen_One的博客-CSDN博客,写的特别好,谢谢原博主。 正文: 对于C的vector容器模板类,存在size和capacity这样两个概念,可以分别通过vect…

OpenCV 图片尺寸缩放——resize函数

文章目录 OpenCV中的缩放:resize函数代码案例 OpenCV中的缩放: 如果要放大或缩小图片的尺寸,可以使用OpenCV提供的两种方法: resize函数,是最直接的方式;pyrUp,pyrDown函数,即图像…

OpenCV的resize函数优化

背景 在使用OpenCV做图像处理的时候,最常见的问题是c版本性能不足,以resize函数为例来说明,将size为[864,1323,3]的函数缩小一半: Mat img0;gettimeofday(&t4, NULL);cv::resize(source, img0, cv::Size(cols_out,rows_out)…

C++ | resize函数的用法

最近在leetcode用C刷题,刚遇到一题需要给重新弄一个容器,并给容器初始化。新建容器要在private类中声明resize函数用来初始化preSum容器。 resize函数是C中序列式容器的一个共性函数,vv.resize(int n,element)表示调整容器vv的大小为n&#x…

opencv的resize函数

一、Opencv官方文档中resize的描述: resize Resizes an image. C: void resize(InputArray src, OutputArray dst, Size dsize, double fx0, double fy0, int interpolationINTER_LINEAR ) Python: cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) …

resize()函数

resize(),设置大小(size); reserve(),设置容量(capacity); size()是分配容器的内存大小,而capacity()只是设置容器容量大小,但并没有真正分配内存。 打个比方:正在建造…

OpenCV 图像缩放:cv.resize() 函数详解

目录 系列前言API函数详解参数列表缩放方式其一缩放方式其二两种方式的优先级关于插值方式 扩展 —— 相关函数 系列前言 这个系列是我第一个想要更下去的系列。每篇会全面介绍一个 OpenCV 函数,会给出 API 和示例。示例主要是用 Python 去写,但是 Open…

安卓中的几种线程间通信方式

一:Handler实现线程间的通信 andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。 在Android,这里的…

Java中的线程通信的几种方式

Java中的线程间通信是指不同线程之间相互协作,以完成一些复杂的任务或实现某些功能的过程。线程间通信主要包括两个方面:线程之间的互斥和同步,以及线程之间的数据共享和通信。Java提供了多种方式来实现线程间通信,本文将介绍Java…

创建线程的四种方式 线程通信

文章目录 1.1 创建线程1.1.1 创建线程的四种方式1.1.2 Thread类与Runnable接口的比较1.1.3 Callable、Future与FutureTask 1.2 线程组和线程优先级1.3 Java线程的状态及主要转化方法1.4 Java线程间的通信1.4.1 等待/通知机制1.4.2 信号量1.4.3 管道 1.1 创建线程 1.1.1 创建线…