决策树、CART与GBDT
GBDT是一种boosting方法,基本理念是组合多个弱模型形成强模型,而每个弱模型的目标都是拟合历史弱模型的残差。GBDT同时也是一种树方法,可以理解为回归树的一种改进,而提到树回归,就不可避免先谈谈决策树与CART。
基本概念
几乎所有的树方法,计算过程都是在当前的数据集上寻找一个最优的划分,每次以一个特征的值作为划分依据。
从划分原则的角度看,最原始的决策树,通过计算划分带来的信息增益去判断当前选择哪个特征,对于离散特征,直接按具体的值计算信息增益,所以可能会形成多叉树;对于连续特征,则需要对特征值进行排序,然后把每个值当作划分的条件进行计算,得到最优的划分值,因此只会形成二叉树。
而从划分评估的角度看,假设是分类问题,则按信息增益或基尼系数进行评估;假设是回归问题,则按最小二乘偏差或最小绝对偏差进行评估。
下面针对具体模型来说明整个过程。
决策树
决策树的核心其实只有两个重点概念。
熵与条件熵
这个话题其实已经讨论过无数次了:熵是评估一个变量的不确定性,或者说混乱程度;而条件熵表示在某个变量确定后,另一个变量的不确定性,直观来看条件熵就是评估某个变量对另一个变量的不确定性贡献有多大。决策树的划分计算是不是呼之欲出?
假设某个变量 Y Y Y(可以理解为类别变量)有 C C C个取值,每个取值的概率为 p c p_c pc,则这个变量熵的计算:
H ( Y ) = − ∑ c = 1 C p c log ( p c ) H(Y) = -\sum_{c = 1}^C{p_c \text{log}(p_c)} H(Y)=−c=1∑Cpclog(pc)
假设现在有另一个变量 X X X(可以理解为特征变量),我们想知道如果变量 X X X变化了,是否会充分地引起变量 Y Y Y的变化,则可以通过条件熵去描述:
H ( Y ∣ X ) = ∑ m = 1 M p m H ( Y ∣ X = x m ) H(Y| X) = \sum_{m = 1}^M{p_m H(Y| X = x_m)} H(Y∣X)=m=1∑MpmH(Y∣X=xm)
信息增益
在知道变量 X X X后,如果数据集整体不确定性变小了,显然就应该按 X X X进行划分,这其实是信息增益的概念(G for Gain):
G ( Y , X ) = H ( Y ) − H ( Y ∣ X ) G(Y, X) = H(Y) - H(Y| X) G(Y,X)=H(Y)−H(Y∣X)
这里其实有个容易忽略的细节,既然有了条件熵,为什么还要信息增益呢?不妨思考一下。
ID3与C4.5
整个决策树的计算过程就是一个递归过程:遍历每个属性,假如是离散的,直接根据变量各个值计算信息增益;假如是连续的,则对变量值排序后计算每种分裂方式的信息增益,然后选择信息增益最大的属性执行分裂,对每个数据子集进行同样的分裂操作,直到树的深度达到某个阈值、或叶子节点包含的数据量达到某个阈值。
而ID3与C4.5的区别是,C4.5没有使用信息增益,因为信息增益的计算方法会偏向于取值较多的特征,因此使用了信息增益比。
CART
CART在决策树的基础上进行了改进,可以分别处理分类和回归问题。
CART分类
对于分类问题,使用了基尼指数(G for Gini)描述一个数据集的不确定程度:
G ( D ) = ∑ c = 1 C p c ( 1 − p c ) = 1 − ∑ c = 1 C p c 2 G(D) = \sum_{c = 1}^C{p_c(1 - p_c)} = 1 - \sum_{c = 1}^C{p_c^2} G(D)=c=1∑Cpc(1−pc)=1−c=1∑Cpc2
其中 p c p_c pc可以简单地理解为类别 c c c的样本频率(即概率)。假设现在对数据集按特征 X X X进行划分(划分为 D 1 D_1 D1和 D 2 D_2 D2),那么基尼指数的计算为:
G ( D , X ) = ∣ D 1 ∣ ∣ D ∣ G ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G ( D 2 ) G(D, X) = \frac{|D_1|}{|D|} G(D_1) + \frac{|D_2|}{|D|} G(D_2) G(D,X)=∣D∣∣D1∣G(D1)+∣D∣∣D2∣G(D2)
过程基本与决策树一致。
CART回归
而对于回归问题,如果数据被划分成 K K K个单元 R 1 , R 2 , … , R K R_1, R_2, \dotsc, R_K R1,R2,…,RK,每个单元有一个固定的输出值 v k v_k vk,模型的输出为:
f ( x ) = ∑ k = 1 K v k I ( x ∈ R k ) f(x) = \sum_{k = 1}^K{v_k I(x \in R_k)} f(x)=k=1∑KvkI(x∈Rk)
则模型输出值与实际值之间的误差为:
∑ x i ∈ R k ( y i − f ( x i ) ) 2 \sum_{x_i \in R_k}{(y_i - f(x_i))^2} xi∈Rk∑(yi−f(xi))2
当 v k v_k vk为相应单元上的所有真实值的均值时,误差可以最小化。
现在假设我们选择了第 d d d个特征 x ( d ) x^{(d)} x(d)作为划分依据, s s s为划分的取值,可以得到两个单元:
R 1 ( d , s ) = { x ∣ x ( d ) ≤ s } R 2 ( d , s ) = { x ∣ x ( d ) > s } R_1(d, s) = \{x| x^{(d)} \le s\} \\ R_2(d, s) = \{x| x^{(d)} \gt s\} R1(d,s)={x∣x(d)≤s}R2(d,s)={x∣x(d)>s}
当选定 d d d、 s s s后,我们需要优化 v 1 v_1 v1、 v 2 v_2 v2两个值使各自单元上的平方误差最小:
min d , s [ min v 1 [ ∑ x i ∈ R 1 ( d , s ) ( y i − v 1 ) 2 ] + min v 2 [ ∑ x i ∈ R 2 ( d , s ) ( y i − v 2 ) 2 ] ] \underset{d, s}{\text{min}} \bigg[ \underset{v_1}{\text{min}} [\sum_{x_i \in R_1(d, s)}{(y_i - v_1)^2}] + \underset{v_2}{\text{min}} [\sum_{x_i \in R_2(d, s)}{(y_i - v_2)^2}] \bigg] d,smin[v1min[xi∈R1(d,s)∑(yi−v1)2]+v2min[xi∈R2(d,s)∑(yi−v2)2]]
根据前面的分析, v 1 v_1 v1、 v 2 v_2 v2的取值实际上是单元内真实值的平均,则只需要对每个变量的每个划分进行遍历,即可找到最优的 d d d、 s s s。
剩余的步骤基本跟决策树一致。
GBDT
提到GBDT(Gradient Boosting Decision Tree),可能觉得奇怪,决策树怎么求梯度?实际上这里还涉及一些比较大的概念,即是Ensemble Learning,类似Few-shot Learning、Meta Learning、Contrastive Learning这些概念,这些都是不同的机器学习框架,里面有很多不同的模型实现。Ensemble Learning又分为三类策略:Bagging、Stacking、Boosting,GBDT就是Boosting策略的代表(随机森林是Bagging的代表)。
回到GBDT本身,GBDT通过构造一系列CART、并把所有CART的输出值累加作为最终的预测值,整体过程如下(Boosting的过程):
- 训练一个初始学习器;
- 根据学习器的表现,对训练样本的分布进行调整,使先前学习器做错的训练样本在后续受到更多关注;
- 基于调整后的样本分布训练下一个学习器;
- 重复执行这个过程,直至学习器数目达到事先指定的 T T T;
- 将 T T T个学习器加权结合。
我们把整个模型记为 F ( x ) F(x) F(x),形式化描述如下:
F k ( x ) = ∑ i = 1 k f i ( x ) F_k(x) = \sum_{i = 1}^k{f_i(x)} Fk(x)=i=1∑kfi(x)
其中 f i ( x ) f_i(x) fi(x)即是第 i i i个CART,也可以写成:
F k ( x ) = F k − 1 ( x ) + f k ( x ) F_k(x) = F_{k - 1}(x) + f_k(x) Fk(x)=Fk−1(x)+fk(x)
我们最终的目标是得到强学习器 F k ( x ) F_k(x) Fk(x),每一个 f k ( x ) f_k(x) fk(x)的学习可以看作是对 F k − 1 ( x ) F_{k - 1}(x) Fk−1(x)的修正。具体的修正方法是在 F k − 1 ( x ) F_{k - 1}(x) Fk−1(x)上叠加 f k ( x ) f_k(x) fk(x),有点像傅里叶变换的感觉,初始的时候用低频去拟合,然后逐渐用更高频的函数叠加,当然GBDT并没有使用基函数,是通过求损失函数对 F k − 1 ( x ) F_{k - 1}(x) Fk−1(x)的梯度,求得 f k ( x ) f_k(x) fk(x)的拟合目标。当前强学习器 F k − 1 ( x ) F_{k - 1}(x) Fk−1(x)的误差记为:
L ( y , F k − 1 ( x ) ) = ( y − F k − 1 ( x ) ) 2 L(y, F_{k - 1}(x)) = (y - F_{k - 1}(x))^2 L(y,Fk−1(x))=(y−Fk−1(x))2
我们的目标是优化强学习器,Gradient Boosting在这里体现为对 F k − 1 ( x ) F_{k - 1}(x) Fk−1(x)求梯度:
∂ L ( y , F k − 1 ( x ) ) ∂ F k − 1 ( x ) = − 2 ( y − F k − 1 ( x ) ) \frac{\partial{L(y, F_{k - 1}(x))}}{\partial{F_{k - 1}(x)}} = -2(y - F_{k - 1}(x)) ∂Fk−1(x)∂L(y,Fk−1(x))=−2(y−Fk−1(x))
可以得到 F k ( x ) F_k(x) Fk(x)的更新公式:
F k ( x ) = F k − 1 ( x ) − r ∗ ∂ L ( y , F k − 1 ( x ) ) ∂ F k − 1 ( x ) F_k(x) = F_{k - 1}(x) - r * \frac{\partial{L(y, F_{k - 1}(x))}}{\partial{F_{k - 1}(x)}} Fk(x)=Fk−1(x)−r∗∂Fk−1(x)∂L(y,Fk−1(x))
因此,构造 f k ( x ) f_k(x) fk(x)的目标就是使 f k ( x ) f_k(x) fk(x)的输出尽可能接近 y − F k − 1 ( x ) y - F_{k - 1}(x) y−Fk−1(x),即是这个CART拟合的是上一个输出和标签值的残差。
扩展阅读
以上是决策树、CART与GBDT的原理简介,在GBDT的实际应用中,还有一些技巧需要掌握: