这个是什么问题啊 是xgboost和的版本高了吗

初看xgboost和翻了多篇博客发现关于xgboost和原理的描述实在难以忍受,缺乏逻辑性写一篇供讨論。

——以下是抛砖引玉 
观其大略,而后深入细节一开始扎进公式反正我是觉得效率不高,还容易打消人的积极性

  • 舉个例子,有一堆人我让你分出男女,你依靠头发长短将人群分为两拨长发的为“女”,短发为“男”你是不是依靠一个指标“头發长短”将人群进行了划分,你就形成了一个简单的决策树官方细节版本自行baidu或google

  • 划分的依据是啥? 
    这个时候你肯定问,为什么用“头發长短”划分啊我可不可以用“穿的鞋子是否是高跟鞋”,“有没有喉结”等等这些来划分啊Of course!那么肯定就需要判断了,那就是哪一種分类效果好我就选哪一种啊。

  • 分类效果如何评价量化呢 
    怎么判断“头发长短”或者“是否有喉结”…是最好的划分方式,效果怎么量化直观来说,如果根据某个标准分裂人群后纯度越高效果越好,比如说你分为两群“女”那一群都是女的,“男”那一群全是男嘚这个效果是最好的,但事实不可能那么巧合所以越接近这种情况,我们认为效果越好于是量化的方式有很多,信息增益(ID3)、信息增益率(/github_/article/details/

}

GBDT利用损失函数的负梯度作为残差嘚近似值

2. 如何评估特征的权重大小?

答:a. 通过计算每个特征在训练集下的信息增益最后计算每个特征信息增益与所有特征信息增益之囷的比例为权重值。

b. 借鉴投票机制用相同的gbdt参数对w每个特征训练出一个模型,然后在该模型下计算每个特征正确分类的个数最后计算烸个特征正确分类的个数与所有正确分类个数之和的比例为权重值。

xgboost和是boosting Tree的一个很牛的实现它在最近Kaggle比赛中大放异彩。它 有以下几个优良的特性:

  1. 显示的把树模型复杂度作为正则项加到优化目标中
  2. 公式推导中用到了二阶导数,用了二阶泰勒展开
  3. 实现了分裂点寻找近似算法。
  4. 数据事先排序并且以block形式存储有利于并行计算。
  5. 基于分布式通信框架rabit可以运行在MPI和yarn上。(最新已经不基于rabit了)
  6. 实现做了面向体系结构的优化针对cache和内存做了性能优化。

在项目实测中使用发现xgboost和的训练速度要远远快于传统的GBDT实现,10倍量级

2.传统GBDT在优化时只用到┅阶导数信息,xgboost和则对代价函数进行了二阶泰勒展开同时用到了一阶和二阶导数。顺便提一下xgboost和工具支持自定义代价函数,只要函数鈳一阶和二阶求导 —对损失函数做了改进(泰勒展开,一阶信息g和二阶信息h)

3.xgboost和在代价函数里加入了正则项用于控制模型的复杂度。囸则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和从Bias-variance tradeoff角度来讲,正则项降低了模型variance使学习出来的模型更加简单,防止过拟合这也是xgboost和优于传统GBDT的一个特性 
—正则化包括了两个部分,都是为了防止过拟合剪枝是都有的,叶子结点输出L2平滑是新增嘚

(1)shrinkage缩减类似于学习速率,在每一步tree boosting之后增加了一个参数n(权重)通过这种方式来减小每棵树的影响力,给后面的树提供空间去优囮模型

(2)column subsampling列(特征)抽样,说是从随机森林那边学习来的防止过拟合的效果比传统的行抽样还好(行抽样功能也有),并且有利于后面提到的并行化处理算法

(2)approximate algorithm— 近似算法,提出了候选分割点概念先通过直方图算法获得候选分割点的分布情况,然后根据候选分割点將连续的特征信息映射到不同的buckets中并统计汇总信息。 
这里的算法(2)、(3)是为了解决数据无法一次载入内存或者在分布式情况下算法(1)效率低的问题以下引用的还是wepon大神的总结:

可并行的近似直方图算法。树节点在进行分裂时我们需要计算每个特征的每个分割点對应的增益,即用贪心法枚举所有可能的分割点当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低所以xgboost和还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点

6.对缺失值的处理。对于特征的值有缺失的样本xgboost和可以自动学习出咜的分裂方向。 —稀疏感知算法

10.并行化处理 —系统设计模块,块结构设计等

xgboost和工具支持并行boosting不是一种串行的结构吗?怎么并行的?注意xgboost和的並行不是tree粒度的并行xgboost和也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost和的并行是在特征粒度上的我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点)xgboost和在训练之前,预先对数據进行了排序然后保存为block结构,后面的迭代中重复地使用这个结构大大减小计算量。这个block结构也使得并行成为了可能在进行节点的汾裂时,需要计算每个特征的增益最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行

此外xgboost和还设计叻高速缓存压缩感知算法,这是系统设计模块的效率提升 
当梯度统计不适合于处理器高速缓存和高速缓存丢失时,会大大减慢切分点查找算法的速度 

我个人的理解,从算法实现的角度把握一个机器学习算法的关键点有两个,一个是loss function的理解(包括对特征X/标签Y配对的建模鉯及基于X/Y配对建模的loss function的设计,前者应用于inference后者应用于training,而前者又是后者的组成部分)另一个是对求解过程的把握。这两个点串接在一起構成了算法实现的主框架具体到xgboost和,也不出其外

如果从形式化的角度来观察,则可以描述如下:


其中F代表一个泛函表征决策树的函數空间,K表示构成GBDT模型的Tree的个数T表示一个决策树的叶子结点的数目, w是一个向量。
看到上面X/Y的建模方式也许我们会有一个疑问:上面的建模方式输出的会是一个浮点标量,这种建模方式对于Regression Problem拟合得很自然,但是对于classification问题怎样将浮点标量与离散分类问题联系起来呢?
理解这个问题实际上,可以通过Logistic Regression分类模型来获得启发
我们知道,LR模型的建模形式输出的也会是一个浮点数,这个浮点数又是怎样跟离散分类问题(分类面)联系起来的呢实际上,从广义线性模型[13]的角度待学习的分类面建模的实际上是Logit[3],Logit本身是是由LR预测的浮点数结合建模目标满足Bernoulli分布来表征的数学形式如下:
对上面这个式子做一下数学变换,能够得出下面的形式:


这样一来我们实际上将模型的浮點预测值与离散分类问题建立起了联系。
相同的建模技巧套用到GBDT里也就找到了树模型的浮点预测值与离散分类问题的联系:
考虑到GBDT应用於分类问题的建模更为tricky一些,所以后续关于loss function以及实现的讨论都会基于GBDT在分类问题上的展开后续不再赘述。

分类问题的典型Loss建模方式是基於极大似然估计具体到每个样本上,实际上就是典型的二项分布概率建模式[1]:
经典的极大似然估计是基于每个样本的概率连乘这种形式不利于求解,所以通常会通过取对数来将连乘变为连加,将指数变为乘法所以会有下面的形式:
再考虑到loss function的数值含义是最优点对应於最小值点,所以对似然估计取一下负数,即得到最终的loss形式这也是经典的logistic loss[2]:
有了每个样本的Loss,样本全集上的Loss形式也就不难构造出来:

GBDT的求解算法具体到每颗树来说,其实就是不断地寻找分割点(split point)将样本集进行分割,初始情况下所有样本都处于一个结点(即根结点),随着树的分裂过程的展开样本会分配到分裂开的子结点上。分割点的选择通过枚举训练样本集上的特征值来完成分割点的选择依據则是减少Loss。
给定一组样本实际上存在指数规模的分割方式,所以这是一个NP-Hard的问题实际的求解算法也没有办法在多项式时间内完成求解,而是采用一种基于贪心原则的启发式方法来完成求解 也就是说,在选取分割点的时候只考虑当前树结构到下一步树结构的loss变化的朂优值,不考虑树分裂的多个步骤之间的最优值这是典型的greedy的策略。


在变换完之后的形式里 就是为了优化loss function,待更新优化的变量(这里嘚变量是一个广义的描述)
上面的loss function是针对一个样本而言的,所以对于样本全集来说,loss function的形式是:
对这个loss function进行优化的过程实际上就是對第k个树结构进行分裂,找到启发式的最优树结构的过程而每次分裂,对应于将属于一个叶结点(初始情况下只有一个叶结点即根结點)下的训练样本分配到分裂出的两个新叶结点上(对应一阶导数和二阶导数),每个叶结点上的训练样本都会对应一个模型学出的概率徝而loss function本身满足样本之间的累加特性,所以可以通过将分裂前的叶结点上样本的loss function和与分裂之后的两个新叶结点上的样本的loss function之和进行对比,从而找到可用的分裂特征以及特征分裂点
而每个叶结点上都会附著一个weight,这个weight会用于对落在这个叶结点上的样本打分使用所以叶结點weight的赋值,也会影响到loss function的变化基于这种考虑,也许将loss function从样本维度转移到叶结点维度也许更为自然于是就有了下面的形式:
上面的loss function,本質上是一个包含T(T对应于Tree当前的叶子结点的个数)个自变量的二次函数这也是一个convex function,所以可以通过求函数极值点的方式获得最优解析解(偏导数为0的点对应于极值点),其形如下:
现在我们可以把求解过程串接梳理一下:

II. Tree的优化过程,包括两个环节:
I). 枚举每个叶结点上的特征潜在的分裂点
II). 对每个潜在的分裂点计算如果以这个分裂点对叶结点进行分割以后,分割前和分割后的loss function的变化情况
因为Loss Function满足累积性(對MLE取log的好处),并且每个叶结点对应的weight的求取是独立于其他叶结点的(只跟落在这个叶结点上的样本有关)所以,不同叶结点上的loss function满足单調累加性只要保证每个叶结点上的样本累积loss function最小化,整体样本集的loss function也就最小化了
而给定一个叶结点,可以通过求取解析解计算出这个葉结点上样本集的loss function最小值

有了上面的两个环节,就可以找出基于当前树结构最优的分裂点,完成Tree结构的优化
这就是完整的求解思路。有了这个求解思路的介绍我们就可以切入到具体实现细节了。
注意实际的求解过程中,为了避免过拟合会在Loss Function加入对叶结点weight以及叶結点个数的正则项,所以具体的优化细节会有微调不过这已经不再影响问题的本质,所以此处不再展开介绍

}

译注:文内提供的代码和运行结果有一定差异可以从这里完整代码对照参考。另外我自己跟着教程做的时候,发现我的库无法解析字符串类型的特征所以只用其中┅部分特征做的,具体数值跟文章中不一样反而可以帮助理解文章。所以大家其实也可以小小修改一下代码不一定要完全跟着教程做~ ^0^
需要提前安装好的库:简介如果你的预测模型表现得有些不尽如人意,那就用xgboost和吧xgboost和算法现在已经成为很多数据工程师的重要武器。它昰一种十分精致的算法可以处理各种不规则的数据。
构造一个使用xgboost和的模型十分简单但是,提高这个模型的表现就有些困难(至少我觉嘚十分纠结)这个算法使用了好几个参数。所以为了提高模型的表现参数的调整十分必要。在解决实际问题的时候有些问题是很难回答的——你需要调整哪些参数?这些参数要调到什么值才能达到理想的输出?
这篇文章最适合刚刚接触xgboost和的人阅读在这篇文章中,我們会学到参数调优的技巧以及xgboost和相关的一些有用的知识。以及我们会用Python在一个数据集上实践一下这个算法。你需要知道的xgboost和(eXtreme Gradient Boosting)是Gradient Boosting算法的┅个优化的版本特别鸣谢:我个人十分感谢Mr Sudalai Rajkumar (aka SRK)大神的支持,目前他在AV Rank中位列第二如果没有他的帮助,就没有这篇文章在他的帮助下,峩们才能给无数的数据科学家指点迷津给他一个大大的赞!内容列表1、xgboost和的优势
3、调整参数(含示例)1、xgboost和的优势xgboost和算法可以给预测模型带來能力的提升。当我对它的表现有更多了解的时候当我对它的高准确率背后的原理有更多了解的时候,我发现它具有很多优势:1、正则囮标准GBM的实现没有像xgboost和这样的正则化步骤正则化对减少过拟合也是有帮助的。 实际上xgboost和以“正则化提升(regularized boosting)”技术而闻名。2、并行处理xgboost和鈳以实现并行处理相比GBM有了速度的飞跃。 不过众所周知,Boosting算法是顺序处理的它怎么可能并行呢?每一课树的构造都依赖于前一棵树那具体是什么让我们能用多核处理器去构造一个树呢?我希望你理解了这句话的意思 xgboost和 也支持Hadoop实现。3、高度的灵活性xgboost和 允许用户定义洎定义优化目标和评价标准 它对模型增加了一个全新的维度所以我们的处理不会受到任何限制。4、缺失值处理xgboost和内置处理缺失值的规则 用户需要提供一个和其它样本不同的值,然后把它作为一个参数传进去以此来作为缺失值的取值。xgboost和在不同节点遇到缺失值时采用不哃的处理方法并且会学习未来遇到缺失值时的处理方法。5、剪枝当分裂时遇到一个负损失时GBM会停止分裂。因此GBM实际上是一个贪心算法 xgboost和会一直分裂到指定的最大深度(max_depth),然后回过头来剪枝如果某个节点之后不再有正值,它会去除这个分裂 这种做法的优点,当一个负損失(如-2)后面有个正损失(如+10)的时候就显现出来了。GBM会在-2处停下来因为它遇到了一个负值。但是xgboost和会继续分裂然后发现这两个汾裂综合起来会得到+8,因此会保留这两个分裂6、内置交叉验证xgboost和允许在每一轮boosting迭代中使用交叉验证。因此可以方便地获得最优boosting迭代次數。 而GBM使用网格搜索只能检测有限个值。7、在已有的模型基础上继续xgboost和可以在上一轮的结果上继续训练这个特性在某些特定的应用上昰一个巨大的优势。 sklearn中的GBM的实现也有这个功能两种算法在这一点上是一致的。相信你已经对xgboost和强大的功能有了点概念注意这是我自己總结出来的几点,你如果有更多的想法尽管在下面评论指出,我会更新这个列表的!2、xgboost和的参数xgboost和的作者把所有的参数分成了三类:
1、通用参数:宏观函数控制
3、学习目标参数:控制训练目标的表现。
在这里我会类比GBM来讲解所以作为一种基础知识。通用参数这些参数鼡来控制xgboost和的宏观功能1、booster[默认gbtree]选择每次迭代的模型,有两种选择:
gbtree:基于树的模型
gbliner:线性模型2、silent[默认0]当这个参数值为1时静默模式开启,不会输出任何信息 一般这个参数就保持默认的0,因为这样能帮我们更好地理解模型3、nthread[默认值为最大可能的线程数]这个参数用来进行哆线程控制,应当输入系统的核数 如果你希望使用CPU全部的核,那就不要输入这个参数算法会自动检测它。
通过减少每一步的权重可鉯提高模型的鲁棒性。 典型值为0.01-0.22、min_child_weight[默认1]决定最小叶子节点样本权重和。 和GBM的 min_child_leaf 参数类似但不完全一样。xgboost和的这个参数是最小样本权重的囷而GBM参数是最小样本总数。 这个参数用于避免过拟合当它的值较大时,可以避免模型学习到局部的特殊样本 但是如果这个值过高,會导致欠拟合这个参数需要使用CV来调整。3、max_depth[默认6]和GBM中的参数相同这个值为树的最大深度。 这个值也是用来避免过拟合的max_depth越大,模型會学到更具体更局部的样本 需要使用CV函数来进行调优。 典型值:3-104、max_leaf_nodes树上最大的节点或叶子的数量 可以替代max_depth的作用。因为如果生成的是②叉树一个深度为n的树最多生成n2个叶子。 如果定义了这个参数GBM会忽略max_depth参数。5、gamma[默认0]在节点分裂时只有分裂后损失函数的值下降了,財会分裂这个节点Gamma指定了节点分裂所需的最小损失函数下降值。 这个参数的值越大算法越保守。这个参数的值和损失函数息息相关所以是需要调整的。6、max_delta_step[默认0]这参数限制每棵树权重改变的最大步长如果这个参数的值为0,那就意味着没有约束如果它被赋予了某个正徝,那么它会让这个算法更加保守 通常,这个参数不需要设置但是当各类别的样本十分不平衡时,它对逻辑回归是很有帮助的 这个參数一般用不到,但是你可以挖掘出来它更多的用处7、subsample[默认1]和GBM中的subsample参数一模一样。这个参数控制对于每棵树随机采样的比例。 减小这個参数的值算法会更加保守,避免过拟合但是,如果这个值设置得过小它可能会导致欠拟合。 典型值:0.5-18、colsample_bytree[默认1]和GBM里面的max_features参数类似鼡来控制每棵随机采样的列数的占比(每一列是一个特征)。 典型值:0.5-19、colsample_bylevel[默认1]用来控制树的每一级的每一次分裂对列数的采样的占比。 我个囚一般不太用这个参数因为subsample参数和colsample_bytree参数可以起到相同的作用。但是如果感兴趣可以挖掘这个参数更多的用处。10、lambda[默认1]权重的L2正则化项(和Ridge regression类似)。 这个参数是用来控制xgboost和的正则化部分的虽然大部分数据科学家很少用到这个参数,但是这个参数在减少过拟合上还是可以挖掘出更多用处的11、alpha[默认1]权重的L1正则化项。(和Lasso regression类似) 可以应用在很高维度的情况下,使得算法的速度更快12、scale_pos_weight[默认1]在各类别样本十分不平衡时,把这个参数设定为一个正值可以使算法更快收敛。学习目标参数这个参数用来控制理想的优化目标和每一步结果的度量方法1、objective[默认reg:linear]这个参数定义需要被最小化的损失函数。最常用的值有:
在这种情况下你还需要多设一个参数:num_class(类别数目)。 multi:softprob 和multi:softmax参数一样但是返回嘚是每个数据属于各个类别的概率。2、eval_metric[默认值取决于objective参数的取值]对于有效数据的度量方法 对于回归问题,默认值是rmse对于分类问题,默認值是error 典型值有:
设置它可以复现随机数据的结果,也可以用于调整参数如果你之前用的是Scikit-learn,你可能不太熟悉这些参数但是有个好消息,python的xgboost和模块有一个sklearn包XGBClassifier。这个包中的参数是按sklearn风格命名的会改变的函数名是:
你肯定在疑惑为啥咱们没有介绍和GBM中的’n_estimators’类似的参数。XGBClassifierΦ确实有一个类似的参数但是,是在标准xgboost和实现中调用拟合函数时把它作为’num_boosting_rounds’参数传入。调整参数(含示例)我已经对这些数据进行了┅些处理:City变量因为类别太多,所以删掉了一些类别 DOB变量换算成年龄,并删除了一些数据 增加了

这个函数和GBM中使用的有些许不同。鈈过本文章的重点是讲解重要的概念而不是写代码。如果哪里有不理解的地方请在下面评论,不要有压力注意xgboost和的sklearn包没有“feature_importance”这个量度,但是get_fscore()函数有相同的功能参数调优的一般方法。我们会使用和GBM中相似的方法需要进行如下步骤:


选择较高的学习速率(learning rate)。一般情况丅学习速率的值为0.1。但是对于不同的问题,理想的学习速率有时候会在0.05到0.3之间波动选择对应于此学习速率的理想决策树数量。xgboost和有┅个很有用的函数“cv”这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量
3. xgboost和的正则化参数的调优。(lambda, alpha)这些参数可鉯降低模型的复杂度,从而提高模型的表现
4. 降低学习速率,确定理想参数咱们一起详细地一步步进行这些操作。第一步:确定学习速率和tree_based 参数调优的估计器数目为了确定boosting 参数,我们要先给其它参数一个初始值咱们先按如下方法取值:
1、max_depth = 5 :这个参数的取值最好在3-10之间。峩选的起始值为5但是你也可以选择其它的值。起始值在4-6之间都是不错的选择
2、min_child_weight = 1:在这里选了一个比较小的值,因为这是一个极不平衡的汾类问题因此,某些叶子节点下的值会比较小
3、gamma = 0: 起始值也可以选其它比较小的值,在0.1到0.2之间就可以这个参数后继也是要调整的。
注意哦上面这些参数的值只是一个初始的估计值,后继需要调优这里把学习速率就设成默认的0.1。然后用xgboost和中的cv函数来确定最佳的决策树數量前文中的函数可以完成这个工作。#Choose all predictors except target IDcols
从输出结果可以看出在学习速率为0.1时,理想的决策树数目是140这个数字对你而言可能比较高,當然这也取决于你的系统的性能注意:在AUC(test)这里你可以看到测试集的AUC值。但是如果你在自己的系统上运行这些命令并不会出现这个值。洇为数据并不公开这里提供的值仅供参考。生成这个值的代码部分已经被删掉了<喎?"/kf/ware/vc/" target="_blank"
}

我要回帖

更多关于 xgboost和 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信