机器学习系列(2)——CART算法

本文主要介绍CART算法,包括CART分类树/回归树的详细步骤和在sklearn中的参数等。

 

0x01、CART算法简介

CART(Classification and Regression Tree,分类与回归树)算法是决策树的一种实现,既可用于分类也可用于回归。它是一种二分递归分割技术,即把当前样本划分为两个子样本(即使特征有多个取值,也把数据分为两部分,当前被划分进同一部分的特征在之后的分割过程中将有机会被划分开来),使得生成的每个非叶子结点都有两个分支,因此CART算法生成的决策树是结构简洁的二叉树。

CART算法的几个特点:

(1)由任务目标决定CART是分类树还是回归树。当CART是分类树时,采用基尼系数(gini)作为特征划分的度量;当CART是回归树时,采用均方误差(mse)作为特征划分的度量。

(2)CART算法不仅可以处理二分属性,可以用来处理标称属性和连续属性(回归),简单来说,就是如果特征值大于或等于给定值就将该记录划分到左子树,否则就划分到右子树。

(3)决策树生成只考虑了对训练数据进行更好的拟合,而决策树剪枝考虑了减小模型复杂度。决策树生成学习局部的模型,决策树剪枝学习 整体的模型。一般选择损失函数最小作为剪枝的标准。

 

0x02、CART算法架构

1、CART算法总体描述

(1)决策树生成

a. 依次遍历每个特征A的可能取值a,对每个切分点(A, a)计算其基尼系数(分类树)或均方误差(回归树);

b. 选择最优切分点,然后使用该切分点将当前的数据集切分成两个子集;

c. 对上述切出的两个子集分别递归调用(a)和(b),直至满足停止条件,生成CART决策树。

(2)剪枝

a. 从决策树底端开始不断剪枝,直到决策树的根结点,形成一个子树序列;

b. 通过交叉验证法在独立的验证数据集上对子树序列进行测试,从中选择最优子树。

下面分别详细讨论特征选择过程和剪枝过程。

2、特征选择过程

(1)分类树

分类树用基尼指数选择最优特征,同时决定该特征的最优二值切分点。

【定义:基尼指数】分类问题中,假设有 K 个类,样本点属于第 k 类的概率为p_{k}, 则概率分布的基尼指数定义为:

        Gini(p) = \sum_{k=1}^{K} p_{k}(1 - p_{k}) = 1 - \sum_{k=1}^{K} p_{k}^{2}  

对于二分类问题,若样本点属于第1个类的概率是 p,则概率分布的基尼指数为:

        Gini(p) = 2p(1-p)  

对于给定的样本集合 D,其基尼指数为:( C_{k} 是 D 中属于第 k 类的样本子集,是类的个数。)

        Gini(D) = 1 - \sum_{k=1}^{K}\left ( \frac{|C_{k}|}{|D|} \right )^2  

【特征选择过程】若样本集合 D 根据特征 A 是否取某一可能值 a 被分割成 D_{1} 和 D_{2} 两部分,即

        D_{1} = \left\{ (x,y) \in D|A(x) = a \right\}, D_{2} = D - D_{1}  

则在特征 A 的条件下,集合 D 的基尼指数定义为:

        Gini(D, A) = \frac{|D_{1}|}{|D|}Gini(D_{1}) + \frac{|D_{2}|}{|D|}Gini(D_{2})   

基尼指数 Gini(D) 表示集合 D 的不确定性,基尼指数 Gini(D,A) 表示经 A=a 分割后集合 D 的不确定性。基尼指数越大,样本集合的不确定性也就越大。

(2)回归树(最小二乘回归树,least squares regression tree)

假设 XY 分别为输入和输出变量,并且 Y 是连续变量,给定训练数据集 D=\left\{ (x_{1},y_{1}),(x_{2},y_{2}), ..., (x_{N},y_{N}) \right\} 。

一棵回归树对应着输入空间(即特征空间)的一个划分以及在划分的单元上的输出值。假设已将输入的空间划分为 M 个单元 R_{1}, R_{2}, .., R_{M},并且每个单元 R_{m} 上有一个固定的输出值 c_{m},于是回归树模型可表示为:

         f(x) = \sum_{m=1}^{M}c_{m}I (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}} = average( y_{i} | x_{i} \in R_{m})  

采用启发式的方法,对输入空间进行划分。选择第 j 个变量 x^{(j)} 和它取的值 s,作为切分变量(splitting variable)和切分点(splitting point),并定义两个区域:

        R_{1}(j,s) = \left\{ x|x^{(j)} \leq s \right\}  和  R_{2}(j,s) = \left\{ x|x^{(j)} > s \right\}  

然后寻找最优切分变量 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 可以找到最优切分点

        \hat{c_{1}} = average(y_{i}|x_{i} \in R_{1}(j,s))  和  \hat{c_{2}} = average(y_{i}|x_{i} \in R_{2}(j,s))  

遍历所有输入变量,找到最优的切分变量 j,构成一个对 (j,s) 。依此将输入空间划分为两个区域。即完成一次特征选择过程。

3、剪枝过程

CART剪枝算法从完全生长的决策树底端剪去一些子树,使决策树模型变简单,从而能够对未知数据有更准确的预测。

(1)剪枝,形成一个子树序列

在剪枝过程中,计算子树的损失函数:

        C_{\alpha }(T) = C(T) + \alpha |T|  

其中,T 为任意子树,C(T) 为对训练数据的预测误差(如基尼指数),|T| 为子树的叶结点个数,\alpha\geq 0 为参数,C_{\alpha}(T) 为参数是 \alpha 时的子树 T 的整体损失,参数 \alpha 权衡训练数据的拟合程度与模型的复杂度。

对固定的 \alpha ,一定存在使损失函数 C_{\alpha}(T) 最小的字数,将其表示为 T_{\alpha}T_{\alpha} 在损失函数 C_{\alpha}(T) 最小的意义下是最优的,且这样的最优子树是唯一的。

用递归的方法对树进行剪枝。将 \alpha 从小增大,0=\alpha _{0} < \alpha_{1}<... <\alpha_{n}<+\infty ,产生一系列的区间 [\alpha_{i},\alpha_{i+1}), i=0,1,...,n ;剪枝得到的子树序列对应着区间 \alpha \in [\alpha_{i},\alpha_{i+1}), i=0,1,...,n 的最优子树序列 \left\{T_{0},T_{1},...,T_{n} \right\} ,序列中的子树是嵌套的。

从整体树 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}| ,

(i)当 \alpha=0 及 \alpha 充分小时,有不等式  C_{\alpha}(T_{t}) < C_{\alpha}(t) ;

(ii)当 \alpha 增大是,在某一 \alpha 值,有  C_{\alpha}(T_{t}) = C_{\alpha}(t) ;

(iii)当 \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} 中的每一个内部结点,计算

        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)在剪枝得到的子树序列中通过交叉验证选取最优子树

利用独立的验证数据集,测试子树序列 T_{0},T_{1},..., T_{n} 中各棵子树的平方误差(回归)或基尼指数(分类)。平方误差或基尼指数最小的决策树被认为是最优的决策树。在子树序列中,每棵子树 T_{1},T_{2},..., T_{n} 都对应于一个参数 \alpha_{1},\alpha_{2},..., \alpha_{n} 。所以,当最优子树 T_{k} 确定时,对应的 \alpha_{k} 也确定了,即得到最优决策树 T_{\alpha}

 

0x03、CART算法详细步骤

1、CART分类树生成算法

输入:训练数据集 D ,停止计算的条件;

输出:CART分类树。

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

(1)设结点的训练数据集为 D ,计算现有特征对该数据集的基尼指数。此时,对每个特征 A ,对其可能取的每个值 a ,根据样本点对 A=a 的测试为“是”或“否”,将 D 分割成 D_1D_2 两部分,计算 A=a 时的基尼指数:

        Gini(D, A) = \frac{|D_{1}|}{|D|}Gini(D_{1}) + \frac{|D_{2}|}{|D|}Gini(D_{2})  

(2)在所有可能的特征 A 以及它们的所有可能的切分点 a 中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。

(3)对两个子结点递归调用(1)和(2),直到满足停止条件(结点中的样本个数小于预定阈值,或样本集的基尼指数小于预定阈值,或没有更多特征)。

(4)生成CART分类树。

2、CART回归树生成算法

输入:训练数据集 D 

输出:CART回归树 f(x) 。

在训练数据集所在的输入空间中,递归地将每个区域划分为两个子区域并决定每个子区域上的输出值,构建二叉决策树:

(1)选择最优切分变量与切分点:遍历变量 j,对固定的切分变量扫描切分点 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 ]   

(2)用选定的对 (j,s) 划分区域并决定相应的输出值:

         R_{1}(j,s) = \left\{ x|x^{(j)} \leq s \right\}  ,  R_{2}(j,s) = \left\{ x|x^{(j)} > s \right\}  

         \hat{c_{m}} = \frac{1}{N_{m}} \sum_{x_{i} \in R_{m}(j,s)} y_{i}  ,x \in R_{m}  , m=1,2  

 (3)继续对两个子区域调用(1)和(2),直到满足停止条件;

(4)将输入空间划分为 M 个区域 R_{1}, R_{2}, .., R_{M} ,生成回归树 

          f(x) = \sum_{m=1}^{M}\hat{c_{m}}I (x\in R_{m})  

3、CART剪枝算法

输入:CART算法生成的决策树;

输出:最优决策树 T_{\alpha} 。

(1)设 k=0T=T_{0} ;

(2)设 \alpha = +\infty ;

(3)自下而上地对各内部结点 t 计算:对训练数据的预测误差 C(T_{t})T_{t} 的叶结点个数 |T_{t}| (T_{t} 表示 t 为根结点的子树),以及:

        g(t)=\frac{C(t)-C(T_{t})}{|T_{t}|-1} , \alpha = min(\alpha,g(t))  

(4)对 g(t)=\alpha 的内部结点 t 进行剪枝,并对叶结点 t 以多数表决法决定其类,得到树 T

(5)设 k=k+1\alpha_{k} = \alphaT_{k} = T

(6)若 T_{k} 不是由根结点及两个叶结点构成的数,则回到步骤(2),否则令 T_{k}=T_{n} ;

(7)采用交叉验证法在子树序列 T_{0}, T_1, ..., T_n 中选取最优子树 T_{\alpha} 。

 

0x04、CART算法在sklearn中的实现

sklearn.tree.DecisionTreeClassifier中,当参数criterion的值为“gini”时,就是一个CART树的实现。

参数说明:

(1)因参数 min_impurity_split 和 presort 将会在之后的版本中删除 ,这里就不列出了;

(2)标粗的三个参数random_state, min_impurity_decrease 和 ccp_alpha是最近几个版本新增的参数。

参数 参数类型 默认值 参数含义 详细说明
criterion

决策树:

{'gini','entropy'}
回归树:{'mse','friedman_mse',

'mse'}

决策树:

'gini'


回归树:

'mse'

特征选择标准 对决策树:gini:基尼系数,entropy:信息增益。
对回归树:可以使用"mse"或者"mae",前者是均方差,后者是和均值之差的绝对值之和。推荐使用默认的"mse"。一般来说"mse"比"mae"更加精确。
splitter {'best','random'} "best" 特征划分点选择标准 best:在所有划分中找出最优的划分点,适合数据量不大的时候;random:随机的在部分划分中找局部最有的划分点,适合数据量非常大的时候。
max_depth int None 树的最大深度 None:不限制子树的深度。样本多,特征多时,一般需要限制深度。
min_samples_split int/float 2 内部节点再划分所需最小样本数 限制子树继续划分的条件。如果节点的样本数少于min_samples_split,则不会继续在尝试选择最优特征来进行划分。若样本数量非常大(例如10w),则推荐增大这个值。
min_samples_leaf int/float 1 叶节点所需的最少样本数 若某叶子节点样本数小于min_samples_leaf,则会和兄弟节点一起被剪枝。若样本数量级非常大(例如10w),则推荐增大这个值。
min_weight_fraction_leaf float 0 叶子节点最小的样本权重和 限制叶子节点所有样本权重和的最小值,如果小于这个值则会和兄弟节点一起被剪枝。默认0表示不考虑权重问题。若样本缺失值较多或分布类别偏差很大,则可引入样本权重。
max_features int/float
/{'auto','sqrt','log2'}
None 划分时考虑的最大特征数 None:考虑所有特征;log2:最多考虑log2N个特征数;sqrt或auto:最多考虑平方根个特征;int:考虑绝对特征数;float:考虑特征百分比。如果特征数不多,使用None,如果特征数非常多,可灵活使用其他,以控制决策树的生成时间。
random_state int
/随机状态实例
None 控制分类器的随机性 当max_features小于特征数量时,在找到最优分割前,算法会在每次分割时随机选择特征,但即使max_feature等于特征数量,最优分割每次仍会不同。每次分割时需随机选择一个分割标准。
max_leaf_nodes int None 最大叶子节点数 防止过拟合。默认None即不限制最大叶子节点数。若加限制,则算法会建立在最大叶子节点数内最优的决策树。若特征数量大,则可限制,可通过交叉验证得到。
min_impurity_decrease float 0 节点划分最小不纯度 限制决策树的增长。若某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点不再生成子节点。
class_weight 字典/"balanced" None 类别权重 指定样本各类别的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别。Balanced:算法自己计算权重,样本量少的类别权重会高。
不适用于回归树。
ccp_alpha 非负的浮点型 0 复杂度参数

用于最小代价复杂度修剪的复杂度参数。

将会选择最大代价复杂度小于ccp_alpha的子树。默认不修剪。


 

参考:
[1]. 李航. 统计学习方法(第二版)

[2]. 决策树及其变种算法-知乎

[3]. CART算法-知乎

[4]. CART分类与回归树 学习笔记-博客园

[5]. scikit-learn决策树算法类库使用小结 - 博客园

[6]. 决策树算法原理(CART分类树)- 博客园

你可能感兴趣的:(机器学习)