龙空技术网

CatBoost, XGBoost, AdaBoost, LightBoost,各种Boost的介绍和对比

deephub 972

前言:

此刻大家对“leaf function”大概比较看重,咱们都想要学习一些“leaf function”的相关知识。那么小编也在网摘上汇集了一些有关“leaf function””的相关文章,希望同学们能喜欢,兄弟们快快来了解一下吧!

本文内容

介绍AdaBoostGradient BoostXGBoostHistogram-Based Gradient BoostLightBoostCatBoost总结介绍

在集成学习中,目标是用多种学习算法最成功地训练模型。Bagging方法是一种集成学习方法,将多个模型并行应用于同一数据集的不同子样本。Boosting是另一种在实践中经常使用的方法,它不是并行构建的,而是按顺序构建的,目的是训练算法和模型。弱算法先对模型进行训练,然后根据训练结果对模型进行重组,使模型更容易学习。然后将修改后的模型发送给下一个算法,第二个算法比第一个算法学习起来更容易。本文包含了不同的增强方法,从不同的角度解释了这些方法并进行了简单的测试。

AdaBoost

自适应提升(Adaboost)是一种广泛使用的基于决策树桩(Decision stump: Threshold isassigned and the Prediction is made by the threshold.)的boosting方法。但是在Adaboost中并不是盲目地重复这种方法。建立了多个算法,这些算法依次更新它们的权值,并在做出最准确的估计时发挥各自的作用。计算了每种算法的错误率。权值被更新,因此被引用到第二种算法中。第二个算法对模型进行分类,像第一个模型一样更新权重,并将其转移到第三个算法。这些过程一直持续到n_estimator的数目或达到误差=0。在这个过程中,由于权值由之前的算法更新并发送给其他算法,使得分类更加容易和成功。让我们用一个例子来解释这个复杂的顺序算法过程:

假设有两个标签,红色和蓝色。第一种算法(弱分类器1)对标签进行分离,结果是2个蓝色样本和1个红色样本被误分类。这些错误分类的权重增加,正确分类的权重降低后,发送到下一个模型进行学习。在新模型中,错误分类样本的偏差增大,而正确分类样本的偏差减小,这两种模型的学习效果较好。接下来的步骤将重复相同的过程。综上所述,强分类是在弱分类的配合下发生的。因为它用于分类,所以也可以通过导入AdaBoostRegressor用于回归。

超参数

base_estimators:一个顺序改进的算法类(默认= DecisionTreeClassifier)

n_estimators:确定上述过程将采取的最大步骤数。(默认= 50)

learning_rate:决定权重的变化量。如果选择过小,则n_estimators的值必须非常高。如果它被选得太大,它可能永远达不到最优值。(默认= 1)

import numpy as npfrom time import timefrom sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score,train_test_splitfrom sklearn.model_selection import KFoldx,y = make_classification(n_samples=100000,n_features=30, n_informative=10, n_redundant=5,random_state=2021)

一个将用于所有方法的数据集已经导入,现在让我们实现Adaboost:

from sklearn.ensemble import AdaBoostClassifierstart_ada = time()ada = AdaBoostClassifier()kf=KFold(n_splits=5,shuffle=True,random_state=2021)ada_score=cross_val_score(ada,x,y,cv=kf,n_jobs=-1)print("ada", np.round(time()-start_ada,5),"sec")print("acc", np.mean(ada_score).round(3))print("***************************")
Gradient Boost

Adaboost 通过使用决策树桩(1 个节点分为 2 个叶子)更新权重来改进自身。 梯度提升是另一种顺序方法,通过创建 8 到 32 个叶子来优化损失,这意味着树在梯度提升中更大(损失:就像是在线性模型中的残差)。(y_test-y_prediction)通过每个数据点给出损失的平方和给出残差。为什么使用平方?因为我们正在寻找的值是预测与实际结果的偏差。负值平方后也会作用于损失值的计算 。简而言之,将残差值转移到下一算法,使残差值更接近于0,从而使损失值最小化。

GB = GradientBoostingClassifier()start_gb = time()kf=KFold(n_splits=5,shuffle=True,random_state=2021)GB_score=cross_val_score(GB,x,y,cv=kf,n_jobs=-1)print("gb", np.round(time()-start_gb,5),"sec")print("acc", np.mean(GB_score).round(3))print("***************************")

在Adaboost中,梯度增强可以通过导入GradientBoostRegressor用于回归。

from sklearn.metrics import mean_squared_errorx_train, x_test, y_train, y_test = train_test_split(x, y,test_size=0.2,random_state=2021)gbr = GradientBoostingRegressor(max_depth=5, n_estimators=150)gbr.fit(x_train, y_train)error_list = [mean_squared_error(y_test, y_pred) for y_pred in gbr.staged_predict(x_test)]
OUT[0.22686585533221332,0.20713350861706786,0.1900682640534445,0.1761959477525979,0.16430532532798403,0.1540494010479854,0.14517117541343785,0.1375952312491854,0.130929810958826,0.12499605002264891,0.1193395594019215,0.11477096339545599,0.11067921343289967,0.10692446632551068,..............................................................................0.05488031632425609,0.05484366975329703,0.05480676108875857,0.054808073418709524,0.054740333154284,0.05460221966859833,0.05456647041868937,0.054489873127848434,0.054376259548495065,0.0542407250628274]

查看Error_list,可以看到损失值在每一步都在变小。[从0.22开始,完成到0.05]

XGBoost

XGBoost(Extreme Gradient Boosting)是由Tianqi Chen在2014年开发的,在Gradient boost之前速度最快,是首选的Boosting方法。由于它包含超参数,可以进行许多调整,如正则化超参数防止过拟合。

超参数

booster [缺省值=gbtree]

决定那个使用那个booster,可以是gbtree,gblinear或者dart。 gbtree和dart使用基于树的模型,而gblinear 使用线性函数.

silent [缺省值=0]

设置为0打印运行信息;设置为1静默模式,不打印

nthread [缺省值=设置为最大可能的线程数]

并行运行xgboost的线程数,输入的参数应该<=系统的CPU核心数,若是没有设置算法会检测将其设置为CPU的全部核心数

下面的两个参数不需要设置,使用默认的就好了

num_pbuffer [xgboost自动设置,不需要用户设置]

预测结果缓存大小,通常设置为训练实例的个数。该缓存用于保存最后boosting操作的预测结果。

num_feature [xgboost自动设置,不需要用户设置]

在boosting中使用特征的维度,设置为特征的最大维度

eta [缺省值=0.3,别名:learning_rate]

更新中减少的步长来防止过拟合。在每次boosting之后,可以直接获得新的特征权值,这样可以使得boosting更加鲁棒。

范围: [0,1]

gamma [缺省值=0,别名: min_split_loss](分裂最小loss)

在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。Gamma指定了节点分裂所需的最小损失函数下降值。 这个参数的值越大,算法越保守。这个参数的值和损失函数息息相关,所以是需要调整的。

范围: [0,∞]

max_depth [缺省值=6]

这个值为树的最大深度。 这个值也是用来避免过拟合的。max_depth越大,模型会学到更具体更局部的样本。设置为0代表没有限制

范围: [0,∞]

min_child_weight [缺省值=1]

决定最小叶子节点样本权重和。XGBoost的这个参数是最小样本权重的和,而GBM参数是最小样本总数。 这个参数用于避免过拟合。当它的值较大时,可以避免模型学习到局部的特殊样本。 但是如果这个值过高,会导致欠拟合。这个参数需要使用CV来调整。.

范围: [0,∞]

subsample [缺省值=1]

这个参数控制对于每棵树,随机采样的比例。 减小这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过小,它可能会导致欠拟合。 典型值:0.5-1,0.5代表平均采样,防止过拟合.

范围: (0,1]

colsample_bytree [缺省值=1]

用来控制每棵随机采样的列数的占比(每一列是一个特征)。 典型值:0.5-1

范围: (0,1]

colsample_bylevel [缺省值=1]

用来控制树的每一级的每一次分裂,对列数的采样的占比。 我个人一般不太用这个参数,因为subsample参数

colsample_bytree参数可以起到相同的作用。但是如果感兴趣,可以挖掘这个参数更多的用处。

范围: (0,1]

lambda [缺省值=1,别名: reg_lambda]

权重的L2正则化项。(和Ridge regression类似)。 这个参数是用来控制XGBoost的正则化部分的。虽然大部分数据科学家很少用到这个参数,但是这个参数在减少过拟合上还是可以挖掘出更多用处的。.

alpha [缺省值=0,别名: reg_alpha]

权重的L1正则化项。(和Lasso regression类似)。 可以应用在很高维度的情况下,使得算法的速度更快。

scale_pos_weight[缺省值=1]

在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。通常可以将其设置为负样本的数目与正样本数目的比值。

from xgboost import XGBClassifierxgb = XGBClassifier()start_xgb = time()kf=KFold(n_splits=5,shuffle=True,random_state=2021)xgb_score=cross_val_score(xgb,x,y,cv=kf,n_jobs=-1)print("xgboost", np.round(time()-start_xgb,5))print("acc", np.mean(xgb_score).round(3))print("***************************")
Histogram-Based Gradient Boost

使用binning(discretizing)对数据进行分组,这是一种数据预处理方法,这里已经解释过了。 例如,当给出“年龄”列时,将这些数据分为 30-40、40-50、50-60 3 组,然后将它们转换为数值数据是一种非常有效的方法。 当这种分箱方法适用于决策树时,通过减少特征数量可以加快算法速度。 该方法还可以通过将其与直方图分组来用作构建每棵树的集成。

from sklearn.experimental import enable_hist_gradient_boostingfrom sklearn.ensemble import HistGradientBoostingClassifierHGB = HistGradientBoostingClassifier()start_hgb = time()kf=KFold(n_splits=5,shuffle=True,random_state=2021)HGB_score=cross_val_score(HGB,x,y,cv=kf,n_jobs=-1)print("hist", np.round(time()-start_hgb,5),"sec")print("acc", np.mean(HGB_score).round(3))print("***************************")
LightBoost

LGBM (Light Gradient Boosting Machine)是微软于2017年首次发布的一种基于决策树的梯度增强方法,是用户首选的另一种梯度增强方法。与其他方法的关键区别在于它是基于叶子进行树的分裂,即它可以通过关键点位检测和停计算(其他提升算法是基于深度或基于级别的)。由于LGBM是基于叶的,如图2所示,LGBM是一种非常有效的方法,可以减少误差,从而提高精度和速度。但是它不支持字符串类型的数据,需要使用特殊算法拆分分类数据,因为必须输入整数值(例如索引)而不是列的字符串名称。

from lightgbm import LGBMClassifierlgbm = LGBMClassifier()start_lgbm = time()kf=KFold(n_splits=5,shuffle=True,random_state=2021)lgbm_score=cross_val_score(lgbm,x,y,cv=kf,n_jobs=-1)print("lgbm", np.round(time()-start_lgbm,5))print("acc", np.mean(lgbm_score).round(3))print("***************************")
CatBoost

CatBoost 由 Yandex 于 2017 年开发。 由于它使用 One-Hot-Encoding 将所有分类特征转换为数值,因此名称来自 Categorical Boosting。将字符串自动转化成索引值输入的同属他还处理了缺失的数值。而且它也比 XGBoost 快得多。与其他 boosting 方法不同,Catboost 与对称树进行区分,对称树在每个级别的节点中使用相同的拆分。

XGBoost 和 LGBM 计算每个数据点的残差并训练模型以获得残差目标值。它针对迭代次数重复此操作,从而训练并降低残差,从而达到目标。由于这种方法适用于每个数据点,因此在泛化方面可能会很弱并导致过度拟合。

Catboost 还计算每个数据点的残差,并使用其他数据训练的模型进行计算。这样,每个数据点就得到了不同的残差数据。这些数据被评估为目标,并且通用模型的训练次数与迭代次数一样多。由于许多模型将根据定义实现,因此这种计算复杂性看起来非常昂贵并且需要太多时间。但是catboost通过有序提升但可以在更短的时间内完成。例如,catboost不是从每个数据点 (n+1)th 计算的残差的开头开始,俄日是计算(n+2)个数据点,应用(n+1)个数据点,依此类推

超参数

l2_leaf_reg:损失函数的L2正则化项。

learning_rate:学习率。 在过度拟合的情况下降低 learning_rate。

depth:树的深度,多在6-10之间使用。

one_hot_max_size:使用一个独热编码对所有分类特征进行编码,其中几个不同的值小于或等于给定的参数值

grow_policy:决定树的构造类型。 可以使用 SymmetricTree、Depthwise 或 Lossguide。

from catboost import CatBoostClassifiercat = CatBoostClassifier()start_cat = time()kf=KFold(n_splits=5,shuffle=True,random_state=2021)cat_score=cross_val_score(cat,x,y,cv=kf,n_jobs=-1)print("cat", np.round(time()-start_cat,5))print("acc", np.mean(cat_score).round(3))print("***************************")
总结

在本文中,使用 DecisionTree 来处理提升方法,但可以通过更改相关的超参数轻松实现其他机器学习模型。 此外,所有boosting方法都使用base version(未调整任何超参数)来比较boosting方法的性能,上面应用的代码如下表:

作者:Ibrahim Kovan

标签: #leaf function