决策树之 CART
继上篇文章决策树之 ID3 与 C4.5,本文继续讨论另一种二分决策树 Classification And Regression Tree,CART 是 Breiman 等人在 1984 年提出的,是一种应用广泛的决策树算法,不同于 ID3 与 C4.5, CART 为一种二分决策树, 每次对特征进行切分后只会产生两个子节点,而ID3 或 C4.5 中决策树的分支是根据选定特征的取值来的,切分特征有多少种不同取值,就有多少个子节点(连续特征进行离散化即可)。CART 设计回归与分类,接下来将分别介绍分类树与回归树。
回归树与模型树
首先简单回忆线性回归:是对于数据集 $D = \left \{(x_i,y_i) \right \}_{i=1}^N$ ,线性回归的模型为:$ \bar{y}_i = \theta ^T x_i $,损失函数可以记做:
\[L(\theta) = \frac{1}{N}\sum_i( y_i - \bar{y}_i )^2\]
或者向量形式(参考NG),对于 $Y = X\theta$ ,损失函数为 $\frac{1}{2}(X\theta-y)^T(X\theta-Y) $,对 $\theta$ 求导,即得:
\[\theta = (X^TX)^{-1}X^TY\]
Liner Regression 已经很强大,可以处理线性数据集,对于非线性数据集,可以考虑增加特征的办法,比如引入高次特征或者进行特征组合来增加模型的非线性能力。如果数据集不是很大,可以考虑不加特征的局部加权回归,这里需要考虑一个概念,即 Parametric 算法与 Non-Parametric 算法,简单介绍一下,Parametric 算法会用训练集训练数据得到模型参数,用做之后的预测;Non-Parametric 算法则并不会学习得到通用的参数,而是根据需求拟合模型。所以线性回归可以认为是一种 Parametric 学习算法,那么局部加权回归可以认定为非参数方法,因为局部加权只考虑离待预测样本 $x$ 近的那些点,所以对于待测样本,都要遍历数据集进行运算,速度会很慢,局部加权回归还对损失函数进行了一些改进:
\[L(\theta) = \frac{1}{N}\sum_iw_i(\bar{y}_i - y_i)\]
\[w_i = exp \left (\frac{x_i-x}{2 \tau ^2} \right ) \]
这里 $\tau$ 控制了权值变化的速率,每个样本 $x_i$ 都有一个权值,权值根据 $\tau$ 来调整大小,离样本点 $x_i$ 越近的样本其权值却大,局部加权回归的预测模型同线性回归。值得注意的问题还有特征归一化与正则化,这里不展开了,关于局部加权回归与线性回归的图形分别如下:
线性回归是一个关于全局数据的模型,用一个唯一的目标优化来优化全数据集。当数据并呈现分段特性的时候,比如如下图所示的数据,全局共享一个优化目标显然不是一个很好的选择。这时可以对数据集进行划分,分而治之明显是一个不错的选择。下图所示的数据可以划分为 5 个分片分别进行处理,分片之后可以对每个分片做一个线性模型,这种情况称之为模型树;也可以简单的对分片后的数据取均值,这种情况就是普通的回归树。接下来分别对回归树与模型树进行介绍。
回归树采用均方误差作为损失函数,树生成时会递归的按最优特征与最优特征下的最优取值对空间进行划分,直到满足停止条件为止,停止条件可以人为设定,比如说设置某个节点的样本容量小于给定的阈值 $c$ ,或者当切分后的损失减小值小于给定的阈值小于给定的 $\varepsilon $,则停止切分,生成叶节点。
对于生成的回归树,每个叶节点的类别为落到该叶节点数据的标签的均值,假设特征空间被划分为 $M$ 个部分,即现在有 $M$ 个叶节点分别为 $R_1,R_2,…,R_M$ , 对应的数据量分别为 $N_1,N_2,…,N_M$ ,则叶节点的预测值分别为:
\[c_m = \frac{1}{N_m}\sum_{x_i \in R_m} y_i \tag{*}\]
回归树为一颗二叉树,每次都是按特征下的某个取值进行划分,每一个内部节点都是做一个对应特征的判断,直至走到叶节点得到其类别,构建这棵树的难点在于如何选取最优的切分特征与切分特征对应的切分变量。回归树与模型树既可以处理连续特征也可以处理离散特征,对于连续特征,若这里按第 $j$ 个特征的取值 $s$ 进行切分,切分后的两个区域分别为:
\[R_1(j,s) = \left \{ x_i|x_i^j \le s \right \} \ \ \ R_2(j,s) = \left \{ x_i|x_i^j > s \right \}\]
若为离散特征,则找到第 j 个特征下的取值 s :
\[R_1(j,s) = \left \{ x_i|x_i^j = s \right \} \ \ \ R_2(j,s) = \left \{ x_i|x_i^j \ne s \right \}\]
根据 $(*)$ 分别计算 $R_1$ 与 $R_2$ 的类别估计 $c_1$ 与 $c_2$, 然后计算按 $(j,s)$ 切分后得到的损失:
\[\min_{j,s} \left [ \sum _{x_i \in R_1}(y_i –c_1)^2 + \sum_{x_i \in R_2} (y_i –c_2)^2 \right ]\]
找到使损失最小的 $(j,s)$ 对即可,递归执行 $(j,s)$ 的选择过程直到满足停止条件为止。这里以连续特征为例,给出回归树的算法:
输入: 训练数据集 $D=\left\{ (x_1,y_1),(x_2,y_2),…,(x_N,y_N)\right\}$
输出: 回归树 $T$
1)求解选择切分特征 $j$ 与 切分特征取值 $s$ ,$j$ 将训练集 $D$ 划分为两部分,$R_1$ 与 $R_2$ ,依照$(j,s)$ 切分后如下:
\[R_1(j,s) = \left \{ x_i|x_i^j \le s \right \} \ \ \ R_2(j,s) = \left \{ x_i|x_i^j > s \right \}\]
\[c_1 = \frac{1}{N_1}\sum_{x_i \in R_1} y_i \ \ \ \ c_2 = \frac{1}{N_2}\sum_{x_i \in R_2} y_i \]
2)遍历所有可能的解$(j,s)$,找到最优的 $(j^*,s^*)$ ,最优的解使得对应损失最小,按照最优特征 $(j^*,s^*)$ 来切分即可。
\[\min_{j,s} \left [ \sum _{x_i \in R_1}(y_i –c_1)^2 + \sum_{x_i \in R_2} (y_i –c_2)^2 \right ]\]
3)递归条用 $1) \sim 2)$ ,知道满足停止条件。
4)返回决策树 $T$.
回归树主要采用了分治策略,对于无法用唯一的全局线性回归来优化的目标进行分而治之,进而取得比较准确的结果,但分段取均值并不是一个明智的选择,可以考虑将叶节点设置为一个线性函数,这便是所谓的分段线性模型树。为什么模型树效果好呢,可以通过下图来观察,左边为回归树,右边为模型树,可以看到模型树的效果还是好一些。
模型树只需在回归树的基础上稍加修改即可,对于分到叶节点的数据,采用线性回归的最小均方损失来计算该节点的损失,具体的求解方法可以参考 《Machine Learning in Action》 这本书。
分类树
分类树是 CART 中用来分类的了,不同于 ID3 与 C4.5 ,分类树采用基尼指数来选择最优的切分特征,而且每次都是二分。
基尼指数是一个类似与熵的概念,对于一个有 $K$ 种状态对应的概率为 $p_1,p_2,…,p_K$ 的随机变量 $X$ ,其 $Gini$ 定义如下:
\[Gini(X) = \sum_k p_k (1-p_k) = 1-\sum_k p_k^2\]
根据公式可得到伯努利分布 $X \sim Bernoulli(p)$ 的基尼系数为:
\[Gini(X) = \sum_k p_k (1-p_k) = 2p(1-p)\]
对于训练数据集合 $D$ ,假设共有 $K$ 个类别,$C_k$ 代表第 $k$ 类的样本子集,$|C_k|$ 为 $C_k$ 的大小,$|D|$ 为 $D$ 的大小,则集合 $D$的基尼系数为:
\[Gini(D) = \sum_k \frac{|C_k|}{|D|}(1-\frac{|C_k|}{|D|}) = 1- \sum_k \left (\frac{|C_k|}{|D|}\right )^2\]
类似于 $ID3$ 中的信息增益,假设现在用特征 $A$ 对数据进行分割,若特征 $A$ 为离散特征,则根据 $A$ 的某一可能取值 $a$ 将 $D$ 分为 $D_1$ 与 $D_2$
\[D_1 =\left \{D | A=a \right \} \ \ \ D_2 = \left \{D | A \ne a \right \} \]
其实就跟回归树一样,对于连续特征,也类似于回归树。接下来便得到类似于条件熵的一个量 $Gini(D,A)$ ,即在已知特征 $A$ 的条件下集合 $D$ 的基尼指数:
\[Gini(D,A) = \frac{|D_1|}{|D|}Gini(D_1) + \frac{|D_2|}{|D|}Gini(D_2)\]
$Gini(D,A)$ 取值越大,样本的不确定性也越大,这一点与熵类似,所以选择特征 $A$ 的标准是 $Gini(D,A)$ 的取值越小越好。接下来以离散特征为例,给出分类树算法:
输入:训练数据集 $D=\left\{ (x_1,y_1),(x_2,y_2),…,(x_N,y_N)\right\}$ ,停止条件
输出:分类树 $T$
1)利用特征 $A$ 的取值 $a$ 将数据分为两部分,计算 $A=a$ 时的基尼系数:
\[Gini(D,A) = \frac{|D_1|}{|D|}Gini(D_1) + \frac{|D_2|}{|D|}Gini(D_2)\]
2)对整个数据集中所有的可能特征 $A$ 以及其可能取值 $a$ 选取基尼系数最小的特征 $A^*$ 与特征下的取值 $a^*$,来将数据集切分,将数据 $D_1$、$D_2$ 分到两个子节点中去。
3)对子节点递归的调用 $1) \sim 2)$ ,直至满足停止条件
4)返回 CART 树 $T$
算法的停止条件可以是节点中的样本数不能小于给定阈值,或者样本集的基尼系数小于给定阈值,或者没有更多的特征。最后给出一个 CART 用于分类的图:
剪枝
CART 中同样需要对生成的树进行剪枝操作,来避免模型过度拟合训练数据,类似于ID3,剪枝时使用的损失函数如下:
\[C_a(T) = C(T) + a|T|\]
$C(T)$为树 $T$ 对训练数据的误差,可以用基尼系数或者均方损失来表示,$a \ge 0$ 代表一个权衡训练数据损失 $C(T)$ 与总节点数 $|T|$ 的参数,$C_a(T)$ 代表了树 $T$ 的整体损失,对于固定的 $a $,一定存在一个确定的使得 $C_a(T)$ 最小的子树,当 $a$ 偏大时, $|T|$ 偏小,树 $T$ 的规模偏小,反之,树 $T$ 的规模偏大,Breiman 等人采用递归的方法对 CART 进行剪枝,将 $a$ 从小增大 $0=a_0 < a_1<…<a_n$ ,如此产生的区间 $a \in [a_i,a_{i+1}) , \ i =1,2,…,n$ ,用对应此区间的 a 产生一系列的子树序列 $\left\{T_0,T_1,…,T_n \right\}$ 这里 $T_{i+1}$ 总是由 $T_i$ 剪枝后产生。
剪枝是从 $T_0$ 开始的,对 $T_0$ 的任意内部节点 $t$ ,把节点 $t$ 看做叶节点计算其损失函数:
\[C_a(t) = C(t) + a|1|\]
然后计算以 $t$ 为根节点时,子树 $T_t$ 的损失函数
\[C_a(T_t) = C(T_t)+ a|T_t|\]
要不要把 $t$ 的子树 $T_t$ 归并到 $t$ 上呢,关键看这个损失了,如果单节点 $t$ 的损失小于或等于整个子树 $T_t$ 的损失,合并当然好了,啥时候 $C_a(t) = C_a(T_t)$ 呢?如下所示:
\[C_a(t) = C_a(T_t) \Rightarrow C(t) + a|1| = C(T_t)+ a|T_t| \Rightarrow a=\frac {C_t-C(T_t)}{|T_t|-1}\]
明显的,只要满足以上条件, $T_t$ 与 $t$ 具有相同的损失,而且 $t$ 的节点少,所以进行剪枝,剪枝就是这么一个过程:
从 $T_0$ 开始,对于每一个内部节点 $t$ ,计算:
\[g(t) = \frac {C_t-C(T_t)}{|T_t|-1}\]
$g(t)$ 表示剪枝后整体损失函数的减小的程度,在 $T_0$ 中剪掉 $g(t)$ 最小的树 $T_t $ ,将得到的树称作 $T_1$ ,同时将最小的 $g(t) $设置为 $a_1$ , $T_1$ 为区间$[a_1,a_2)$上的最优子树,如此剪下去,在这一过程中,不断增加 $a$ 的取值,产生新的区间,最终会得到一组决策树 $\left\{T_0,T_1,…,T_n \right\}$ 对应一组确定的权衡参数 $\left\{a_0,a_1,…,a_n \right\}$ ,通过验证集合中每颗树的总体误差,也就得到了最终的最优决策树 $T^*$ ,这里给出CART 剪枝算法:
输入:CART 生成树 $T_0$
输出:剪枝后的最优树 $T^*$
1)设 $k = 0$ , $T = T_0$ ,$a=+\infty$
3) 自下而上的对内部节点 t 计算 :
\[g(t) = \frac {C_t-C(T_t)}{|T_t|-1} \]
\[a = min(a,g(t))\]
4) 自上而下的访问内部节点 $t$ , 对最小的 $g(t) = a$ 进行剪枝,并对叶节点 $t$ 以多数表决形式决定其类别,得到树 $T$
5) $k = k + 1$, $a_k = a $,$T_k = T$
6) 如果 $T$ 为非单节点树,回到 4).
7) 对于产生的子树序列 $\left\{T_0,T_1,…,T_n \right\}$ 分别计算损失,得到最优子树 $T^* $ 并返回.
至此,关于CART 的内容全部介绍完毕,CART 剪枝还是不同于 ID3 与 C4.5 的 , 另外 CART 为二叉树,且可用于回归。
参考:http://www.stat.cmu.edu/~cshalizi/350-2006/lecture-10.pdf
《统计学习方法》
《Machine Learning in Action》
决策树之 CART的更多相关文章
- 机器学习技法-决策树和CART分类回归树构建算法
课程地址:https://class.coursera.org/ntumltwo-002/lecture 重要!重要!重要~ 一.决策树(Decision Tree).口袋(Bagging),自适应增 ...
- 机器学习之决策树三-CART原理与代码实现
决策树系列三—CART原理与代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9482885.html ID ...
- 监督学习——决策树理论与实践(下):回归决策树(CART)
介绍 决策树分为分类决策树和回归决策树: 上一篇介绍了分类决策树以及Python实现分类决策树: 监督学习——决策树理论与实践(上):分类决策树 决策树是一种依托决策而建立起来的一种 ...
- 决策树之Cart算法一
Contents 1. CART算法的认识 2. CART算法的原理 3. CART算法的实现 1. CART算法的认识 Classification And Regression ...
- 机器学习:决策树(CART 、决策树中的超参数)
老师:非参数学习的算法都容易产生过拟合: 一.决策树模型的创建方式.时间复杂度 1)创建方式 决策树算法 既可以解决分类问题,又可以解决回归问题: CART 创建决策树的方式:根据某一维度 d 和某一 ...
- 决策树之CART算法
顾名思义,CART算法(classification and regression tree)分类和回归算法,是一种应用广泛的决策树学习方法,既然是一种决策树学习方法,必然也满足决策树的几大步骤,即: ...
- 《机器学习实战》学习笔记第九章 —— 决策树之CART算法
相关博文: <机器学习实战>学习笔记第三章 —— 决策树 主要内容: 一.CART算法简介 二.分类树 三.回归树 四.构建回归树 五.回归树的剪枝 六.模型树 七.树回归与标准回归的比较 ...
- 决策树2 -- CART算法
声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结.不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,因为本人在学习初始时有非常多数学知识都已忘记.所以为 ...
- 决策树(CART)
CART算法全称是分类回归算法,(Classification And Regression Tree),他与ID3.C4.5的不同在于: 1.既可以处理分类问题又可以处理回归问题 2.使用基尼系数作 ...
随机推荐
- 全注解的SSH框架
基于struts2.23 + spring2.5.6 + hibernate3.6.4 + hibernate-generic-dao1.0(除了spring,我整合的都是最新的GA包,hiberna ...
- MongoDB (九) MongoDB 投影
mongodb 投影意思是只选择必要的数据而不是选择一个文件的数据的整个.如果一个文档有5个字段,需要显示只有3个,然后选择其中只有3个字段. find() 方法 MongoDB 的find()方法, ...
- centOS学习part1:操作系统安装
0 linux作为服务器的主要操作系统,在处理速度以及安全性上都要优于windows,虽然需要很多命令要记,但是一般常用的命令不多,用多了就熟悉了,而且现在很多都要图形界面,也降低了学习成本. cen ...
- SinoSure
Sino,就是“中国.东方”的意思, 这个词只能作为前缀使用,不能单独讲.西方社会有时使用“Sino-”来表示“中国(的)”的意思,但是“Sino”均为连接词,并非单独用来表示“中国”之语.如表达中美 ...
- ADB not responding. You can wait more,or kill"abd.exe" process manually and click 'Restart'
在使用Android Studio进行开发的过程中,有时候编译运行时,会出现如下提示: ADB not responding. You can wait more,or kill"abd.e ...
- django中的filter详解
filter (数据过滤) 我们很少会一次性从数据库中取出所有的数据:通常都只针对一部分数据进行操作. 在Django API中,我们可以使用`` filter()`` 方法对数据进行过滤: > ...
- HDU 1941 Hide and Seek(离散化+树状数组)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1941 题意:给出平面上n个点,找出一点p,使得距离p最近和最远的点的距离之差最小.输出这 ...
- 关于VECTOR和DEQUE
http://www.cnblogs.com/ixnehc/archive/2008/09/02/1282356.html *.先说内部结构.vector就是一块连续的内存,这块连续的内存会随着成员 ...
- 详解Android中的屏幕方向
屏幕方向 是对Activity而言的,所以你可以在AndroidManifest.xml 文件中,通过<activity> 标记的screenOrientation 属性进行设定,例如: ...
- NPOI导出Excel表功能实现(多个工作簿)(备用)
Excel生成操作类: 代码 using System; using System.Collections.Generic; using System.Text; using System.IO; u ...