AdaBoost, GBDT和XGBoost的区别和联系

原文请参考: https://hackernoon.com/gradient-boosting-and-xgboost-90862daa6c77

什么是Boosting

Boosting 是将一组弱学习器(weak learner)组合起来成为一个强学习器(strong learner) 的方法。假设我们有一个二分类任务。一个较弱的学习器分类时的错误率略小于0.5,即它的学习能力比抛硬币略强一点点,而强学习器的错误率接近于0。为了把一个学习能力差的学习器转变成一个学习能力强的学习器,我们找一组学习能力差的学习器,把它们结合起来使用,这就把这群弱学习器变成了强学习器。

Boosting 的策略用一句形象的话说就是:三个臭皮匠,顶上一个诸葛亮

Boosting 算法的类型主要有:

  • AdaBoost
  • Gradient Boosting
  • XGBoost

AdaBoost (Adaptive Boosting)

Adaptive Boosting 技术由 Yoav Freund 和 Robert Schapire 于1995年提出。AdaBoost致力于改进base learner 失败之处。base learner 可以认为是一个机器学习算法,它是一种弱学习器,应用 boosting 方法可以使之成为强学习器。任何接受训练数据权重的机器学习算法都可以作为 base learner。在下面的例子中,决策桩(decision stump)被用作 base learner。

我们从训练数据中随机抽取样本点,应用决策桩算法(decision stump)对这些点进行分类。对采样点进行分类后,将决策桩与完整的训练数据进行拟合。这个过程迭代地进行,直到完整的训练数据没有任何错误地匹配,或者直到指定的最大估计值。

在从训练数据中取样并应用决策桩算法后,该模型如下所示:

AdaBoost, GBDT和XGBoost的区别和联系

我们可以看到有三个正样本被错误地分类为负类。因此,我们需要增大这些被错误分类的样本的权重,以便在再次采样时有更好的机会被选中。

AdaBoost, GBDT和XGBoost的区别和联系

当下次采样数据时,将决策桩2与决策桩1 结合起来拟合训练数据。因此,我们这里有一个小型的集成,试图完美地拟合数据。这个由两个决策树桩组成的微型集合将三个负样本错误地分类为正类。因此,我们增大这些被错误分类的样本的权重,以便在再次采样时有更好的机会被选中。

AdaBoost, GBDT和XGBoost的区别和联系

选取之前错误分类的样本,利用决策桩3对训练数据进行拟合。我们可以发现两个阳性样本被归为阴性,一个阴性样本被归为阳性。然后利用三个决策桩(1,2,3)的组合来拟合完整的训练数据。当使用这三个决策桩组合时,模型与训练数据非常吻合。

AdaBoost, GBDT和XGBoost的区别和联系

AdaBoost算法的缺点是容易被噪声数据打败,当算法试图完美地拟合每个点时,异常值对算法的效率影响很大。你可能会想,既然算法试着去适应每一个点,它不会过拟合吗?答案是,它不会。实验结果已经证实了这一点,但没有具体的理论支撑。

# AdaBoost Algorithm
from sklearn.ensemble import AdaBoostClassifier
clf = AdaBoostClassifier()
...
clf.fit(x_train,y_train)
clf.predict(x_test)

Gradient Boosting

Gradient Boosting 也是一种 Boosting 算法,因此它也试图利用一群弱学习器来创建一个强学习器。该算法与AdaBoost算法相似,但在某些方面有所不同。在这种方法中,我们试图将增强问题形象化为一个优化问题。我们采用一个损失函数,并试图优化它。

将梯度增强转换为优化问题

我们采用一个较弱的学习器(在以前的案例中是decision stump),在每一次迭代步中,我们都添加一个较弱的学习器,以提高性能,从而构建一个较强的学习者,该过程减少了损失函数的大小。我们迭代地添加每个模型并计算损失,损失表示为误差残差(实际值和预测值之间的差值),使用这个损失值更新预测,以最小化残差。

我们来一步一步讲解:

AdaBoost, GBDT和XGBoost的区别和联系

在第一个迭代中,我们使用一个简单的模型,并试图匹配完整的数据。从上图可以看出,模型的ground truth 和预测值是不同的。误差残差被绘制在图像的右侧。损失函数试图通过添加更多的弱学习者器减少这些错误残差。新增的弱学习器是为了专注于现有学习者表现较差的领域。

AdaBoost, GBDT和XGBoost的区别和联系

经过三次迭代后,如上图,可以观察到该模型能够更好地拟合数据。迭代地执行该过程直到残差无限接近于零。

AdaBoost, GBDT和XGBoost的区别和联系

# Gradient Boosting 
from sklearn.ensemble import GradientBoostingClassifier
clf = GradientBoostingClassifier()
# n_estimators = 100 (default)
# loss function = deviance(default) used in Logistic Regression
clf.fit(x_train,y_train)
clf.predict(x_test)

XGBoost (Extreme Gradient Boosting)

XGBoost掀起了一场数据科学竞赛的风暴。XGBoost似乎是用于赢得数据科学竞赛的分类器/预测器必不可少的算法。为什么XGBoost如此强大呢?

XGBoost类似于梯度增强算法,但它有一些技巧,使其脱颖而出:

  • clever penalisation of trees
  • 叶节点的比例收缩 (A Proportional shrinking of leaf nodes)
  • Newton Boosting
  • 额外的随机化参数

在XGBoost中,树可以有不同数量的终端节点,并且计算证据较少的树的左权值收缩得更厉害。Newton Boosting 采用 Newton-Raphson 近似法,比梯度下降法提供了一条直接到达最小值的路径。额外的随机化参数可以用来减少树之间的相关性,正如在前一篇文章中所看到的,分类器之间的相关性越小,我们的分类器集合就会越好。一般来说,XGBoost比 Gradient Boosting 快,但 Gradient Boosting 的范围很广。

# XGBoost 
from xgboost import XGBClassifier
clf = XGBClassifier()
# n_estimators = 100 (default)
# max_depth = 3 (default)
clf.fit(x_train,y_train)
clf.predict(x_test)