引言
\quad \quad 在决策树、ID3、C4.5算法一文中,简单地介绍了决策树模型,以及决策树生成算法ID3算法和ID3算法的改进版C4.5算法;在决策时剪枝算法一文中,简单地介绍了剪枝的算法。我们也提到了它的不足,比如模型是用较为复杂的熵来度量,使用了相对较为复杂的多叉树,只能处理分类不能处理回归等。对于这些问题, CART算法大部分做了改进。CART算法也就是我们下面的重点了。由于CART算法可以做回归,也可以做分类,我们分别加以介绍,先从CART分类树算法开始,重点比较和C4.5算法的不同点。接着介绍CART回归树算法,重点介绍和CART分类树的不同点。然后我们讨论CART树的建树算法和剪枝算法,最后总结决策树算法的优缺点。
1、概述
\quad \quad 所谓CART算法,全名叫Classification and Regression Tree,即分类与回归树。顾名思义,相较于此前的ID3算法和C4.5算法,CART除了可以用于分类任务外,还可以完成回归分析。完整的CART算法包括特征选择、决策树生成和决策树剪枝三个部分。
\quad \quad 有以下特点:
(1)CART是一棵二叉树;
(2)CART算法主要包括回归树和分类树两种。回归树用于目标变量为连续型的建模任务,其特征选择准则用的是平方误差最小准则。分类树用于目标变量为离散型的的建模任务,其特征选择准则用的是基尼指数(Gini Index),这也有别于此前ID3的信息增益准则和C4.5的信息增益比准则。无论是回归树还是分类树,其算法核心都在于递归地选择最优特征构建决策树。
(3)CART作为一种单模型,也是GBDT的基模型。当很多棵CART分类树或者回归树集成起来的时候,就形成了GBDT模型。关于GBDT,笔者将在后续中进行详细讲述,这里不再展开。
2、CART算法
\quad \quad CART算法由以下两步生成:
(1)决策树生成:递归地构建二叉决策树的过程,基于训练数据集生成决策树,生成的决策树要尽量大;自上而下从根开始建立节点,在每个节点处要选择一个最好的属性来分裂,使得子节点中的训练集尽量的纯。不同的算法使用不同的指标来定义"最好"。
(2)决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时用损失函数最小作为剪枝的标准。【剪枝可以视为决策树算法的一种正则化手段,作为一种基于规则的非参数监督学习方法,决策树在训练很容易过拟合,导致最后生成的决策树泛化性能不高。】
2.1 CART生成
\quad \quad CART算法的决策树生成实现过程如下:
-
使用CART算法选择特征
- 对回归树用平方误差最小化准测,进行特征选择;
- 对分类树用基尼指数(GINI)最小化准则,进行特征选择,
-
根据特征切分数据集合
-
构建树
【代码实现】简单例子:根据特征切分数据集合
import numpy as np
# 函数说明:根据给定特征和特征值,将数据集分为两个区域
"""
Parameters:
dataSet - 数据集合
feature - 待切分的特征
value - 特征的某个值
Returns:
mat0-切分的数据集合0
mat1-切分的数据集1
"""
def binSplitDataSet(dataSet,feature,value):
mat0=dataSet[np.nonzero(dataSet[:,feature]>value)[0],:]
mat1=dataSet[np.nonzero(dataSet[:,feature]<=value)[0],:]
return mat0,mat1
if __name__=='__main__':
testMat=np.mat(np.eye(4))
mat0,mat1=binSplitDataSet(testMat,1,0.5)
mat0, mat1 = binSplitDataSet(testMat, 1, 0.5)
print("原始集合:\n", testMat)
print("mat0:\n", mat0)
print("mat1:\n", mat1)
原始集合:
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
mat0:
[[0. 1. 0. 0.]]
mat1:
[[1. 0. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
2.1.1 回归树的生成
划分的准则是平方误差最小化
\quad \quad 假设X与Y分别为输入和输出变量,并且Y是连续变量,给定训练数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y n ) } D=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_n)\} D={
(x1,y1),(x2,y2),...,(xN,yn)}
假定已将输入空间划分为M个单元 R 1 , R 2 , . . . , R M R_1,R_2,...,R_M R1,R2,...,RM,并且在每个单元 R M R_M RM上有一个固定的输出值 c m c_m cm,则
回归模型:
f ( x ) = ∑ m = 1 M c m I ( x ∈ R m ) f(x)=\sum_{m=1}^Mc_mI(x\in R_m) f(x)=m=1∑McmI(x∈Rm)
预测误差:平方误差
∑ x i ∈ R m ( y i − f ( x i ) ) 2 \sum_{x_i\in R_m}(y_i-f(x_i))^2 xi∈Rm∑(yi−f(xi))2
如何选择每一个单元上的最优输出值 c m c_m cm?
\quad \quad 用平方误差最小的准则求解每个单元上的最优输出值得单元 R M R_M RM上的 c m c_m cm的最优值 c m ^ \hat{c_m} cm^是 R M R_M RM上的所有输入实例 x i x_i xi对应的输出 y i y_i yi的均值,即
c m ^ = a v e ( y i ∣ x i ∈ R m ) \hat{c_m}=ave(y_i|x_i\in R_m) cm^=ave(yi∣xi∈Rm)
如何对输入空间进行划分?
\quad \quad 采用启发式即二元切分的方法,假设选择第j个变量 x ( j ) x^{(j)} x(j)和它的取值s,作为切分变量和切分点,那么就会得到两个区域:
R 1 ( j , s ) = { x ∣ x ( j ) ≤ s } 和 R 2 ( j , s ) = { x ∣ x ( j ) > s } R_1(j,s)=\{x|x^{(j)}\leq s\} \ 和\ R_2(j,s)=\{x|x^{(j)}> s\} R1(j,s)={
x∣x(j)≤s} 和 R2(j,s)={
x∣x(j)>s}
当j和s固定时,我们要找到两个区域的代表值c1,c2使各自区间上的平方差最小:
m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] \mathop{min}\limits_{j,s}[\mathop{min}\limits_{c_1}\sum_{x_i\in R_1(j,s)}(y_i-c_1)^2+\mathop{min}\limits_{c_2}\sum_{x_i\in R_2(j,s)}(y_i-c_2)^2] j,smin[c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2]
前面已经知道c1,c2为区间上的平均:
c 1 ^ = a v e ( y i ∣ x i ∈ R 1 ( j , s ) ) 和 c 2 ^ = a v e ( y i ∣ x i ∈ R 2 ( j , s ) ) \hat{c_1}=ave(y_i|x_i\in R_1(j,s)) \ 和 \ \hat{c_2}=ave(y_i|x_i\in R_2(j,s)) c1^=ave(yi∣xi∈R1(j,s)) 和 c2^=ave(yi∣xi∈R2(j,s))
那么对固定的 j 只需要找到最优的s,然后通过遍历所有的变量,我们可以找到最优的j,这样我们就可以得到最优对(j,s),并得到两个区间。
\quad \quad 这样的回归树通常称为最小二乘回归树。算法具体流程如下:
算法5.5 (最小二乘回归树生成算法)
输入:训练数据集D
输出:回归树 f ( x ) f(x) f(x)
\quad \quad 在训练数据集所在的输入空间中,递归地将每一个区域划分为两个子区域并决定每个子区域上的输出值,构建二叉决策树:
(1)选择最优切分变量 j 和切分点 s,求解
m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1