前向分步算法 && AdaBoost算法 && 提高树(GBDT)算法 && XGBoost算法

1. 提高方法

提高(boosting)方法是一种经常使用的统计学方法,在分类问题中,它经过逐轮不断改变训练样本的权重,学习多个分类器,并将这些分类器进行线性组合,提升分类的性能html

0x1: 提高方法的基本思路

提高方法基于这样一种思想:对于一个复杂任务来讲,将多个专家的判断进行适当(按照必定权重)综合(例如线性组合加法模型)所得出的判断,要比其中任何一个专家单独的判断好git

历史上,Kearns和Valiant首先提出了“强可学习(strongly learnable)”和“弱可学习(weekly learnable)”的概念,指出在几率近似正确(probably approximately correct,PAC)学习的框架中github

1. 一个概念(几率规律)若是存在一个多项式的学习算法可以学习它(经过建模抽象拟合),而且正确率很高,那么就称这个概念是强可学习的;
2. 一个概念若是存在一个多项式的学习算法可以学习它,可是学习的正确率仅比随机猜想略好,那么就称这个概念是弱可学习的

同时,后来Schapire证实强在PAC学习的框架下,一个概念是强可学习的充分必要条件是这个概念是弱可学习的。这样一来,问题就转化为了,在算法训练建模中,若是已经发现了“弱可学习算法”(即当前分类效果并不优秀,甚至仅仅比随机预测效果要好),就有可能将其boosting(提高)为强可学习算法,这其中最具表明性的方法就是AdaBoosting(AdaBoosting algorithm)web

提高方法就是从弱学习算法出发,反复学习,获得一系列弱分类器(基本分类器),而后组合这些弱分类器,构成一个强分类器。大多数的提高方法都是改变训练数据的几率分布(训练数据的权重分布)算法

0x2:提高方法的两个关键要素

对于提高方法来讲,有两个很是重要的问题api

1. 在每一轮如何改变训练数据的权值或几率分布,修改的策略是什么?
2. 如何将弱分类器组合成一个强分类器?

这2个问题是全部Boosting方法都要考虑和解决的问题,这里以AdaBoost为例,讨论AdaBoost的策略数组

1. 提升那些被前一轮弱分类器错误分类的样本的权值,而下降那些被正确分类样本的权值。这样一来,那些被分错的数据,在下一轮就会获得更大的关注。因此,分类问题被一系列的弱分类器“分而治之”
2. 对弱分类器的组合,AdaBoost采起加权多数表决的方法。即加大分类偏差率小的弱分类器的权值,使其在表决中起较大做用,减少分类偏差率大的弱分类器的权值,使其在表决中起较小的做用

Relevant Link:网络

https://cseweb.ucsd.edu/~yfreund/papers/IntroToBoosting.pdf
http://blog.csdn.net/dark_scope/article/details/14103983

 

2. 前向分步算法

在开始学习AdaBoost算法以前,咱们须要先了解前向分步算法思想。实际上,AdaBoost算法是模型为加法模型、损失函数为指数函数、学习算法为前向分步算法时的二类分类学习算法并发

0x1:加法模型(aditive model)

加法模型是一种线性模型,,其中,为基函数,为基函数的参数,为基函数的系数(权重)app

在给定训练数据及损失函数的条件下,学习加法模型成为经验风险极小化(即损失函数极小化)问题:

即同时考虑N个样本在整个线性模型组中的损失函数的极小值,一般这是一个十分复杂的优化问题(求极值问题),想要一步到位求出最优解特别困难。前向分步算法(forward stagewise algorithm)求解这一优化问题的思想是:

由于学习的是加法模型(线性模型),若是可以从前向后,每一步只学习一个基函数及其系数,逐步逼近优化目标函数式,那么就能够极大简化优化的复杂度

具体地,每步只须要优化以下损失函数:,即一次只要考虑一个基函数及其系数便可

有一点要注意,前向分步的思想和贝叶斯估计有相似的地方:

它们都假设每一步之间的基函数和系数是独立不相关的(在贝叶斯估计中这叫独立同分布),也由于这一假设才能够把原始的全局最优解求解等价为分步的子项求解过程。
可是这种假设会丢失一部分精确度,即每一步之间的依赖关联会被丢弃

而前向分步算法的思想就是不求一步到位,而是逐步逼近最优解,经过分步求得每一步的最优解来逼近全局最优解。我我的以为这和SGD梯度降低的求最优思想是同样的

0x2:算法策略

和其余统计机器学习模型同样,前向分布算法的策略也一样是:经验风险最小化。若是在模型中加入了penalty惩罚项,则能够演进为结构风险最小化

0x3: 前向分步算法

给定训练数据集,损失函数和基函数的集合,学习加法模型的前向分步算法以下

(1)初始化

(2)对m = 1,2,3...,M(M表明基函数个数)

  (a)在上一步获得的最优基函数的基础上,极小化本次单个基函数的损失函数:,获得本轮最优基函数参数

  (b)更新(线性累加基函数)

(3)获得最终加法模型

这样,前向分步算法将同时求解从m=1到M全部参数的全局最优解问题简化为逐次求解各个的局部最优化问题

Relevant Link:

https://en.wikipedia.org/wiki/Additive_model
https://en.wikipedia.org/wiki/Generalized_additive_model
http://www.stat.cmu.edu/~ryantibs/advmethods/notes/addmodels.pdf

 

3. AdaBoost算法

0x1:算法过程

假设给定一个二类分类的训练数据集(adaboost不限于二类分类),其中,每一个样本点由实例与标记组成。实例是实例空间,是标记集合。AdaBoost利用如下算法,从训练数据集中学习一系列弱分类器或基本分类器,并将这些弱分类器线性组合成一个强分类器

  • (1)初始化训练数据的权值分布(N表明样本数量):(初始等几率分布体现了最大熵原理,在没有任何先验知识的前提下做等几率假设是最合理的)。这一步假设数据集具备均匀的权值分布,即每一个训练样本在基本分类器的学习中做用相同,这一假设保证第一步可以在原始数据上学习基本分类器
  • (2)假设训练轮次为M(直到达到某个预约的足够小的错误率或达到预先指定的最大迭代次数),则对m = 1,2,....,M

  (2.1)使用具备权值分布的训练数据集(对应本轮权值分布的数据集)学习,获得本轮次的基本分类器:

  (2.2)计算在本轮训练数据集上的分类偏差率(权重偏差函数):在加权的训练数据集上的分类偏差率是被误分类样本的权值之和,注意,权重偏差函数关注的是本轮数据集的权重(几率)分布,而不关注弱分类器内部的参数。即咱们对本轮高几率分布(重点关注的数据)的错误会给与更大的惩罚,这样就体现了模型Adding组合过程当中根据权重偏差进行模型组合选择的策略了

  (2.3)根据本轮的弱分类器对数据集的分类偏差计算的模型系数:,表明了本轮获得的弱分类器的重要程度。由左式可知,当时,,而且随着的减少而增大,因此在本轮分类偏差率越小的基本分类器在最终分类器中的做用越大

  (2.4)更新下一轮训练数据集的权值分布:是规范化因子:,它使得成为一个几率分布(每一轮的权值总和都为1,)。由此可知,被基本分类器误分类样本的权值得以扩大,而被正确分类样本的权值却在下一轮得以缩小。两相比较,误分类样本的权值被放大了倍,所以误分类样本在下一轮学习中起更大做用。不改变所给的训练数据自己,而不断改变训练数据权值的分布,使得训练数据在基本分类器的学习中起不一样的做用,一次优化一个弱分类模型,或者理解理解为一次优化全局复杂问题中的一次子问题(分而治之)

从数学的角度看,这也是一个平滑单调递增函数和 log 指数函数组合获得的动态增减平衡获得的神奇效果

  • (3)构建基本分类器的线性组合:,获得最终分类器:。线性组合实现M个基本分类器的加权表决。系数表示了基本分类器的重要性
能够看到,在每轮的训练中,训练样本的权值分布不断在变更,同时
1. 权值分布对本轮的弱分类器在最终线性分类器组合中重要程度起正比例做用;
2. 对下一轮的样本权值调整起反比例做用

0x2:算法策略

毫无疑问是经验风险最小化策略

0x3:AdaBoost的一个例子

分析一下书上给的例子的计算过程,体会adaboost的思想

初始化训练数据的权值分布:,在第一轮输入原始数据自己

1. 迭代过程 m = 1

要肯定本轮的权重偏差率,首先要"肯定"出本轮的模型内部参数(可是最终偏差损失的评估同时也受本轮数据集的权重分布影响,因此同一份数据每一轮的模型最优参数解都不同),题目所给的模型是一个离散而分类模型,离散表明着模型的最优解是有一个区间的,最优解并不惟一(例如v取1.5和v取1.2都是等价的)。咱们遍历【-0.5,0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5】比较模型偏差率最小的模型内部参数,通过计算可得,对于m=1,在权值分布为D1(10个数据,每一个数据的权值皆初始化为0.1)的训练数据上

  1. 阈值v取2.5时偏差率为0.3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,偏差率为0.3),
  2. 阈值v取5.5时偏差率最低为0.4(x < 5.5时取1,x > 5.5时取-1,则3 4 5 6 7 8皆分错,偏差率0.6大于0.5,不可取。故令x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,偏差率为0.4),
  3. 阈值v取8.5时偏差率为0.3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,偏差率为0.3)。
  4. ...其余类推可本身计算

能够看到,不管阈值v取2.5,仍是8.5,总得分错3个样本,故可任取其中任意一个如2.5,弄成第一个基本分类器为:

从而获得G1(x)在训练数据集上的偏差率(被G1(x)误分类样本“6 7 8”的权值之和)e1=P(G1(xi)≠yi) = 3*0.1 = 0.3

而后根据偏差率e1计算G1的系数:

接着更新训练数据的权值分布,用于下一轮迭代:

第一轮迭代后,最后获得各个数据的权值分布D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715,  0.0715, 0.1666, 0.1666, 0.1666, 0.0715)。由此能够看出

1. 由于样本中是数据“6 7 8”被G1(x)分错了,因此它们的权值由以前的0.1增大到0.1666
2. 反之,其它数据皆被分正确,因此它们的权值皆由以前的0.1减少到0.0715

分类函数f1(x)= a1*G1(x) = 0.4236G1(x)

从上述第一轮的整个迭代过程能够看出:被误分类样本的权值之和影响偏差率,偏差率影响基本分类器在最终分类器中所占的权重,每轮被误分类的样本的调整幅度是一致的。

2. 迭代过程 m = 2

对于m=2,在权值分布为D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715,  0.0715, 0.1666, 0.1666, 0.1666, 0.0715)的训练数据上,通过计算可得:

  1. 阈值v取2.5时偏差率为0.1666*3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,偏差率为0.1666*3),
  2. 阈值v取5.5时偏差率最低为0.0715*4(x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,偏差率为0.0715*3 + 0.0715),
  3. 阈值v取8.5时偏差率为0.0715*3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,偏差率为0.0715*3)

因此,阈值v取8.5时偏差率最低,故第二个基本分类器为:

G2(x)把样本“3 4 5”分错了,根据D2可知它们的权值为0.0715, 0.0715,  0.0715,因此G2(x)在训练数据集上的偏差率e2=P(G2(xi)≠yi) = 0.0715 * 3 = 0.2143。

计算G2的系数:

更新训练数据的权值分布:

D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667,  0.01667, 0.1060, 0.1060, 0.1060, 0.0455)。被分错的样本“3 4 5”的权值变大,其它被分对的样本的权值变小

f2(x)=0.4236G1(x) + 0.6496G2(x)

3. 迭代过程 m = 3

对于m=3,在权值分布为D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667,  0.01667, 0.1060, 0.1060, 0.1060, 0.0455)的训练数据上,通过计算可得:

  1. 阈值v取2.5时偏差率为0.1060*3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,偏差率为0.1060*3),
  2. 阈值v取5.5时偏差率最低为0.0455*4(x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,偏差率为0.0455*3 + 0.0715),
  3. 阈值v取8.5时偏差率为0.1667*3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,偏差率为0.1667*3)

因此阈值v取5.5时偏差率最低,故第三个基本分类器为:

此时,被误分类的样本是:0 1 2 9,这4个样本所对应的权值皆为0.0455,因此G3(x)在训练数据集上的权重偏差率e3 = P(G3(xi)≠yi) = 0.0455*4 = 0.1820

计算G3的系数:

更新训练数据的权值分布:D4 = (0.125, 0.125, 0.125, 0.102, 0.102,  0.102, 0.065, 0.065, 0.065, 0.125)。被分错的样本“0 1 2 9”的权值变大,其它被分对的样本的权值变小

f3(x)=0.4236G1(x) + 0.6496G2(x)+0.7514G3(x)

此时,获得的第三个基本分类器sign(f3(x))在训练数据集上有0个误分类点。至此,整个训练过程结束

从上述过程当中能够发现:若是某些个样本被分错,它们在下一轮迭代中的权值将被增大(让模型倾向于在下一轮把这些样本点分对),同时,其它被分对的样本在下一轮迭代中的权值将被减少。就这样,分错样本权值增大,分对样本权值变小,而在下一轮迭代中,老是选取让偏差率最低的阈值来设计基本分类器,因此每轮的偏差率e(全部被Gm(x)误分类样本的权值之和)不断下降。看起来就是最终线性模型组合的整体偏差率在每一轮的训练中不断下降

综上,将上面计算获得的a一、a二、a3各值代入G(x)中,G(x) = sign[f3(x)] = sign[ a1 * G1(x) + a2 * G2(x) + a3 * G3(x) ],获得最终的分类器为:

G(x) = sign[f3(x)] = sign[ 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x) ]

能够看到,每一轮迭代中阈值的选择是经过一个相似learning rate的学习率,能够理解为步长,去限制弱学习器的迭代次数

(scikitlearn的AdaBoostClassifier 中的learning_rate参数)

书中例子只有一个变量x,所以梯度为1能够忽略,可当作在原数据上学习率(步长)为0.5,去进行弱分类器的迭代,一次单变量的梯度下learning rate看起来和for循环遍历形式上是同样的

....
n_step = 0.5
features_min = min(features)
features_max = max(features)
# 步长
n_step = (features_max - features_min + self.learning_rate) // self.learning_rate

for i in range(1, int(n_step)):
        v = features_min + self.learning_rate * i
        # 加入条件:阈值与数据点不重合   
        if v not in features:
            # 误分类计算
            ....

0x4: 前向分布算法与AdaBoost的关系

在前面的章节中,咱们讨论了加法模型(aditive model)与它的一个最优解近似求解算法前向分步算法。其实本质上说,AdaBoost还有另一种解释,便可以认为:

AdaBoost是模型为加法模型、损失函数为指数函数、学习算法为前向分步算法的二类分类学习方法,AdaBoost算法就是前向分步算法的一个特例

AdaBoost中,各个基本分类器就至关于加法模型中的基函数,且其损失函数为指数函数

换句话说,当前向分步算法中的基函数为Adaboost中的基本分类器时,加法模型等价于Adaboost的最终分类器

Relevant Link:

http://blog.csdn.net/v_july_v/article/details/40718799
http://blog.csdn.net/dark_scope/article/details/14103983 
https://www.zhihu.com/question/65357931
http://blog.csdn.net/v_july_v/article/details/40718799 

 

4. 提高树(GBDT Gradient Boostring Decision Tree)

提高树是一种以分类树或回归树为基本分类器的提高方法

0x1: 提高树模型

提高树实际采用加法模型(基函数的线性组合)与前向分步算法。以决策树为基函数的提高方法称为提高树(boosting tree),对二分类问题决策树是二叉树,对回归问题决策树是二叉回归树。提高树模型能够表示为决策树的加法模型,其中表示决策树;表示决策树内部参数(选哪一个特征做为切分点;阈值多少);M 为整个模型的个数

0x2: 提高树算法

提高树算法采用前向分步算法,首先肯定初始提高树,第m步的模型是:,其中为上一轮训练获得的单个基本分类器,经过经验风险极小化肯定下一棵决策树的参数

若是抽象来看,把每一个基分类器的权重几率看做模型的参数,即每一轮的模型都接收上一步模型的参数做为输入,这一点很像深度神经网络的层一层之间的关系。
区别在于Boosting方法每轮获得的模型参数在输入下一轮迭代时是固定不变的,在每轮跌倒之间变更的只有:1)数据的几率权重;及2)模型的决策权重,而DNN会在每轮迭代中不断调整模型自身内部的全部神经元(对应基分类器)的内部参数。
打个不巧当的比喻:DNN坚信本身就是最棒的,不断提高本身。而Boostring认为众人拾柴火焰高,一我的不行咱们就用祖父子->祖父子代代之间不断去优化,而后你们一块儿来参与决策

因为树的线性组合能够很好地拟合训练数据中存在的几率规则分布(多是多峰的),即便数据中的输入与输出之间的关系很复杂也是如此,因此提高树是一个高效地学习算法。

下面讨论针对不一样问题的提高树学习算法,其主要区别在于使用的损失函数不一样:

1)用平方偏差损失函数的回归问题:用平方偏差求导更平滑可微;

2)用指数损失函数的分类问题;

3)用通常损失函数的通常决策问题;

1. 二分类问题提高树

对于二分类问题,提高树算法只须要将AdaBoost算法中的基本分类器(阶跃分类器)限制为二类分类树便可,能够说这时的提高树算法是AdaBoost算法的特殊状况

这里插一句:前面例子中看到的基本分类器 x < v 或 x > v,能够看做是由一个根节点直接链接的两个叶节点的简单决策树,即所谓的决策树桩(decision stump)

2. 回归问题的提高树

已知一个训练数据集为输入空间,为输出空间。若是将输入空间划分为 J 个互不相交的区域 R1,R2,...,Rj,而且在每一个区域上肯定输出的常量Cj(连续区间的离散采样值),那么树能够表示为:,其中,参数 表示树的区域划分和各区域上的常数。J 是回归树的复杂度即叶节点个数(采样粒度)

回归问题提高树使用如下前向分步算法:

在前向分步算法的第 m 步,给定当前模型 (上一轮训练获得的模型),需求解,获得,即第 m 棵树的参数

当采用平方偏差损失函数时,,其损失变为:

这里,是当前模型拟合训练数据的残差(residual),因此,对回归问题的提高树算法来讲,只需简单地拟合当前模型的残差便可。算法流程以下

(1) 初始化

(2)对 m = 1,2,...,M,M表明该加法模型总共有M个基本模型进行线性组合,在每一轮的训练中都进行以下步骤

  (a)计算残差

  (b)拟合残差(残差最小化)学习一个回归树,获得

  (c)更新

(3)获得回归问题提高树:

0x3: 提高树算法的一个例子

来一步步推导下书上的例子加深理解和印象

1. 第一次迭代 m = 1

对第一次迭代来讲,提高树输入的是原始数据,残差等于原始样本输入

即回归树。首先经过如下优化问题:求解训练数据的切分点s:

容易求得在R1,R2内部使平方偏差达到最小的C1,C2为:(离散采样点取子集的均值可使得平方偏差最小),这里N1,N2是R1,R2的样本个数

每一轮迭代训练中要计算的就是训练数据的切分点,这里能够采起遍历全部可能值的策略求得最优切分点s,s及m(s)的计算结果以下

可知当s = 6.5时m(s)达到最小值,此时,全部回归树为:

拟合训练数据的残差用于输入下一轮迭代训练(从第二轮开始模型的输入就是残差了,这是GBDT区别于普通回归决策树的一个区别)以下表所示

拟合训练数据的平方损失偏差:

仔细看这个结果,咱们会发现:从第二轮开始,输入下一轮的就再也不是原始数据,而是数据的“离心距离”,即距离最佳分类面的距离。

2. 第二次迭代 m = 2

提高树和AdaBoost的核心思想是同样的,即:分而治之,每一轮迭代的“误报量”会被传递到下一轮,在下一轮的迭代中经过调整基本函数内部参数对那部分“误报量“进行重点解决

在AdaBoost中,上一轮误报的样本点会在下一轮按照必定的比例被提升权重,而在提高树中。这种思想经过残差得以体现,上一轮分类错误的残差被做为样本点传入进行模型训练,这一轮的目的就是尽力消弭这部分残差

这一轮的训练样本是上一轮的残差

经过遍历全部可能分界点s,能够获得:,-0.5二、0.22分别是左右分类子集的均值(知足平方偏差最小)

至此,两个不等式线性相加的结果

注意到这里和普通回归决策树的不一样:GBDT每一轮获得的基分类器线性组合都同时包括此前的基分类器结果以及本轮的训练拟合结果,而普通回归决策树每轮迭代获得的区间基分类器都仅仅取决于原是样本

拟合原始训练数据的平方损失偏差是:(比第一轮的损失函数在降低)

# -*- coding:utf-8 -*-

import math

def f2_fuc(x):
    if x < 3.5:
        return 5.72
    elif x < 6.5:
        return 6.46
    else:
        return 9.13

if __name__ == "__main__":
    loss = 0
    train_data = {
        1: 5.56,
        2: 5.7,
        3: 5.91,
        4: 6.4,
        5: 6.8,
        6: 7.05,
        7: 8.9,
        8: 8.7,
        9: 9.0,
        10: 9.05
    }
    for i in train_data:
        loss += (train_data[i] - f2_fuc(i)) ** 2

    print loss

3. 继续往下迭代

拟合原始训练数据的平方损失偏差是:

假设此时已经知足中止条件,则即为所求提高树(它的区间离散采样值是由多课决策树线性组合而成决定的)

0x4: 更加general泛化的残差求解方式 - 梯度提高

提高树利用加法模型与前向分步算法实现学习的优化过程。当损失函数是平方损失和指数损失函数时,每一步优化是相对简单的(咱们均可以经过求导获得最佳离散化采样值c1/c2),但对通常泛化的损失函数而言,每每每一步的优化并不容易(针对连续回归函数的复杂函数的拟合场景)。针对这一问题,Freidman提出了梯度提高(gradient boosting)算法,梯度提高的关键是利用损失函数的负梯度(负导数) 做为回归问题提高树算法中的残差的近似值(负梯度一样体现了该区间内样本数据和最佳分界面的“离心程度”),拟合一个回归树

(1)初始化:

(2)对 m = 1,2,...,M,M表明该加法模型总共有M个基本模型进行线性组合,在每一轮的训练中都进行以下步骤

  (a)对 i = 1,2,...,N(N个样本),计算:(计算损失函数的负梯度在当前模型的值,将它做为残差的估计,对于平方损失函数它就是残差;对于通常的损失函数,它就是残差的近似值)

  (b)对拟合一个回归树,获得第 m 棵树的叶节点区域,j = 1,2,...,J(叶节点不必定等于2)

  (c)对 j = 1,2,...,J,计算(利用线性搜索估计叶节点区域的值,寻找使得偏差梯度最小的离散采样值c)

  (d)更新 (每一个基本函数由该棵树的全部叶节点的离散采样值组成)

(3)获得回归树:

Relevant Link:

https://www.zhihu.com/question/60625492/answer/200165954
http://www.jianshu.com/p/005a4e6ac775

 

5. xgboost(Scalable and Flexible Gradient Boosting)

0x1:用一个图例说明XGboost模型

咱们用一个简单的例子来引入对Xgboost的讨论,咱们的目标是根据一些属性特性,判断一个家庭里的成员是否喜欢玩电脑游戏

1. 单个CART树的预测

能够看到,CART树和decision tree有一些不一样,CART树的叶节点对应的是一个分值,而不像分类决策树是一个肯定的类别,CART树的这个分值咱们能够理解为权重

2. 两个CART树的线性加和组合

简单来讲,xgboost对应的模型就是一堆CART树的线性组合,和GBDT同样,XGBoost将每棵树的预测值加到一块儿做为最终的预测值

第二图的底部说明了如何用一堆CART树作预测,就是基于“addive model加法线性模型”的思想,将各个树的预测分数相加 。经过这种多基分类器加和(相似DNND中的多神经元)综合判断的方式,各个基模型互相补充,实现对多峰几率分布的拟合。这也体现了ensemble learning集成学习的思想

0x2:XGBoost数学模型

咱们用数学来准确地表示这个模型:

这里的K就是树的棵数,F表示全部可能的CART树,f表示一棵具体的CART树。这个模型由K棵CART树组成。

模型的目标函数以下:

这个目标函数一样包含两部分

1. 第一部分就是损失函数:MSE或指数损失(例如交叉熵损失)
2. 第二部分就是正则项,这里的正则化项由K棵树的正则化项相加而来,体现了总体模型的复杂度

咱们但愿XGBoost获得的是一个: simple and predictive model

0x3:XGBoost模型训练策略 - 前向分步策略(逐轮加法训练)

几乎对于全部的有监督机器学习模型来讲,训练过程就是找到一个目标函数,而后优化求导求极值。

可是XGBoost的模型:是由K棵树以及每棵树中的全部叶节点值组成的加法模型,要对其进行全局求导;或者是进行梯度降低都是很困难的,或者说在计算上很是复杂。

解决这个问题,咱们可使用“加法训练”,即咱们一次只训练一棵树,同时把上一轮获得的全部ensemble tree结果做为本轮的输入:

在第t步时,咱们添加了一棵最优的CART树ft,这棵最优的CART树ft是怎么得来的呢?就是在现有的t-1棵树的基础上,使得目标函数最小的那棵CART树,以下图所示:

假如咱们使用的损失函数时MSE,那么上述表达式会变成这个样子:

这个式子很是漂亮,由于它含有ft(xi)的一次式和二次式,并且一次式项的系数是残差。注意:这里模型的参数 ft(xi) 就是CART树叶子结点的值

可是对于其余的损失函数(指数损失和通常损失),咱们未必能得出如此漂亮的式子,因此,对于通常的损失函数,咱们须要将其做泰勒二阶展开,以下所示: 

其中:

在这个公式中,constant表明的 t -1 棵树的正则化项;l(yi, yi^t-1)也是常数项;剩下的三个变量项分别是第t棵CART树的一次式,二次式;和整棵树的正则化项。

咱们的目标在在这轮迭代中,让目标函数最小化,因此能够把常数项去掉,公式整理后以下:

obj*表明了什么呢?它表示了这棵树的结构有多好,值越小,表明这样结构越好!也就是说,它是衡量第t棵CART树的结构好坏的标准。这个值仅仅是用来衡量结构的好坏的,与叶子节点的值但是无关的。以下图所示:

有了评判树的结构好坏的标准,咱们就能够先求最佳的树结构,这个定出来后,最佳的叶子结点的值实际上在上面已经求出来了(模型的参数也就获得了)。

问题是:树的结构近乎无限多,一个一个去测算它们的好坏程度,而后再取最好的显然是不现实的。因此,咱们仍然须要采起 “逐轮迭代渐进逼近全局最优策略”,咱们 每次只优化一层的树结点,获得在这层里最优的树结构,即找到一个最优的切分点,使得切分后的Gain最大(和决策树的基尼指数求解最优分界面的思想是一致的)。
扫描结束后,咱们就能够肯定是否切分,若是切分,对切分出来的两个节点,递归地调用这个切分过程,咱们就能得到一个相对较好的树结构。

咱们以上文提到过的判断一我的是否喜欢计算机游戏为例子。最简单的树结构就是一个节点的树。咱们能够算出这棵单节点的树的好坏程度obj*。假设咱们如今想按照年龄将这棵单节点树进行分叉,咱们须要知道:

1、按照年龄分是否有效,也就是是否减小了obj的值
2、若是可分,那么以哪一个年龄值来分。

为了回答上面两个问题,咱们能够将这一家五口人按照年龄作个排序。以下图所示:

这个Gain实际上就是单节点的obj*减去切分后的两个节点的树obj*,Gain若是是正的,而且值越大,表示切分后obj*越小于单节点的obj*,就越值得切分。

同时,咱们还能够观察到,Gain的左半部分若是小于右侧的,则Gain就是负的,代表切分后obj反而变大了。

在这里其实是一个临界值,它的值越大,表示咱们对切分后obj降低幅度要求越严。这个值也是能够在xgboost中设定的。这个实际在本质上就起到了剪枝限制的做用,这也是XGboost和决策树的一个不一样点:普通的决策树在切分的时候并不考虑树的复杂度,而依赖后续的剪枝操做来控制。xgboost在切分的时候就已经考虑了树的复杂度,就是那个参数。因此,它不须要进行单独的剪枝操做

0x4:XGboost的优势

从这个目标函数能够看出XGBoost的优势之处:

1. 目标函数中的一次式,二次式的系数是 gi 和 hi,而 gi 和 hi 是彼此独立的,能够并行的计算,这带来了计算速度上的并发优点
2. 并且,gi 和 hi是不依赖于损失函数的形式,只要这个损失函数是二次可微便可,因此 XGBoost能够自定义损失函数
Relevant Link:

https://www.jianshu.com/p/7467e616f227 
https://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf
https://xgboost.readthedocs.io/en/latest/model.html
https://www.cnblogs.com/csyuan/p/6537255.html 
http://blog.csdn.net/a819825294/article/details/51206410
http://blog.csdn.net/sb19931201/article/details/52557382
http://blog.csdn.net/github_38414650/article/details/76061893

Copyright (c) 2018 LittleHann All rights reserved

相关文章
相关标签/搜索