CART-分类和回归树
之前在博文 决策树归纳 中,我介绍了用决策树进行分类的算法,包括ID3和C4.5。然而决策树不仅可以用来做数据分类,也可用于做数据回归。1984年Breiman,Friedman,Olshen等人出版了著作《Classification and Regression Trees》(简称CART)介绍了二叉决策树的产生。他们给出了用二叉决策进行树数据分类和回归的方法。
在阅读本文之前,我假设读者已经了解了我之前写的“决策树归纳”中的知识点,包括决策树的基本构建方法,以及相关术语。然后我会分别介绍用于分类和回归两类计算任务的CART。
1. 分类树
1.1 基本步骤
用于分类的CART的构建方法与之前ID3和C4.5算法是非常类似的,都是采用贪心策略,自顶而下分治地构建树。只不过此处判断分裂后子集元素“纯”度的标准不是ID3中用的信息增益,也不是C4.5中用的增益率,而是用基尼指数。
基尼指数按照如下的计算方式度量一个训练集DDD的不纯度:
\begin{equation} Gini(D) = 1 - \sum_{i = 1}^m p_i^2 \end{equation}
其中pipip_i是某个元组属于类CiCiC_i的概率,可以用|Ci||D||Ci||D|\frac{|C_i|}{|D|}估计。而经过分裂之后,可以依据新得到的子节点,按照如下公式计算分裂后的基尼指数。
\begin{equation} Gini_A(D) = \sum_{j = 1}^k \frac{|D_j|}{|D|} Gini(D_j) \end{equation}
其中kkk为分裂后的子节点的个数,A" role="presentation">AAA是用于分裂的属性(即分裂准则)。以二叉决策树为例,就是:
\begin{equation} Gini_A(D) = \frac{|D_1|}{|D|} Gini(D_1) + \frac{|D_2|}{|D|} Gini(D_2) \end{equation}
这样,对于一个节点中包含的数据集DDD,我们的目标是去寻找最合适的分裂准则以及分裂值,使得经过分裂之后的基尼指数与分裂之前的基尼指数之差最大。这个差值如下计算得到:
\begin{equation} \Delta_A(D) = Gini(D) - Gini_A(D) \end{equation}
所以,CART作为分类树的算法步骤如下:
- 根节点包含所有的训练元组,每个元组由多个属性组成。我们按照分裂前后基尼指数的差值,找到最好的分裂准则以及分裂值,将根节点一分为二(CART是二叉树);
- 对于生成的子节点递归的执行1步的算法,直到(1)数据集为空;(2)属性列表为空;(3)节点中所有数据集属于同一类;
CART的构建本来到此就算是结束了。但是所有的决策树构建算法(包括我之前介绍的ID3和C4.5)都有可能存在过拟合的问题(尤其是训练数据存在一些噪声和离群点时)。虽然可以通过阈值控制终止条件,避免树形结构分支过细,还有随机森林这样一些方法防止过拟合,但是一般情况下最常用的还是剪枝。剪枝的操作我在之前介绍ID3和C4.5的时候并没有讲到,但它是决策树算法中非常关键的一环,是不可以跳过的。所以我放到本文中也算是对之前文章的一个补充。
1.2 剪枝
如果我们先建好决策树再进行剪枝(即所谓的后剪枝),那需要在初始构建决策树时让树完全增长直到所有的叶子节点都是纯的且具有零训练误差。然后找到过拟合的子树并剪掉它们。同时,剪枝导致决策树高度更低,分支更少,这也在一定程度上提高了数据分类(回归)的速度。
如果一棵子树需要被剪枝,那么剪枝之后这棵子树就变成了一个叶子节点,其类标记为原先子树的元组中出现最多次的类标记。比如下图中的左图,假如要把A3A3A_3分裂点为根的子树剪枝,而这棵子树中的数据类标号最多的是class B,那么剪枝后的决策树就变成下图中的右图模样。
现在剩下的问题就是在什么情况下需要对决策树的某个子树剪枝。简单想想就能想到,是否剪枝的评估标准肯定是子树的误差和子树复杂度(实际上就是叶子节点数)之间的平衡关系。根据这个原理,我们可以定义子树的损失函数:
\begin{equation} J(\tau) = E(\tau) + \lambda |\tau| \end{equation}\tag{1}
其中E(τ)E(τ)E(\tau)为子树的预测误差(比如用基尼指数计算),λλ\lambda为罚因子,|τ||τ||\tau|为子树的叶子节点数,相当于是对子树复杂度的评估。这个函数其实跟我之前介绍损失函数时提到的结构风险最小损失函数是一致的(可以参考博文 SVM解释:四、线性不可分的情况),都是“误差+惩罚复杂度”
现在我们设最初得到的决策树为τ0τ0\tau_0,那么对于τ0τ0\tau_0的任意内部节点(记为ccc)可以计算它的单节点损失函数:
\begin{equation} J(c) = E(c) + \lambda \end{equation}\tag{2}
也可以计算得到以ccc为根的子树的损失函数:
\begin{equation} J(\tau_c) = E(\tau_c) + \lambda |\tau_c| \end{equation}\tag{3}
由此我们不难得到:当λλ\lambda充分小时,J(c)>J(τc)J(c)>J(τc)J(c) > J(\tau_c),随着λλ\lambda增大,J(c)J(c)J(c)和J(τc)J(τc)J(\tau_c)之间的大小关系不断接近,当λλ\lambda大到一定程度时,J(c)=J(τc)J(c)=J(τc)J(c) = J(\tau_c),随着λλ\lambda继续增大,最终J(c)<J(τc)J(c)<J(τc)J(c) .
所以,如果找到了使得J(c)=J(τc)J(c)=J(τc)J(c) = J(\tau_c)的λλ\lambda,那此时单节点和子树的损失函数一致,单节点却结构更加简单,我们就选择剪枝。由公式(2),(3),我们可以推出J(c)=J(τc)J(c)=J(τc)J(c) = J(\tau_c)时的λλ\lambda为:
\begin{equation} \lambda = \frac{E(c) - E(\tau_c)}{|\tau_c| - 1} \end{equation}
上式中的λλ\lambda实际上是罚因子的阈值。因此,我们可以对于τ0τ0\tau_0中的每个内部节点ccc,计算他们的罚因子阈值。我们从小到大排列每个内部节点的罚因子阈值。先找到罚因子阈值最小的节点c" role="presentation">ccc,将以ccc为根的子树剪枝,剪枝之后的树记为τ1" role="presentation">τ1τ1\tau_1,那么τ1τ1\tau_1就是罚因子在区间[0,λ1)[0,λ1)[0, \lambda_1)内的最优决策树。以此类推,再对罚因子阈值次最小的节点c′c′c'剪枝,得到λ2λ2\lambda_2和τ2τ2\tau_2,τ2τ2\tau_2是[λ1,λ2)[λ1,λ2)[\lambda_1, \lambda_2)之间的最优决策树。。。直到剩下根节点单独存在,也就是不能再剪枝了。最终,假设一共得到n+1n+1n + 1个最优决策树{τ0,τ1,τ2,…,τn}{τ0,τ1,τ2,…,τn}\{\tau_0, \tau_1, \tau_2, \dots, \tau_n\},每个最优树对应着一个罚因子区间,其中τ0τ0\tau_0为初始决策树,τnτn\tau_n为只有单个节点的树。
接下来,我们利用独立的验证数据集,测试子树序列{τ1,τ2,…,τn}{τ1,τ2,…,τn}\{\tau_1, \tau_2, \dots, \tau_n\}中各棵子树的基尼指数或平方误差(平方误差是用于分类的CART的误差计算标准)。平方误差或基尼指数最小的决策树被认为是最优的决策树。
综上所述,我们可以这样描述决策树剪枝的过程:
设初始决策树为τ0τ0\tau_0,k=0k=0k = 0,λ=+∞λ=+∞\lambda = +\infty
自下而上,依次计算初始决策树的每个内部节点的罚因子阈值,计算公式如下:
g(c)=E(c)−E(τc)|τc|−1λk=min(λ,g(c))(6)(6)g(c)=E(c)−E(τc)|τc|−1λk=min(λ,g(c))\begin{equation} \begin{aligned} &g(c) = \frac{E(c) - E(\tau_c)}{|\tau_c| - 1}\\ &\lambda_k = \min(\lambda, g(c)) \end{aligned} \end{equation}
自上而下,依次检查内部节点,若某节点ccc满足g(c)=λk" role="presentation">g(c)=λkg(c)=λkg(c) = \lambda_k(也就是说这个节点在本轮迭代中是罚因子阈值最小的),那么对ccc为根的子树剪枝,剪枝后得到新的一棵树τk" role="presentation">τkτk\tau_k:
λ=λkk=k+1(7)(7)λ=λkk=k+1\begin{equation} \begin{aligned} &\lambda = \lambda_k\\ &k = k + 1 \end{aligned} \end{equation}
如果得到了只有单个节点的树,则结束迭代;否则,继续执行步骤2,3;
结束迭代后,得到一组最优决策树{τ0,τ1,τ2,…,τn}{τ0,τ1,τ2,…,τn}\{\tau_0, \tau_1, \tau_2, \dots, \tau_n\}。采用交叉验证法选择最优子树,选择的依据是分别计算这些子树的误差大小(比如基尼指数或平方误差),选择误差最小的子树为最终的剪枝结果。
2. 回归树的生成
训练回归树其实和训练分类树没有本质不同,也是自上而下,不断分裂节点的过程。不同之处在于对节点分裂的分裂准则和分裂值的选择方法上。我下面将一步步推导回归树的构建算法。
设有训练数据集D={(X1,y1),(X2,y2),…,(Xn,yn)}D={(X1,y1),(X2,y2),…,(Xn,yn)}D = \{(X_1, y_1), (X_2, y_2), \dots, (X_n, y_n)\}。我们知道决策树最终将数据元组划分到了多个叶子节点中,比如分类树的每个叶子就有一个类标号,作为元组的预测类。回归树的思路类似,我将数据空间划分成了mmm个区域{R1,R2,…,Rm}" role="presentation">{R1,R2,…,Rm}{R1,R2,…,Rm}\{R_1, R_2, \dots, R_m\},实际上就是将训练元组的分区。然后赋给每个区域有一个固定的代表值CiCiC_i(类似于分类树中的类标号),这样,回归树的模型可以表示成公式(4)的形式:
\begin{equation} f(X) = \sum_{i = 1}^m C_i I(X \in R_i) \end{equation}\tag{4}
其中I(X∈Ri)=1I(X∈Ri)=1I(X \in R_i) = 1,如果X∈RiX∈RiX \in R_i;否则,I(X∈Ri)=0I(X∈Ri)=0I(X \in R_i) = 0。这么看来,公式(4)的含义是:先判断XXX属于哪个区域,然后返回这个区域的代表值。
这样,我们可以写出对于某个区域Ri" role="presentation">RiRiR_i回归模型的损失函数:
\begin{equation} J(C) = \sum_{X_j \in R_i} (f(X_j) - g_i)^2 \end{equation}\tag{5}
其中,gigig_i为这个区域的代表值(这里用gigig_i而不用CiCiC_i的原因是我要表达gigig_i是分裂中间的某个区域的代表值,而CiCiC_i为最终完成分裂之后的叶子节点的代表值),gigig_i的计算方法一般是这个区域中的元组的yyy值的均值(取均值时,损失函数达到最优)。
\begin{equation} g_i = \frac{1}{N_i} \sum_{X_j \in R_i} y_i \end{equation}
其中,NiNiN_i为这个区域内数据元组的总数。初始时,所有的数据元组都在一个区域内,我们按照公式(5)计算损失函数,如果计算得到的误差值太大,不能满足要求,则寻找最佳的分裂准则(属性)和分裂值将数据集一分为二。这里的关键在于怎样的分裂准则和分裂值对于回归树来说是最佳的。其实很明显,“最佳”指我按照这样的属性和属性值将数据集一分为二后,使得分裂得到的两个子区域的误差和最小。
综上所述,回归树的计算步骤如下:
初始时,将所有训练元组放置于根节点中,计算损失函数得到误差值,倘若误差大于事先定好的参数,那么执行下面的2~4步;
选择用于分裂区域的属性AAA和对应的属性值s" role="presentation">sss,将当前节点的数据元组划分到以下两个区域R1,R2R1,R2R_1, R_2中。:
R1={X|xi≤s}; R2={X|xi>s};(9)(9)R1={X|xi≤s};R2={X|xi>s};\begin{equation} R_1 = \{X|x_i \leq s\}; ~~~~ R_2 = \{X|x_i > s\}; \end{equation}
其中xixix_i为元组XXX中属性A" role="presentation">AAA的值。而选择分裂属性AAA以及属性值s" role="presentation">sss的依据是使得分裂后的子区域误差值的和最小。即:min∑Xj∈R1(f(Xj)−y1)2+∑Xj∈R2(f(Xj)−y2)2(6)(6)min∑Xj∈R1(f(Xj)−y1)2+∑Xj∈R2(f(Xj)−y2)2\begin{equation} \min \sum_{X_j \in R_1} (f(X_j) - y_1)^2 + \sum_{X_j \in R_2} (f(X_j) - y_2)^2 \end{equation}\tag{6}
这一步具体执行的时候,我们遍历所有的属性以及每个属性的所有可能的划分值,分别计算他们划分数据元组之后的两个子区域的代表值y1,y2y1,y2y_1, y_2,这样就可以计算R1,R2R1,R2R_1, R_2的误差和(公式(6)),最终选择误差和最小的属性AAA和属性值s" role="presentation">sss,作为分裂依据。剪枝。
CART-分类和回归树相关推荐
- CART分类与回归树
一.CART分类与回归树 资料转载: http://dataunion.org/5771.html http://blog.sina.com.cn/s/blog_afe2af380102x020.ht ...
- 数据挖掘十大经典算法--CART: 分类与回归树
一.决策树的类型 在数据挖掘中,决策树主要有两种类型: 分类树 的输出是样本的类标. 回归树 的输出是一个实数 (例如房子的价格,病人呆在医院的时间等). 术语分类和回归树 (CART) 包含了上述 ...
- CART分类与回归树的原理与实现
算法概述 CART(Classification And Regression Tree)算法是一种决策树分类方法. 它采用一种二分递归分割的技术,分割方法采用基于最小距离的基尼指数估计函数,将当前的 ...
- CART 分类和回归树
背景 CART(Classification And Regression Tree)可以做分类树也可以做回归树.注意特征可以是不同的类别,标签也可以是不同的类别. 回归树 求最优的数据切分点,首先要 ...
- ML之DT之CART:分类与回归树CART算法的简介、应用、经典案例之详细攻略
ML之DT之CART:分类与回归树CART算法的简介.应用.经典案例之详细攻略 目录 分类与回归树CART算法简介 1.CART原理-比较ID3.C4.5 2.CART算法描述 CART算法的案经典案 ...
- 分类与回归树(CART)相关知识
文章目录 CART算法 CART回归树生成 CART分类树的生成 连续值处理: 离散值处理: CART 剪枝 CART算法 分类与回归树(CART)是应用广泛的算法,同样由特征选择.树的生成及剪枝组成 ...
- 1. 分类与回归树原理(CART)
1. 简介 分类与回归树(Classification And Regression Tree),采用二分递归分割技术,将当前样本集划分成两个子集,即其结构为二叉树,每个内部节点均只有两个分支.左分支 ...
- 决策树之CART 算法(回归树,分类树)
CART 算法,英文全称叫做 Classification And Regression Tree,中文叫做分类回归树. ID3 和 C4.5 算法可以生成二叉树或多叉树,而 CART 只支持二叉树. ...
- 决策树6:分类与回归树CART
0x01 概念介绍 1.1 CART算法 CART算法:Classification And Regression Tree.顾名思义,CART算法既可以用于创建分类树(Classification ...
- 经典算法详解--CART分类决策树、回归树和模型树
Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Reg ...
最新文章
- 批量启用lync用户-3
- [原创] Matlab 指派问题模型代码
- ubuntu14.04下的NVIDIA Tesla K80显卡驱动的安装教程
- DevExpress的TreeList怎样设置数据源,从实例入手
- mysql字段A复制到字段B,并替换指定字符
- 有关嵌入式、单片机、51单片机、STM32、的一些概念详解
- 单代号网络图计算例题_如何把横道图转化成双代号网络图?
- 最后一波机会!!本周你最不能错过的互联网大会,VIP门票0元限时抢!
- 机器学习 - 训练集、验证集、测试集
- 央行数字货币离我们还有多远?
- iPad的尺寸与分辨率
- Elasticsearch - Indices stats 获取索引级别的统计信息之三 【indexing】索引操作信息
- circos 可视化手册-links 篇
- Windows服务优化(整理篇)
- 明日之后各个服务器的信息,明日之后三个字的和四个字的区什么不同 服务器区别详解...
- 【题解】【AcWing】1635. 最大团
- pr怎么把视频去水印
- Wifi无法自动连接的问题
- 爬虫——爬取网页数据存入表格
- Gate使用手册(四)数据输出