XGBoost、LightGBM的详细对比介绍

sklearn集成方法

集成方法的目的是结合一些基于某些算法训练获得的基学习器来改进其泛化能力和鲁棒性(相对单个的基学习器而言)
主流的两种作法分别是:node

bagging

基本思想

独立的训练一些基学习器(通常倾向于强大而复杂的模型好比彻底生长的决策树),而后综合他们的预测结果,一般集成模型的效果会优于基学习器,由于模型的方差有所下降。python

常见变体(按照样本采样方式的不一样划分)

  • Pasting:直接从样本集里随机抽取的到训练样本子集
  • Bagging:自助采样(有放回的抽样)获得训练子集
  • Random Subspaces:列采样,按照特征进行样本子集的切分
  • Random Patches:同时进行行采样、列采样获得样本子集

sklearn-bagging

学习器

  • BaggingClassifier
  • BaggingRegressor

参数

  • 可自定义基学习器
  • max_samples,max_features控制样本子集的大小
  • bootstrap,bootstrap_features控制是否使用自主采样法
    • 当使用自助采样法时,能够设置参数oob_score=True来经过包外估计来估计模型的泛化偏差(也就不须要进行交叉验证了)

Note:方差的产生主要是不一样的样本训练获得的学习器对于同一组测试集作出分类、预测结果的波动性,究其缘由是基学习器可能学到了所供学习的训练样本中的局部特征或者说是拟合了部分噪声数据,这样综合不一样的学习器的结果,采起多数表决(分类)或者平均(回归)的方法能够有效改善这一情况git

sklearn-forests of randomized trees

学习器

  • RandomForest: 采起自主采样法构造多个基学习器,而且在学习基学习器时,不是使用所有的特征来选择最优切分点,而是先随机选取一个特征子集随后在特征子集里挑选最优特征进行切分;这种作法会使得各个基学习器的误差略微提高,但在总体上下降了集成模型的方差,因此会获得总体上不错的模型
    • RandomForestClassifier
    • RandomForestRegressor

Notes:算法

  • 不一样于原始的模型实现(让各个基学习器对样本的分类进行投票),sklearn里随机森林的实现是经过将各个基学习器的预测几率值取平均来获得最终分类
  • 随机森林的行采样(bagging)和列采样(feature bagging)都是为了减少模型之间的相关性使基学习器变得不一样从而减少集成模型的方差bootstrap

  • Extra-Trees(extremely randomized trees):相较于rf进一步加强了随机性,rf是对各个基学习器随机挑选了部分特征来作维特征子集从中挑选最佳的特征切分,而Extra-Trees更进一步,在特征子集里挑选最佳特征时不是选择最有区分度的特征值,而是随机选择这一划分的阈值(该阈值在子特征集里的特征对应的采样后的样本取值范围里随机选取),而不一样的随机阈值下的特征中表现最佳的做为划分特征,这样其实加强了随机性,更进一步整大了基学习器的误差但下降了总体的方差性能优化

    • ExtraTreesClassifier
    • ExtraTreesRegressor

调参

  • 最重要的两个参数
    • n_estimators:森林中树的数量,初始越多越好,可是会增长训练时间,到达必定数量后模型的表现不会再有显著的提高
    • max_features:各个基学习器进行切分时随机挑选的特征子集中的特征数目,数目越小模型总体的方差会越小,可是单模型的误差也会上升,经验性的设置回归问题的max_features为总体特征数目,而分类问题则设为总体特征数目开方的结果
  • 其余参数
    • max_depth:树的最大深度,经验性的设置为None(即不设限,彻底生长)
    • min_samples_split,节点最小分割的样本数,表示当前树节点还能够被进一步切割的含有的最少样本数;经验性的设置为1,缘由同上
    • bootstrap,rf里默认是True也就是采起自助采样,而Extra-Trees则是默认关闭的,是用整个数据集的样本,当bootstrap开启时,一样能够设置oob_score为True进行包外估计测试模型的泛化能力
    • n_jobs,并行化,能够在机器的多个核上并行的构造树以及计算预测值,不过受限于通讯成本,可能效率并不会说分为k个线程就获得k倍的提高,不过总体而言相对须要构造大量的树或者构建一棵复杂的树而言仍是高效的
    • criterion:切分策略:gini或者entropy,默认是gini,与树相关
    • min_impurity_split–>min_impurity_decrease:用来进行早中止的参数,判断树是否进一步分支,原先是比较不纯度是否仍高于某一阈值,0.19后是判断不纯度的下降是否超过某一阈值
    • warm_start:若设为True则能够再次使用训练好的模型并向其中添加更多的基学习器
    • class_weight:设置数据集中不一样类别样本的权重,默认为None,也就是全部类别的样本权重均为1,数据类型为字典或者字典列表(多类别)
      • balanced:根据数据集中的类别的占比来按照比例进行权重设置n_samples/(n_classes*np.bincount(y))
      • balanced_subsamples:相似balanced,不过权重是根据自助采样后的样原本计算

方法

  • predict(X):返回输入样本的预测类别,返回类别为各个树预测几率均值的最大值
  • predict_log_proba(X):
  • predict_proba(X):返回输入样本X属于某一类别的几率,经过计算随机森林中各树对于输入样本的平均预测几率获得,每棵树输出的几率由叶节点中类别的占比获得
  • score(X,y):返回预测的平均准确率

特征选择

特征重要性评估:一棵树中的特征的排序(好比深度)能够用来做为特征相对重要性的一个评估,居于树顶端的特征相对而言对于最终样本的划分贡献最大(通过该特征划分所涉及的样本比重最大),这样能够经过对比各个特征所划分的样本比重的一个指望值来评估特征的相对重要性,而在随机森林中,经过对于不一样树的特征的指望取一个平都可以减少评估结果的方差,以供特征选择;在sklearn中这些评估最后被保存在训练好的模型的参数featureimportances里,是各个特征的重要性值通过归一化的结果,越高表明特征越匹配预测函数网络

Notes:app

  • 此外sklearn还有一种RandomTreesEmbedding的实现,不是很清楚有何特殊用途

随机森林与KNN

  • 类似之处:均属于所谓的权重近邻策略(weighted neighborhoods schemes):指的是,模型经过训练集来经过输入样本的近邻样本点对输入样本做出预测,经过一个带权重的函数关系

boosting

基本思想

一个接一个的(串行)训练基学习器,每个基学习器主要用来修正前面学习器的误差。dom

sklearn-AdaBoost

  • AdaBoost可用于分类和回归
    • AdaBoostClassifier
    • AdaBoostRegressor
  • 参数
    • n_estimators:基学习器数目
    • learning_rate:学习率,对应在最终的继承模型中各个基学习器的权重
    • base_estimator:基学习器默认是使用决策树桩

_Notes:调参的关键参数是基学习器的数量n_estimators以及基学习器自己的复杂性好比深度max_depth或者叶节点所需的最少样本数min_samples_leaf_分布式

sklearn-GBRT

概述

Gradient Tree Boosting或者说GBRT是boosting的一种推广,是的能够应用通常的损失函数,能够处理分类问题和回归问题,应用普遍,常见应用场景好比网页搜索排序和社会生态学

优缺点

  • 优势:
    • 可以直接处理混合类型的特征
    • 对输出空间的异常值的鲁棒性(经过鲁棒的损失函数)
  • 缺点:
    • 难以并行,由于自己boosting的思想是一个接一个的训练基学习器

学习器

  • GradientBoostingClassifier

    • 支持二分类和多分类
    • 参数控制:
      • 基学习器的数量n_estimators
      • 每棵树的大小能够经过树深max_depth或者叶节点数目max_leaf_nodes来控制(注意两种树的生长方式不一样,max_leaf_nodes是针对叶节点优先挑选不纯度降低最多的叶节点,这里有点LightGBM的’leaf-wise’的意味,而按树深分裂则更相似于原始的以及XGBoost的分裂方式)
      • 学习率learning_rate对应取值范围在(0,1]之间的超参数对应GBRT里的shrinkage来避免过拟合(是sklearn里的GBDT用来进行正则化的一种策略);
      • 对于须要多分类的问题须要设置参数n_classes对应每轮迭代的回归树,这样整体树的数目是n_classes*n_estimators
      • criterion用来设置回归树的切分策略
        • friedman_mse,对应的最小平方偏差的近似,加入了Friedman的一些改进
        • mse对应最小平方偏差
        • mae对应平均绝对值偏差
      • subsample:行采样,对样本采样,即训练每一个基学习器时再也不使用原始的所有数据集,而是使用一部分,而且使用随机梯度上升法来作集成模型的训练
      • 列采样:max_features在训练基学习器时使用一个特征子集来训练,相似随机森林的作法
      • early stopping:经过参数min_impurity_split(原始)以及min_impurity_decrease来实现,前者的是根据节点的不纯度是否高于阈值,若不是则中止增加树,做为叶节点;后者则根据分裂不纯度降低值是否超过某一阈值来决定是否分裂(此外这里的early stopping彷佛与XGBoost里显示设置的early stopping不一样,这里是控制树的切分生长,而XGBoost则是控制基学习器的数目)
        另一点,有说这里的early_stopping起到了一种正则化的效果,由于控制了叶节点的切分阈值从而控制了模型的复杂度(可参考李航《统计学习方法》P213底部提高方法没有显式的正则化项,一般经过早中止的方法达到正则化的效果)
      • 基学习器的初始化:init,用来计算初始基学习器的预测,须要具有fitpredict方法,若未设置则默认为loss.init_estimator
      • 模型的重复使用(热启动):warm_start,若设置为True则可使用已经训练好的学习器,而且在其上添加更多的基学习器
      • 预排序:presort,默认设置为自动,对样本按特征值进行预排序从而提升寻找最优切分点的效率,自动模式下对稠密数据会使用预排序,而对稀疏数据则不会
      • 损失函数(loss)
        • 二分类的对数损失函数(Binomial deviance,’deviance’),提供几率估计,模型初值设为对数概率
        • 多分类的对数损失(Multinomial deviance,’deviance’),针对n_classes互斥的多分类,提供几率估计,初始模型值设为各种别的先验几率,每一轮迭代须要构建n类回归树可能会使得模型对于多类别的大数据集不过高效
        • 指数损失函数(Exponential loss),与AdaBoostClassifier的损失函数一致,相对对数损失来讲对错误标签的样本不够鲁棒,只可以被用来做二分类
    • 经常使用方法
      • 特征重要性(feature_importances_):进行特征重要性的评估
      • 包外估计(oob_improvement_),使用包外样原本计算每一轮训练后模型的表现提高
      • 训练偏差(train_score_)
      • 训练好的基学习器集合(estimators_)
      • fit方法里能够设置样本权重sample_weight,monitor能够用来回调一些方法好比包外估计、早中止等
  • GradientBoostingRegressor

    • 支持不一样的损失函数,经过参数loss设置,默认的损失函数是最小均方偏差ls
    • 经过属性train_score_可得到每轮训练的训练偏差,经过方法staged_predict能够得到每一阶段的测试偏差,经过属性feature_importances_能够输出模型判断的特征相对重要性
    • 损失函数:
      • 最小均方偏差(Least squares,’ls’),计算方便,通常初始模型为目标均值
      • 最小绝对值偏差(Least absolute deviation,’lad’),初始模型为目标中位值
      • Huber,一种结合了最小均方偏差和最小绝对值偏差的方法,使用参数alpha来控制对异常点的敏感状况

正则化

  • Shrinkage,对应参数learning rate一种简单的正则化的策略,经过控制每个基学习器的贡献,会影响到基学习器的数目即n_estimators,经验性的设置为一个较小的值,好比不超过0.1的常数值,而后使用early stopping来控制基学习器的数目
  • 行采样,使用随机梯度上升,将gradient boosting与bagging相结合,每一次迭代经过采样的样本子集来训练基学习器(对应参数subsample),通常设置shrinkage比不设置要好,而加上行采样会进一步提高效果,而仅使用行采样可能效果反而不佳;并且进行行采样后可以使用包外估计来计算模型每一轮训练的效果提高,保存在属性oob_improvement_里,能够用来作模型选择,可是包外预估的结果一般比较悲观,因此除非交叉验证太过耗时,不然建议结合交叉验证一块儿进行模型选择
  • 列采样,相似随机森林的作法,经过设置参数max_features来实现

可解释性

单一的决策树能够经过将树结构可视化来分析和解释,而梯度上升模型由于由上百课回归树组成所以他们很难像单独的决策树同样被可视化,不过也有一些技术来辅助解释模型

  • 特征重要性(featureimportances属性),决策树在选择最佳分割点时间接地进行了特征的选择,而这一信息能够用来评估每个特征的重要性,基本思想是一个特征越常常地被用来做为树的切分特征(更加说明使用的是CART树或其变体,由于ID3,C4.5都是特征用过一次后就再也不用了),那么这个特征就越重要,而对于基于树的集成模型而言能够经过对各个树判断的特征重要性作一个平均来表示特征的重要性
  • PDP(Partial dependence plots),能够用来绘制目标响应与目标特征集的依赖关系(控制其余的特征的值),受限于人类的感知,目标特征集合通常设置为1或2才能绘制对应的图形(plot_partial_dependence),也能够经过函数partial_dependence来输出原始的值

Notes:

  • GradientBoostingClassifier和GradientBoostingRegressor均支持对训练好的学习器的复用,经过设置warm_start=True能够在已经训练好的模型上添加更多的基学习器

VotingClassifier

Voting的基本思想是将不一样学习器的结果进行硬投票(多数表决)或者软投票(对预测几率加权平均)来对样本类别作出预估,其目的是用来平衡一些表现至关且都还不错的学习器的表现,以消除它们各自的缺陷

  • 硬投票(voting=’hard’):按照多数表决原则,根据分类结果中多数预测结果做为输入样本的预测类别,若是出现类别数目相同的状况,会按照预测类别的升序排序取前一个预测类别(好比模型一预测为类别‘2’,模型二预测为类别‘1’则样本会被判为类别1)
  • 软投票:对不一样基学习器的预测几率进行加权平均(所以使用软投票的基学习器须要可以预测几率),需设置参数wights为一个列表表示各个基学习器的权重值

XGBoost

过拟合

XGBoost里可使用两种方式防止过拟合

  • 直接控制模型复杂度
    • max_depth,基学习器的深度,增长该值会使基学习器变得更加复杂,荣易过拟合,设为0表示不设限制,对于depth-wise的基学习器学习方法须要控制深度
    • min_child_weight,子节点所需的样本权重和(hessian)的最小阈值,如果基学习器切分后获得的叶节点中样本权重和低于该阈值则不会进一步切分,在线性模型中该值就对应每一个节点的最小样本数,该值越大模型的学习约保守,一样用于防止模型过拟合
    • gamma,叶节点进一步切分的最小损失降低的阈值(超过该值才进一步切分),越大则模型学习越保守,用来控制基学习器的复杂度(有点LightGBM里的leaf-wise切分的意味)
  • 给模型训练增长随机性使其对噪声数据更加鲁棒
    • 行采样:subsample
    • 列采样:colsample_bytree
    • 步长:eta即shrinkage

数据类别分布不均

对于XGBoost来讲一样是两种方式

  • 若只关注预测的排序表现(auc)
    • 调整正负样本的权重,使用scale_pos_weight
    • 使用auc做为评价指标
  • 若关注预测出正确的几率值,这种状况下不能调整数据集的权重,能够经过设置参数max_delta_step为一个有限值好比1来加速模型训练的收敛

调参

通常参数

主要用于设置基学习器的类型

  • 设置基学习器booster
    • 基于树的模型
      • gbtree
      • dart
    • 线性模型
      • gblinear
  • 线程数nthread,设置并行的线程数,默认是最大线程数

基学习器参数

在基学习器肯定后,根据基学习器来设置的一些个性化的参数

  • eta,步长、学习率,每一轮boosting训练后能够获得新特征的权重,能够经过eta来适量缩小权重,使模型的学习过程更加保守一点,以防止过拟合
  • gamma,叶节点进一步切分的最小损失降低的阈值(超过该值才进一步切分),越大则模型学习越保守,用来控制基学习器的复杂度(有点LightGBM里的leaf-wise切分的意味)
  • max_depth,基学习器的深度,增长该值会使基学习器变得更加复杂,荣易过拟合,设为0表示不设限制,对于depth-wise的基学习器学习方法须要控制深度
  • min_child_weight,子节点所需的样本权重和(hessian)的最小阈值,如果基学习器切分后获得的叶节点中样本权重和低于该阈值则不会进一步切分,在线性模型中该值就对应每一个节点的最小样本数,该值越大模型的学习约保守,一样用于防止模型过拟合
  • max_delta_step,树的权重的最大估计值,设为0则表示不设限,设为整数会是模型学习相对保守,通常该参数没必要设置,可是对于基学习器是LR时,在针对样本分布极为不均的状况控制其值在1~10之间能够控制模型的更新
  • 行采样:subsample,基学习器使用样本的比重
  • 列采样:
    • colsample_bytree,用于每棵树划分的特征比重
    • colsample_bylevel,用于每层划分的特征比重
  • 显式正则化,增长该值是模型学习更为保守
    • L1:alpha
    • L2:lambda
  • tree_method,树的构建方法,准确的说应该是切分点的选择算法,包括原始的贪心、近似贪心、直方图算法(可见LightGBM这里并非一个区别)
    • auto,启发式地选择分割方法,近似贪心或者贪心
    • exact,原始的贪心算法,既针对每个特征值切分一次
    • approx,近似的贪心算法选取某些分位点进行切分,使用sketching和histogram
    • hist,直方图优化的贪心算法,对应的参数有grow_policy,max_bin
    • gpu_exact
    • gpu_hist
  • scale_pos_weight,针对数据集类别分布不均,典型的值可设置为
    sum(negativecases)sum(positivecases)sum(negativecases)sum(positivecases)
  • grow_policy,控制树的生长方式,目前只有当树的构建方法tree_method设置为hist时才可使用所谓的leaf-wise生长方式
    • depthwise,按照离根节点最近的节点进行分裂
    • lossguide,优先分裂损失变化大的节点,对应的一个参数还有max_leaves,表示可增长的最大的节点数
  • max_bin,一样针对直方图算法tree_method设置为hist时用来控制将连续特征离散化为多个直方图的直方图数目
  • predictor,选择使用GPU或者CPU
    • cpu_predictor
    • gpu_predictor

任务参数

根据任务、目的设置的参数,好比回归任务与排序任务的目的是不一样的

  • objective,训练目标,分类仍是回归
    • reg:linear,线性回归
    • reg:logistic,逻辑回归
    • binary:logistic,使用LR二分类,输出几率
    • binary:logitraw,使用LR二分类,但在进行logistic转换以前直接输出分类得分
    • count:poisson,泊松回归
    • multi:softmax,使用softmax进行多分类,须要设置类别数num_class
    • multi:softprob
    • rank:pairwise,进行排序任务,最小化pairwise损失
    • reg:gamma,gamma回归
    • reg:tweedie,tweedie回归
  • 评价指标eval_metric,默认根据目标函数设置,针对验证集,默认状况下,最小均方偏差用于回归,错分用于分类,平均精确率用于排序等,能够同时使用多个评估指标,在python里使用列表来放置
    • 均方偏差rmse
    • 平均绝对值偏差mae
    • 对数损失logloss,负的对数似然
    • 错误率error,根据0.5做为阈值判断的错分率
    • 自定义阈值错分率error@t
    • 多分类错分率merror
    • 多分类对数损失mlogloss
    • auc主要用来排序
    • ndcg,normalized discounted cumulative gain及其余的一些针对泊松回归等问题的评价指标

命令行参数

  • num_round迭代次数,也对应基学习器数目
  • task当前对模型的任务,包括
    • 训练train
    • 预测pred
    • 评估/验证eval
    • 导出模型dump
  • 导入导出模型的路径model_inmodel_out
  • fmap,feature map用来导出模型

LightGBM

特色

效率和内存上的提高

直方图算法,LightGBM提供一种数据类型的封装相对Numpy,Pandas,Array等数据对象而言节省了内存的使用,缘由在于他只须要保存离散的直方图,LightGBM里默认的训练决策树时使用直方图算法,XGBoost里如今也提供了这一选项,不过默认的方法是对特征预排序,直方图算法是一种牺牲了必定的切分准确性而换取训练速度以及节省内存空间消耗的算法

  • 在训练决策树计算切分点的增益时,预排序须要对每一个样本的切分位置计算,因此时间复杂度是O(#data)而LightGBM则是计算将样本离散化为直方图后的直方图切割位置的增益便可,时间复杂度为O(#bins),时间效率上大大提升了(初始构造直方图是须要一次O(#data)的时间复杂度,不过这里只涉及到加和操做)
  • 直方图作差进一步提升效率,计算某一节点的叶节点的直方图能够经过将该节点的直方图与另外一子节点的直方图作差获得,因此每次分裂只需计算分裂后样本数较少的子节点的直方图而后经过作差的方式得到另外一个子节点的直方图,进一步提升效率
  • 节省内存
    • 将连续数据离散化为直方图的形式,对于数据量较小的情形可使用小型的数据类型来保存训练数据
    • 没必要像预排序同样保留额外的对特征值进行预排序的信息
  • 减小了并行训练的通讯代价

稀疏特征优化

对稀疏特征构建直方图时的时间复杂度为O(2*#非零数据)

准确率上的优化

LEAF-WISE(BEST-FIRST)树生长策略

相对于level-wise的生长策略而言,这种策略每次都是选取当前损失降低最多的叶节点进行分割使得总体模型的损失降低得更多,可是容易过拟合(特别当数据量较小的时候),能够经过设置参数max_depth来控制树身防止出现过拟合

Notes:XGBoost如今两种方式都是支持的

直接支持类别特征

对于类别类型特征咱们原始的作法是进行独热编码,可是这种作法对于基于树的模型而言不是很好,对于基数较大的类别特征,可能会生成很是不平衡的树而且须要一颗很深的树才能达到较好的准确率;比较好的作法是将类别特征划分为两个子集,直接划分方法众多(2^(k-1)-1),对于回归树而言有一种较高效的方法只须要O(klogk)的时间复杂度,基本思想是对类别按照与目标标签的相关性进行重排序,具体一点是对于保存了类别特征的直方图根据其累计值(sum_gradient/sum_hessian)重排序,在排序好的直方图上选取最佳切分位置

网络通讯优化

使用collective communication算法替代了point-to-point communication算法提高了效率

并行学习优化

特征并行

特征并行是为了将寻找决策树的最佳切分点这一过程并行化

  • 传统作法
    • 对数据列采样,即不一样的机器上保留不一样的特征子集
    • 各个机器上的worker根据所分配的特征子集寻找到局部的最优切分点(特征、阈值)
    • 互相通讯来从局部最佳切分点里获得最佳切分点
    • 拥有最佳切分点的worker执行切分操做,而后将切分结果传送给其余的worker
    • 其余的worker根据接收到的数据来切分数据
    • 传统作法的缺点
      • 计算量太大,并无提高切分的效率,时间复杂度为O(#data)(由于每一个worker持有全部行,须要处理所有的记录),当数据量较大时特征并行并不能提高速度
      • 切分结果的通讯代价,大约为O(#data/8)(若一个数据样本为1bit)
  • LightGBM的作法
    让每一个机器保留整个完整的数据集(并非通过列采样的数据),这样就没必要在切分后传输切分结果数据,由于每一个机器已经持有完整的数据集
    • 各个机器上的worker根据所分配的特征子集寻找到局部的最优切分点(特征、阈值)
    • 互相通讯来从局部最佳切分点里获得最佳切分点
    • 执行最优切分操做

Notes:典型的空间换时间,差异就是减小了传输切分结果的步骤,节省了这里的通讯消耗

数据并行

上述特征并行的方法并无根本解决寻找切分点的计算效率问题,当记录数过大时须要考虑数据并行的方法

  • 传统作法
    • 行采样,对数据进行横向切分
    • worker使用分配到的局部数据构建局部的直方图
    • 合并局部直方图获得全局的直方图
    • 对全局直方图寻找最优切分点,而后进行切分
    • 缺点:通讯代价太高,若使用point-to-point的通讯算法,每一个机器的通讯代价时间复杂度为O(#machine*#feature*#bin),若使用collective通讯算法则通讯代价为O(2*#feature*#bin)
  • LightGBM的作法(依然是下降通讯代价)
    • 不一样于合并全部的局部直方图得到全局的直方图,LightGBM经过Reduce Scatter方法来合并不一样worker的无交叉的不一样特征的直方图,这样找到该直方图的局部最优切分点,最后同步到全局最优切分点
    • 基于直方图作差的方法,在通讯的过程当中能够只传输某一叶节点的直方图,而对于其邻居可经过作差的方式获得
    • 通讯的时间复杂度为O(0.5*#feature*#bin)

并行投票

进一步减少了数据并行中的通讯代价,经过两轮的投票来减少特征直方图中的通讯消耗

其余特色

直接支持类别(标称)特征

LightGBM能够直接用类别特征进行训练,没必要预先进行独热编码,速度会提高很多,参数设置categorical_feature来指定数据中的类别特征列

早中止

sklearn-GBDT,XGBoost,LightGBM都支持早中止,不过在细节上略有不一样

  • sklearn-GBDT中的early stopping是用来控制基学习器的生长的:经过参数min_impurity_split(原始)以及min_impurity_decrease来实现,前者的是根据节点的不纯度是否高于阈值,若不是则中止增加树,做为叶节点;后者则根据分裂不纯度降低值是否超过某一阈值来决定是否分裂(此外这里的early stopping彷佛与XGBoost里显示设置的early stopping不一样,这里是控制树的切分生长,而XGBoost则是控制基学习器的数目)
  • XGBoost和LightGBM里的early_stopping则都是用来控制基学习器的数目的
    • 二者均可以使用多组评价指标,可是不一样之处在于XGBoost会根据指标列表中的最后一项指标控制模型的早中止,而LightGBM则会受到全部的评估指标的影响
    • 在使用early stopping控制迭代次数后,模型直接返回的是最后一轮迭代的学习器不必定是最佳学习器,而在作出预测时能够设置参数选择某一轮的学习器做出预测
      • XGBoost里保存了三种状态的学习器,分别是bst.best_score, bst.best_iteration, bst.best_ntree_limit,官方的建议是在作预测时设置为bst.best_ntree_limit,实际使用时感受bst.best_iteration和 bst.best_ntree_limit的表现上区别不大
      • LightGBM则仅提供了bst.best_iteration这一种方式

实践上

  • 内置cv
  • 支持带权重的数据输入
  • 能够保留模型
  • DART
  • L1/L2回归
  • 保存模型进行进一步训练
  • 多组验证集

支持的任务

  • 回归任务
  • 分类(二分类、多分类)
  • 排序

支持的评价指标METRIC

  • 绝对值偏差l1
  • 平方偏差l2
  • 均方偏差l2_root
  • 对数损失binary_logloss,multi_logloss
  • 分类偏差率binary_error,multi_error
  • auc
  • ndcg
  • 多分类对数损失
  • 多分类分类偏差率

调参

核心参数

  • 叶节点数num_leaves,与模型复杂度直接相关(leaf-wise)
  • 任务目标
    • 回归regression,对应的损失函数以下
      • regression_l1,加了l1正则的回归,等同于绝对值偏差
      • regression_l2,等同于均方偏差
      • huber,Huber Loss
      • fair,Fair Loss
      • poisson,泊松回归
    • 分类
      • binary,二分类
      • multiclass,多分类
    • 排序
      • lambdarank
  • 模型
    • boosting
      • gbdt,传统的梯度提高决策树
      • rf,随机森林
      • dart,Dropouts meet Multiple Additive Regression Trees
      • goss,Gradient-based One-Side Sampling
  • 迭代次数num_iterations,对于多分类问题,LightGBM会构建num_class*num_iterations的树
  • 学习率/步长learning_rate,即shrinkage
  • 树的训练方式tree_learner,主要用来控制树是否并行化训练
    • serial,单机的树学习器
    • feature,特征并行的树学习器
    • data,数据并行的树学习器
  • 线程数num_threads
  • 设备device,使用cpu仍是gpu
    • cpu
    • gpu

训练控制参数

防止过拟合

  • 树的最大深度max_depth,主要用来避免模型的过拟合,设为负数值则代表不限制
  • 叶节点的最少样本数min_data_in_leaf
  • 叶节点的最小海森值之和min_sum_hessian_in_leaf
  • 列采样feature_fraction,每棵树的特征子集占比,设置在0~1之间,能够加快训练速度,避免过拟合
  • 行采样bagging_fraction,不进行重采样的随机选取部分样本数据,此外须要设置参数bagging_freq来做为采样的频率,即多少轮迭代作一次bagging;
  • 早中止early_stopping_roung,在某一验证数据的某一验证指标当前最后一轮迭代没有提高时中止迭代
  • 正则化
    • lambda_l1
    • lambda_l2
  • 切分的最小收益min_gain_to_split

IO参数

直方图相关

  • 最大直方图数max_bin,特征值装载的最大直方图数目,通常较小的直方图数目会下降训练的准确性但会提高总体的表现,处理过拟合
  • 直方图中最少样本数min_data_in_bin,设置每一个直方图中样本数的最小值,一样防止过拟合

特征相关

  • 是否预排序is_pre_partition
  • 是否稀疏is_sparse
  • 类别特征列categorical_feature,声明类别特征对应的列(经过索引标记),仅支持int类型
  • 声明权重列weight,指定一列做为权重列

内存相关

  • 分阶段加载数据two_round,通常LightGBM将数据载入内存进行处理,这样会提高数据的加载速度,可是对于数据量较大时会形成内存溢出,因此此时须要分阶段载入
  • 保存数据为二进制save_binary,将数据文件导出为二进制文件,下次加载数据时就会更快一些

缺失值

  • 是否处理缺失值use_missing
  • 是否将0值做为缺失值zeros_as_missing

目标参数

  • sigmoid,sigmoid函数中的参数,用于二分类和排序任务
  • scale_pos_weight,设置正例在二分类任务中的样本占比
  • 初始化为均值boost_from_average,调整初始的分数为标签的均值,加速模型训练的收敛速度,仅用于回归任务
  • 样本类别是否不平衡is_unbalance
  • num_class,用于多分类

调参小结

LEAF-WISE

  • num_leaves,对于leaf-wise的模型而言该参数是用来控制模型复杂度的主要参数,理论上能够经过设置num_leaves=2^(max_depth)来设置该参数值,实际是不可取的,由于在节点数目相同的前提下,对于leaf-wise的模型会倾向于生成深度更深的模型,若是生硬的设置为2^(max_depth)可能会形成模型的过拟合,通常设置的值小于2^(max_depth),
  • min_data_in_leaf,在设置了叶节点数后,该值会对模型复杂度形成影响,若设的较大则树不会生长的很深,但可能形成模型的欠拟合
  • max_depth

效率

  • bagging_fractionbagging_freq,使用bagging进行行采样提高训练速度(减少了数据集)
  • feature_fraction,列采样
  • 设置较少的直方图数目,max_bin
  • 保存数据为二进制文件以便于将来训练时能快速加载,save_binary
  • 经过并行训练来提速

准确率

  • 设置较大的直方图数目max_bin,固然这样会牺牲训练速度
  • 使用较小的学习率learning_rate,这样会增长迭代次数
  • 设置较大的叶节点数num_leaves,可能形成模型过拟合
  • 使用较大的训练数据
  • 尝试dart模型

过拟合

  • 设置较少的直方图数目,max_bin
  • 设置较小的叶节点数num_leaves
  • 设置参数min_data_in_leafmin_sum__hessian_in_leaf
  • 使用bagging进行行采样bagging_fractionbagging_freq
  • feature_fraction,列采样
  • 使用较大的训练数据
  • 正则化
    • lambda_l1
    • lambda_l2
    • 切分的最小收益min_gain_to_split
  • 控制树深max_depth

总结

GBDT vs. XGBoost vs. LightGBM(论文层面)

GBDT vs. XGBoost

  • GBDT无显式正则化
  • GBDT仅使用了目标函数一阶泰勒展开,而XGBoost使用了二阶的泰勒展开值
    • 为何二阶展开?
      • 一说加快收敛速度
      • 另外有说自己模型训练的学习率shrinkage能够经过二阶导数作一个逼近,而原始的GBDT没有计算这个,因此通常是经过预设的超参数eta人为指定
  • XGBoost加入了列采样
  • XGBoost对缺失值的处理
  • XGBoost经过预排序的方法来实现特征并行,提升模型训练效率
  • XGBoost支持分布式计算

XGBoost vs. LightGBM

  • 树的切分策略不一样
    • XGBoost是level-wise而LightGBM是leaf-wise
  • 实现并行的方式不一样
    • XGBoost是经过预排序的方式
    • LightGBM则是经过直方图算法
  • LightGBM直接支持类别特征,对类别特征没必要进行独热编码处理

sklearn GBDT vs. XGBoost vs. LightGBM(实现层面)

实际在库的实现层面原始论文里的不少区别是不存在的,差别更多在一些工程上的性能优化

sklearn GBDT vs. XGBoost

  • 正则化方式不一样
    • sklearn GBDT中仅仅经过学习率来作一个正则化(影响到基学习器的数目),此外gbdt里的early stopping也达到了一个正则化的效果,对应的主要参数是min_impurity_split即控制了判断叶节点是否进一步切分的不纯度的阈值,若超过该阈值则能够进一步切分,不然不行,故而控制了树的深度即控制了基学习器的复杂度
    • XGBoost除了学习率之外还有显示的设置正则化项l1,l2以及对应论文里的叶节点数(对应参数gamma)以及节点权重和(参数min_child_weight)来控制模型复杂度
  • GBDT仅使用了目标函数一阶泰勒展开,而XGBoost使用了二阶的泰勒展开值
  • XGBoost自有一套对缺失值的处理方法
  • early-stopping意义不一样
    • sklearn GBDT中控制基学习器进一步切分、生长
    • XGBoost控制基学习器的数目
  • 特征重要性的判断标准
    • sklearn GBDT是根据树的节点特征对应的深度来判断
    • XGBoost则有三种方法(get_score)
      • weight:特征用来做为切分特征的次数
      • gain:使用特征进行切分的平均增益
      • cover:各个树中该特征平均覆盖状况(根据样本?)
  • 树的切分算法
    • XGBoost存在三种切分方法,
      • 原始的贪心算法(每一个特征值切分)
      • 近似贪心(分位点切分)(使得对于大量的特征取值尤为是连续变量时XGBoost会比sklearn-gbdt快不少)
      • 直方图算法
  • XGBoost支持level-wise和leaf-wise两种树的生长方式
  • XGBoost支持GPU
  • XGBoost支持多种评价标准、支持多种任务(回归、分类、排序)

XGBoost vs. LightGBM

XGBoost目前已经实现了LightGBM以前不一样的一些方法好比直方图算法,二者的区别更多的在与LightGBM优化通讯的的一些处理上

    • LightGBM直接支持类别特征,能够没必要预先进行独热编码,提升效率(categorical_feature)
    • 优化通讯代价
      • 特征并行
      • 数据并行
      • point to point communication–>collective communication
    • 使用多项评价指标同时评价时二者的早中止策略不一样,XGBoost是根据评价指标列表中的最后一项来做为中止标准,而LightGBM则受到全部评价指标的影响

转载自:懒死骆驼: http://izhaoyi.top/2017/09/23/sklearn-xgboost/

相关文章
相关标签/搜索