全文引用自《统计学习方法》(李航)

分类与回归树(classification and regression tree, CART)模型是由Breiman等人于1984年提出的另一类决策树算法。该算法同样由特征选择、树的生成以及树的剪枝三个部分组成,可以用于分类和回归问题。
CART算法生成的决策树为二叉树,其每个内部节点都对应训练数据中每个实例点的某个特征的具体值,节点以是否是该值来区分应进入的下一层节点方向,如“是”则进入左子树,“否”进入右子树。这种决策树等价于在每一层递归地将某个特征进行二分类,将输入空间不断二分为有限个单元,并在这些单元上确定预测的概率分布。算法的主要步骤如下:

  • 决策树的生成:根据输入的训练数据生成决策树,生成的决策树要尽量大;
  • 决策树的剪枝:利用验证数据集对生成的树进行剪枝并以损失函数最小为标准选择出最优子树。

下面将根据分类和回归问题分别介绍CART算法中决策树的生成算法,以及介绍决策树的剪枝算法。

1. CART生成算法

1.1 分类树的生成

分类树的生成就是不断地选择某一特征的某个值作为切分点,递归地构建一棵二叉树的过程,而最优特征的选择,采用基尼指数最小化为标准。
基尼指数(Gini index) 定义为:在分类问题中,假设有K个类,样本点属于第k类的概率为\(p_k\),那么概率分布的基尼指数为:
\[
Gini(p)=\sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp_k^2
\]
当针对二分类问题时,假设样本点属于第1类的概率为p,那么概率分布的基尼指数为:
\[
Gini(p)=2p(1-p)
\]
对于给定的样本集合D,其基尼指数为:
\[
Gini(D)=1-\sum_{k=1}^K\left(\frac{|C_k|}{|D|}\right)^2
\]
其中,\(C_k\)是D中属于第k类的样本的子集,K是类的个数。
若样本集合D按照特征A是否是某一个值a,被分割成\(D_1\)和\(D_2\)两个部分,即
\[
D_i=\{(x,y)\in D|A(x)=a\},D_2=D-D_1
\]
那么在特征A=a的条件下,集合D的基尼指数定义为:
\[
Gini(D,A=a)=\frac{|D_1|}{|D|}Gini(D_1)+\frac{|D_2|}{|D|}Gini(D_2)
\]
基尼指数Gini(D)代表了集合D的不确定性,基尼指数Gini(D,A=a)代表了经过A=a分割后的集合D的不确定性,与熵相似,基尼指数越大,则样本集合的不确定性就越大。
而CART算法就是选择基尼指数最小的特征及其值作为切分点来建立决策树。具体的算法过程如下:

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

根据训练数据集,从根节点开始,递归地对每个节点做如下操作,以建立二叉树:

  1. 设节点内的训练数据集为D,计算现有特征对该数据集的基尼指数,即针对每一个特征A的每一个可能取值a,根据样本点对A=a取“是”或是“否”,将D分割成\(D_1\)和\(D_2\),并计算Gini(D,A=a)。
  2. 在所有的可能的特征A和其可能取值a中,选择基尼指数最小的特征和对应的值作为最优特征和最优切分点,将训练数据集切分为两个子集,生成两个子节点,将对应的子集分配到相应的节点上。
  3. 对两个子节点递归地调用1,2两步,直到满足停止条件为止。
    停止条件为:当节点中样本个数小于阈值,或样本集的基尼指数小于预定的阈值(样本基本上属于同一类)时,或没有更多的特征时,计算停止。
  4. 生成CART决策树。
1.2 回归树的生成

回归树的生成同样是不断地选择某一特征的某个值作为切分点,递归地构建一棵二叉树的过程,而最优特征的选择,采用平方误差最小化为标准。
假定X与Y分别为输入和输出变量,且Y为连续变量,给定的训练数据集为
\[
D=\{(x_1,y_1),(x_2,y_2),\cdots,(x_{_N},y_{_N})\}
\]
一棵回归树对应着输入空间的一个划分,以及在每个划分后的单元空间上的一个输入值。假定输入空间已经被划分为M个单元\(R_1,R_2,\cdots,R_M\),并且在每个单元上有一个固定的输出值\(c_m\),那么回归树的模型可以表示为:
\[
f(x)=\sum_{m=1}^Mc_mI(x\in R_m)
\]
当输入空间的划分确定后,就可以用平方误差\(\sum_{x_i\in R_m}(y_i-f(x_i))^2\)来表示回归树对训练数据的预测误差,用平方误差最小的准则求解每个单元上的最优输出,可知单元\(R_m\)上的\(c_m\)的最优值\(\hat{c_m}\)是\(R_m\)上所有输入实例\(x_i\)对应的输出\(y_i\)的均值,即:
\[
\hat{c_m}=\operatorname{ave}(y_i|x_i\in R_m)
\]
在对输入空间的划分上,采用启发式方法。选择第j个变量\(x^{(j)}\)和它的取值s,作为切分变量和切分点,并定义两个区域:
\[
R_1(j,s)=\{x|x^{(j)}\le s\},R_2(j,s)=\{x|x^{(j)}\gt s\}
\]
然后寻找最优切分变量j和最优切分点s,具体需求解:
\[
\min_{j,s}\left[\min_{c_1}\sum_{x_i\in R_1(j,s)}(y_i-c_1)^2+\min_{c_2}\sum_{x_i\in R_2(j,s)}(y_i-c_2)^2\right]
\]
对固定输入变量j可以找到最优切分点s。
\[
\hat{c_1}=\operatorname{ave}(y_i|x_i\in R_1),\hat{c_2}=\operatorname{ave}(y_i|x_i\in R_2)
\]
遍历所有的输入变量,找到最优的切分变量j,构成一个(j,s)对,以此将输入空间划分为两个区域。重复以上过程,知道满足条件为止,就可以生成一棵回归树。这种回归树通常称为最小二乘树(least squares regression tree)
具体的算法过程如下:

  • 输入:训练数据集D;
  • 输出:回归树f(x)。
    在训练集中,递归地将每个区域划分Wie两个子区域并决定每个子区域上的输出值,构建二叉树。
  1. 选择最优切分变量j和切分点s,求解
    \[
    \min_{j,s}\left[\min_{c_1}\sum_{x_i\in R_1(j,s)}(y_i-c_1)^2+\min_{c_2}\sum_{x_i\in R_2(j,s)}(y_i-c_2)^2\right]
    \]
    遍历变量j,对固定的切分变量j扫描切分点s,选择使上式最小的值对(j,s);
  2. 用选定的对(j,s)划分区域并决定相应的输出值:
    \[
    \begin{aligned}
    R_1(j,s)=\{x|x^{(j)}\le s\},R_2(j,s)=\{x|x^{(j)}\gt s\}\\
    \hat{c_1}=\operatorname{ave}(y_i|x_i\in R_1),\hat{c_2}=\operatorname{ave}(y_i|x_i\in R_2)
    \end{aligned}
    \]
  3. 继续讲两个子区域递归调用1-2步,直到满足停止条件;
  4. 将输入空间划分为M个子区域\(R_1,R_2,\cdots,R_M\),生成决策树:
    \[
    f(x)=\sum_{m=1}^Mc_mI(x\in R_m)
    \]

2.CART剪枝

CART生成算法生成的子树是"完全生长"而成的决策树,其复杂度非常大,需要从底端开始剪去一部分子树,降低复杂度,使模型变得更简单,从而能够对未知的数据有准确的预测。CART剪枝算法主要有两步,首先从生成的决策树底端开始不断进行剪枝,直到根节点,形成一个子树序列\(\{T_0,T_1,\cdots,T_n\}\),然后通过交叉验证的方法,在独立的验证集上对子树的序列进行测试,选择最优的子树。

2.1 剪枝,形成子树序列

在剪枝的过程中,计算子树的损失函数:
\[
C_\alpha(T)=C(T)+\alpha|T|
\]
其中,T为任意子树,|T|为子树的叶节点个数,C(T)为对训练数据的预测误差(如基尼指数),\(\alpha\ge 0\)为参数,\(C_\alpha(T)\)为参数是\(\alpha\)时的子树T的整体损失。
对于固定的\(\alpha\),一定存在一个使损失函数\(C_\alpha(T)\)最小的子树,将其表示为\(T_\alpha\),\(T_\alpha\)在损失函数\(C_\alpha(T)\)最小的意义下是最优的。当\(\alpha\)大时,最优子树\(T_\alpha\)规模偏小,当\(\alpha\)小时,最优子树\(T_\alpha\)规模偏大。极端情况下,当\(\alpha = 0\)时,生成算法生成的整体树就是最优的,当\(\alpha \rightarrow\infty\)时,根节点组成的单节点树是最优的。
由Breiman等人证明,可以用递归的方法对树进行剪枝,将\(\alpha\)从小增大,\(0=\alpha_0<\alpha_1<\cdots<\alpha_n<+\infty\),可以产生一系列的区间\([\alpha_i,\alpha_{i+1}),i=0,1,\cdots,n;\)剪枝得到的子树对应着区间\(\alpha\in[\alpha_i,\alpha_{i+1}),i=0,1,\cdots,n\)的最优子树序列\(\{T_0,T_1,\cdots,T_n\}\),序列中的子树是嵌套的。
具体的过程为,从整体\(T_0\)开始剪枝,对\(T_0\)的任意内部节点t,以t为单节点树的损失函数为
\[
C_\alpha(t)=C(t)+\alpha
\]
以t为根节点的子树\(T_t\)的损失函数为
\[
C_\alpha(T_t)=C(T_t)+\alpha|T_t|
\]
当\(\alpha = 0\)及\(\alpha\)很小时,有\(C_\alpha(T_t) < C_\alpha(t)\),
当\(\alpha\)增大到某一值时,有\(C_\alpha(T_t) = C_\alpha(t)\),
当\(\alpha\)继续增大时,有\(C_\alpha(T_t) > C_\alpha(t)\)。
只需\(\alpha=\frac{C(t)-C(T_t)}{|T_t|-1},T_t\)与t有相同的损失函数,而t的节点更少,因此t比\(T_t\)更可取,对\(T_t\)进行剪枝。
因此,对\(T_0\)中每个内部节点t,计算
\[
g(t)=\frac{C(t)-C(T_t)}{|T_t|-1}
\]
表示剪枝后的整体损失函数减少的程度。在\(T_0\)中减掉g(t)最小的子树\(T_t\),因为减去它的损失函数减小程度最小,将得到的子树作为\(T_1\),同时设最小的g(t)为\(\alpha_1,T_1\)为区间\([\alpha_1,\alpha_2)\)的最优子树。
按照以上过程,不断进行剪枝,直到最后得到的结果为根节点,在这一过程中,不断增加\(\alpha\)的值,不断产生新的区间。

2.2 对得到的子树序列进行交叉验证,选择最优子树

主要利用独立的验证数据集,测试子树序列\(T_0,T_1,\cdots,T_n\)中各个子树的平方误差或基尼指数。选择平方误差或基尼指数最小的决策树作为最优决策树并返回。在给定的子树序列中,每颗子树都对应着一个\(\alpha\)值,因此当最优子树确定时,对应的\(\alpha\)也会确定。

剪枝的主要算法过程如下:

  • 输入:CART算法生成的决策树\(T_0\);
  • 输出:最优决策树\(T_\alpha\).
  1. 设\(k=0,T=T_0\);
  2. 设\(\alpha = +\infty\);
  3. 自上而下对各个内部节点t计算\(C(T_t),|T_t|\)以及
    \[
    \begin{aligned}
    g(t)=\frac{C(t)-C(T_t)}{|T_t|-1}\\
    \alpha = \min(\alpha,g(t))
    \end{aligned}
    \]
    其中\(T_t\)表示以t为根节点的子树,\(C(T_t)\)为对训练数据的预测误差,\(|T_t|\)是\(T_t\)的叶节点个数;
  4. 自上而下地访问内部结点t,若有\(g(t)=\alpha\),进行剪枝,即选择g(t)最小的子树进行剪枝,并对叶节点t以多数表决的方法决定该节点的类,得到树T;
  5. 设\(k=k+1,\alpha_k=\alpha,T_k=T\);
  6. 若T不是有根节点单独构成的树,那么回到步骤4;
  7. 得到子树序列\(T_0,T_1,\cdots,T_n\),利用交叉验证法选择最优的子树\(T_\alpha\)。

通过以上过程,就可以选取最优的回归或分类决策树。

统计学习五:3.决策树的学习之CART算法的更多相关文章

  1. TweenMax动画库学习(五)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  2. SVG 学习<五> SVG动画

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  3. 《机器学习实战》学习笔记第九章 —— 决策树之CART算法

    相关博文: <机器学习实战>学习笔记第三章 —— 决策树 主要内容: 一.CART算法简介 二.分类树 三.回归树 四.构建回归树 五.回归树的剪枝 六.模型树 七.树回归与标准回归的比较 ...

  4. 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试

    机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...

  5. 20145330第五周《Java学习笔记》

    20145330第五周<Java学习笔记> 这一周又是紧张的一周. 语法与继承架构 Java中所有错误都会打包为对象可以尝试try.catch代表错误的对象后做一些处理. 使用try.ca ...

  6. Android JNI学习(五)——Demo演示

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  7. git学习——<五>git分支

    git学习——<一>git安装 git学习——<二>git配置文件 git学习——<三>git操作 git学习——<四>git版本管理 一.提出问题 今 ...

  8. ZigBee学习五 无线温度检测

    ZigBee学习五 无线温度检测 1)修改公用头文件GenericApp.h typedef union h{ uint8 TEMP[4]; struct RFRXBUF { unsigned cha ...

  9. (转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射

    http://blog.csdn.net/yerenyuan_pku/article/details/71894172 在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中 ...

随机推荐

  1. Struts2-01

    一.Struts2的介绍 讲Struts2框架之前,我们需要知道框架是什么呢?估计大多数初学者都只知道其名却不知其意,框架就是一个半成品,别人将一些功能已经写好了,我们只需要拿来用即可,像我们之前使用 ...

  2. 『C++』Temp_2018_12_13_Type

    #include <iostream> #include <string> using namespace std; class Object{ public: virtual ...

  3. CentOS 6.8安装Ceph

    机器规划 IP 主机名 角色 10.101.0.1 ceph01 mon admin mds 10.101.0.2 ceph02 ods 10.101.0.3 ceph03 ods 10.101.0. ...

  4. CRT7.3.1版本安装步骤

    工具: Setup.exe安装程序 keygen.exe注册机 zwt.nfo 查看电脑信息(主要看自己电脑是x86还x64版本) 安装步骤(所有程序尽量以管理员身份启动) 1.安装SecureCRT ...

  5. PHP的发展历程

    PHP的发展历程 了解一门语言,我们必须知道这门语言的发展史,现在我通过版本的变化以时间轴的形式来说明PHP的发展历程. 1.1995年初PHP1.0诞生 Rasmus Lerdof发明了PHP,这是 ...

  6. TCC : Tiny C Compiler (2018-2-6)

    饭墙下载,有缘上传: https://files.cnblogs.com/files/bhfdz/tcc-0.9.27-win32-bin.zip https://files.cnblogs.com/ ...

  7. 找球号(三)南阳acm528(异或' ^ ')

    找球号(三) 时间限制:2000 ms  |  内存限制:10000 KB 难度:2   描述 xiaod现在正在某个球场负责网球的管理工作.为了方便管理,他把每个球都编了号,且每个编号的球的总个数都 ...

  8. 网易云音乐API

    网易云音乐API使用 封装了一些api调用 ZZRRegion/StNetease

  9. break和continue使用

    前面讲的循环,这里就是控制循环的东西 break其实在我们学习switch判断的时候就是用到了 break:代表跳出整个循环 continue和break的用法差不多 continue:代表只跳出当前 ...

  10. 20155335 俞昆 2016-2017-2 《Java程序设计》第九周学习总结

    学号 2016-2017-2 <Java程序设计>第九周学习总结 ##JDBC入门 在正式介绍JDBC前,已知JDBC是用来执行SQL的解决方案,开发人员使用JDBC的标准接口,开发人员不 ...