精华内容
下载资源
问答
  • LGB算法梳理-Task4

    千次阅读 2019-08-15 20:46:57
    高级算法梳理-Task4 LightGBM梳理 1、LightGBM LightGBM是个快速、分布式的、高性能的基于决策树算法的梯度提升框架。可用于排序、分类、回归以及很多其他的机器学习任务中。 因为他是基于决策树算法的,它采用最优...

    高级算法梳理-Task4

    LightGBM梳理

    1、LightGBM

    LightGBM是个快速、分布式的、高性能的基于决策树算法的梯度提升框架。可用于排序、分类、回归以及很多其他的机器学习任务中。

    因为他是基于决策树算法的,它采用最优的leaf-wise策略分裂叶子节点,然而其它的提升算法分裂树一般采用的是level-wise。因此,在LightGBM算法中,当增长到相同的叶子节点,leaf-wise算法比level-wise算法减少更多的loss,因此导致更高的精度。与此同时,它的速度也让人感到震惊,这就是该算法名字Light的原因。

    2、LightGBM的起源

    LGB是一种GBDT的工程实现。常见的机器学习算法,例如神经网络等算法,都可以以mini-batch的方式训练,训练数据的大小不会受到内存限制。而GBDT在每一次迭代的时候,都需要遍历整个训练数据多次,如果把整个训练数据装进内存会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。尤其面对工业级海量的数据,普通的GBDT算法是不能满足其需求的。

    LightGBM提出的主要原因就是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地用于工业实践。

    3、Histogram VS pre-sorted(如何寻找最优切分点)

    Pre-sorted:

    之前的GBDT工具都是基于预排序(pre-sorted)的方法(如 xgboost)。这种构造决策树的算法基本思想是:

    首先,对所有特征都按照特征的数值进行预排序。

    其次,在遍历分割点的时候用O(#data)的代价找到一个特征上的最好分割点。

    最后,找到一个特征的分割点后,将数据分裂成左右子节点。

    优点:能精确地找到分割点;缺点:空间消耗大,时间开销也大,对cache优化不友好。

    Histogram:

    直方图算法的基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中积累统计量,当遍历一次数据后,直方图累计了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

    优点:内存消耗的降低,可以降到原来的1/8;计算代价的降低,预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图只需要计算k次(k可以认为是常数),时间复杂度从O(#data ∗ * #feature)优化到O(k*#features)。

    Histogram(直方图)做差加速,一个叶子的直方图可以由它的父亲节点与它的兄弟的直方图做差得到。这样速度可以提升一倍。

    4、leaf-wise VS level-wise(决策树生长策略)

    level-wise

    大多数GBDT工具使用按层生长(level-wise)的决策树生长策略。Level-wise过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

    [外链图片转存失败(img-TxTlHU6s-1565873202939)(D:\workspace\Markdown文档\高级算法梳理\高级算法梳理-Task4.assets\1565857570169.png)]

    leaf-wise

    Leaf-wise是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。

    [外链图片转存失败(img-Ngh2Ayjf-1565873202940)(D:\workspace\Markdown文档\高级算法梳理\高级算法梳理-Task4.assets\1565857775793.png)]

    5、特征并行和数据并行

    **特征并行:**适用于数据少,但是特征比较多的情况。LightGBM的不同worker在不同的特征子集合上分别寻找最优的分割点,然后同步找到全局最佳切分点。

    [外链图片转存失败(img-zZLra9wE-1565873202941)(D:\workspace\Markdown文档\高级算法梳理\高级算法梳理-Task4.assets\1565867014995.png)]

    **数据并行:**适用于数据量大,特征比较少的情况。数据并行对数据进行水平切分,每个worker上的数据先建立起局部直方图,然后合并成全局的直方图,之后找到最优的分割点。

    [外链图片转存失败(img-WrKQHV2p-1565873202941)(D:\workspace\Markdown文档\高级算法梳理\高级算法梳理-Task4.assets\1565867038392.png)]

    **投票并行:**适用于数据量大,特征也大的情况。投票并行主要是对数据并行的一个优化。每个worker首先会找到它们数据中最优的一些特征,然后进行全局的投票,根据投票的结果,选择top的特征的直方图进行合并,再寻求全局的最优分割点。

    [外链图片转存失败(img-79lpwbQm-1565873202942)(D:\workspace\Markdown文档\高级算法梳理\高级算法梳理-Task4.assets\1565867075175.png)]

    6、支持类别特征

    大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征转化到多维的0/1特征,降低了空间和时间的效率。而类别特征的使用时在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树上增加了类别特征的 决策规则。速度快乐,精度不变。LightGBM是第一个支持类别特征的GBDT工具。(有时候对类别特征展开精度还是会高一点)

    7、应用场景

    • 回归,目标函数为L2 loss
    • 二分类,目标函数为logloss(对数损失)
    • 多分类
    • lambdarank,目标函数为基于NDCG的lambdarank

    8、sklearn参数

    此链接

    9、LightGBM与XGBoost的不同点

    (1)由于决策树在每一次选择节点特征的过程中,要遍历所有的属性的所有取值并选择一个较好的。XGB使用的是近似算法,先对特征值进行排序Pre-sort,然后根据二阶梯度进行分桶,能够更精确的找到数据分割点;但是复杂度较高。LightGBM使用的是histgram算法,这种只需要将数据分割成不同的段即可,不需要进行预先的排序。占用的内存更低,数据分割的复杂度更低。

    (2)决策树生长策略,XGB用的是Level-wise的树生长策略,LGB采用的是Leaf-wise的生长策略。

    (3)并行策略对比,XGB的并行主要是特征并行,而LGB的并行策略有特征并行,数据并行和投票并行。

    展开全文
  • xgb gbdt lgb 算法的比较

    千次阅读 2018-09-24 00:32:36
    本文主要简要的比较了常用的boosting算法的一些区别,从AdaBoost到LightGBM,包括AdaBoost,GBDT,XGBoost,LightGBM四个模型的简单介绍,一步一步从原理到优化对比。 AdaBoost原理 原始的AdaBoost算法是在算法开始的...

    本文主要简要的比较了常用的boosting算法的一些区别,从AdaBoost到LightGBM,包括AdaBoost,GBDT,XGBoost,LightGBM四个模型的简单介绍,一步一步从原理到优化对比。 AdaBoost原理 原始的AdaBoost算法是在算法开始的时候,为每一个样本赋上一个权重值,初始的时候,大家都是一样重要的。在每一步训练中得到的模型,会使得数据点的估计有对有错,我们就在每一步结束后,增加分错的点的权重,减少分对的点的权重,这样使得某些点如果老是被分错,那么就会被“重点关注”,也就被赋上一个很高的权重。然后等进行了N次迭代(由用户指定),将会得到N个简单的分类器(basic learner),然后我们将它们组合起来(比如说可以对它们进行加权、或者让它们进行投票等),得到一个最终的模型。 关键字:样本的权重分布 GBDT概述 GBDT(Gradient Boosting Decison Tree)中的树都是回归树,GBDT用来做回归预测,调整后也可以用于分类(设定阈值,大于阈值为正例,反之为负例),可以发现多种有区分性的特征以及特征组合。GBDT是把所有树的结论累加起来做最终结论的,GBDT的核心就在于,每一棵树学的是之前所有树结论和的残差(负梯度),这个残差就是一个加预测值后能得真实值的累加量。比如A的真实年龄是18岁,但第一棵树的预测年龄是12岁,差了6岁,即残差为6岁。那么在第二棵树里我们把A的年龄设为6岁去学习,如果第二棵树真的能把A分到6岁的叶子节点,那累加两棵树的结论就是A的真实年龄;如果第二棵树的结论是5岁,则A仍然存在1岁的残差,第三棵树里A的年龄就变成1岁,继续学。 Boosting的最大好处在于,每一步的残差计算其实变相地增大了分错instance的权重,而已经分对的instance则都趋向于0。这样后面的树就能越来越专注那些前面被分错的instance。 Gradient Boost与AdaBoost的区别 Gradient Boost每一次的计算是为了减少上一次的残差(residual),而为了消除残差,我们可以在残差减少的梯度(Gradient)方向上建立一个新的模型。所以说,在Gradient Boost中,每个新的模型的建立是为了使得之前模型的残差往梯度方向减少。Shrinkage(缩减)的思想认为,每次走一小步逐渐逼近结果的效果,要比每次迈一大步很快逼近结果的方式更容易避免过拟合。即它不完全信任每一个棵残差树,它认为每棵树只学到了真理的一小部分,累加的时候只累加一小部分,通过多学几棵树弥补不足。本质上,Shrinkage为每棵树设置了一个weight,累加时要乘以这个weight,但和Gradient并没有关系。 Adaboost是另一种boost方法,它按分类对错,分配不同的weight,计算cost function时使用这些weight,从而让“错分的样本权重越来越大,使它们更被重视” Gradient Boost优缺点 优点: 它的非线性变换比较多,表达能力强,而且不需要做复杂的特征工程和特征变换。 缺点:Boost是一个串行过程,不好并行化,而且计算复杂度高,同时不太适合高维稀疏特征。 XGBoost XGBoost能自动利用cpu的多线程,而且适当改进了gradient boosting,加了剪枝,控制了模型的复杂程度 传统GBDT以CART作为基分类器,特指梯度提升决策树算法,而XGBoost还支持线性分类器(gblinear),这个时候XGBoost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。 传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。 xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。 xgboost中树节点分裂时所采用的公式: Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(传统GBDT的实现也有学习速率) 列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。 对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。 xgboost工具支持并行。注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。(特征粒度上的并行,block结构,预排序) 这个公式形式上跟ID3算法、CART算法是一致的,都是用分裂后的某种值减去分裂前的某种值,从而得到增益。为了限制树的生长,我们可以加入阈值,当增益大于阈值时才让节点分裂,上式中的gamma即阈值,它是正则项里叶子节点数T的系数,所以xgboost在优化目标函数的同时相当于做了预剪枝。另外,上式中还有一个系数lambda,是正则项里leaf score的L2模平方的系数,对leaf score做了平滑,也起到了防止过拟合的作用,这个是传统GBDT里不具备的特性。 XGBoost实现层面 内置交叉验证方法 能够输出特征重要性文件辅助特征筛选 XGBoost优势小结: a.公式推导里用到了二阶导数信息,而普通的GBDT只用到一阶 b.显式地将树模型的复杂度作为正则项加在优化目标,penalty function Omega主要是对树的叶子数和叶子分数做惩罚,这点确保了树的简单性。 c.借鉴了Random Forest的思想,允许使用列抽样(column(feature) sampling)来防止过拟合,sklearn里的gbm好像也有类似实现。 d.Pre-sorted 算法,样本数据事先排好序并以block的形式存储,利于并行计算 e.实现了一种分裂节点寻找的近似算法,用于加速和减小内存消耗,节点分裂算法能自动利用特征的稀疏性。 f.支持分布式计算可以运行在MPI,YARN上,得益于底层支持容错的分布式通信框架rabit。 LightGBM lightGBM:基于决策树算法的分布式梯度提升框架。 大多数机器学习工具都无法直接支持类别特征作为输入,一般需要转换成多维0/1特征,带来计算和内存上的额外消耗。LightGBM增加了针对于类别特征的决策规则,这在决策树上也很好实现。主要的思想是,在对类别特征计算分割增益的时候,不是按照数值特征那样由一个阈值进行切分,而是直接把其中一个类别当成一类,其他的类别当成另一类。这实际上与0/1展开的效果是一样的。 GBDT 虽然是个强力的模型,但却有着一个致命的缺陷,不能用类似 mini batch 的方式来训练,需要对数据进行无数次的遍历。如果想要速度,就需要把数据都预加载在内存中,但这样数据就会受限于内存的大小;如果想要训练更多的数据,就要使用外存版本的决策树算法。虽然外存算法也有较多优化,SSD 也在普及,但在频繁的 IO 下,速度还是比较慢的。 为了能让 GBDT 高效地用上更多的数据,我们把思路转向了分布式 GBDT, 然后就有了 LightGBM。 设计的思路主要是两点,1. 单个机器在不牺牲速度的情况下,尽可能多地用上更多的数据;2.多机并行的时候,通信的代价尽可能地低,并且在计算上可以做到线性加速。 基于这两个需求,LightGBM 选择了基于 histogram 的决策树算法。相比于另一个主流的算法 pre-sorted(如 xgboost 中的 exact 算法),histogram 在内存消耗和计算代价上都有不少优势。 Pre-sorted 算法需要的内存约是训练数据的两倍(2 * #data * #features* 4Bytes),它需要用32位浮点来保存 feature value,并且对每一列特征,都需要一个额外的排好序的索引,这也需要32位的存储空间。对于 histogram 算法,则只需要(#data* #features * 1Bytes)的内存消耗,仅为 pre-sorted算法的1/8。因为 histogram 算法仅需要存储 feature bin value (离散化后的数值),不需要原始的 feature value,也不用排序,而 bin value 用 uint8_t (256 bins) 的类型一般也就足够了。 在计算上的优势则主要体现在“数据分割”。决策树算法有两个主要操作组成,一个是“寻找分割点”,另一个是“数据分割”。从算法时间复杂度来看,Histogram 算法和 pre-sorted 算法在“寻找分割点”的代价是一样的,都是O(#feature*#data)。而在“数据分割”时,pre-sorted 算法需要O(#feature*#data),而 histogram 算法是O(#data)。因为 pre-sorted 算法的每一列特征的顺序都不一样,分割的时候需要对每个特征单独进行一次分割。Histogram算法不需要排序,所有特征共享同一个索引表,分割的时候仅需对这个索引表操作一次就可以。(更新: 这一点不完全正确,pre-sorted 与 level-wise 结合的时候,其实可以共用一个索引表(row_idx_to_tree_node_idx)。然后在寻找分割点的时候,同时操作同一层的节点,省去分割的步骤。但这样做的问题是会有非常多随机访问,有很大的chche miss,速度依然很慢。)。 最后,在数据并行的时候,用 histgoram 可以大幅降低通信代价。用 pre-sorted 算法的话,通信代价是非常大的(几乎是没办法用的)。所以 xgoobst 在并行的时候也使用 histogram 进行通信。 当然, histogram 算法也有缺点,它不能找到很精确的分割点,训练误差没有 pre-sorted 好。但从实验结果来看, histogram 算法在测试集的误差和 pre-sorted 算法差异并不是很大,甚至有时候效果更好。实际上可能决策树对于分割点的精确程度并不太敏感,而且较“粗”的分割点也自带正则化的效果。 在 histogram 算法之上, LightGBM 进行进一步的优化。首先它抛弃了大多数 GBDT 工具使用的按层生长(level-wise) 的决策树生长策略,而使用了带有深度限制的按叶子生长 (leaf-wise) 算法。 level-wise 过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,不容易过拟合。但实际上level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销。因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。leaf-wise则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大(一般也是数据量最大)的一个叶子,然后分裂,如此循环。因此同 level-wise 相比,在分裂次数相同的情况下,leaf-wise 可以降低更多的误差,得到更好的精度。leaf-wise 的缺点是可能会长出比较深的决策树,产生过拟合。因此 LightGBM 在leaf-wise 之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。 另一个比较巧妙的优化是 histogram 做差加速。一个容易观察到的现象:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的 k 个桶。利用这个方法,LightGBM 可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。 lightGBM与XGBoost的区别: 切分算法(切分点的选取) 占用的内存更低,只保存特征离散化后的值,而这个值一般用8位整型存储就足够了,内存消耗可以降低为原来的1/8。 降低了计算的代价:预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算k次(k可以认为是常数),时间复杂度从O(#data#feature)优化到O(k#features)。(相当于LightGBM牺牲了一部分切分的精确性来提高切分的效率,实际应用中效果还不错)空间消耗大,需要保存数据的特征值以及特征排序的结果(比如排序后的索引,为了后续快速计算分割点),需要消耗两倍于训练数据的内存时间上也有较大开销,遍历每个分割点时都需要进行分裂增益的计算,消耗代价大对cache优化不友好,在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。 XGBoost使用的是pre-sorted算法(对所有特征都按照特征的数值进行预排序,基本思想是对所有特征都按照特征的数值进行预排序;然后在遍历分割点的时候用O(#data)的代价找到一个特征上的最好分割点最后,找到一个特征的分割点后,将数据分裂成左右子节点。优点是能够更精确的找到数据分隔点;但这种做法有以下缺点 LightGBM使用的是histogram算法,基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点; 优点在于决策树生长策略上: XGBoost采用的是带深度限制的level-wise生长策略,Level-wise过一次数据可以能够同时分裂同一层的叶子,容易进行多线程优化,不容易过拟合;但不加区分的对待同一层的叶子,带来了很多没必要的开销(因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂) LightGBM采用leaf-wise生长策略,每次从当前所有叶子中找到分裂增益最大(一般也是数据量最大)的一个叶子,然后分裂,如此循环;但会生长出比较深的决策树,产生过拟合(因此 LightGBM 在leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合)。 histogram 做差加速。一个容易观察到的现象:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的k个桶。利用这个方法,LightGBM可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。 直接支持类别特征:LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。 分布式训练方法上(并行优化) 在特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信; 在数据并行中使用分散规约(Reduce scatter)把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。基于投票的数据并行(Parallel Voting)则进一步优化数据并行中的通信代价,使通信代价变成常数级别。 特征并行的主要思想是在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。 数据并行则是让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。 原始LightGBM针对这两种并行方法都做了优化,Cache命中率优化 基于直方图的稀疏特征优化 DART(Dropout + GBDT) GOSS(Gradient-based One-Side Sampling):一种新的Bagging(row subsample)方法,前若干轮(1.0f / gbdtconfig->learning_rate)不Bagging;之后Bagging时, 采样一定比例g(梯度)大的样本 LightGBM优点小结(相较于XGBoost) 速度更快 内存消耗更低 --------------------- 本文来自 akenseren 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/akenseren/article/details/80766112?utm_source=copy

    展开全文
  • 搜狐算法大赛(实体撤销+情感预测)的基准线〜 没有用深度模型,用的传统的lgb当成分类做的,这里的代码只用了一个非常基本的tfidf特征,模型构造好了,大家可以自己遵循自己的想法体现特征。 想先做实体的部分,就...
  • 本文主要讲解:使用微软自动化机器学习框架Auto ML-NNI对lgb的超参进行优化 主要思路: 设置需要优化的参数,用json格式保存为一个文件 设置yml文件,用于调参算法和文件的配置 写python文件,使用nni获取参数并...

    1、摘要

    本文主要讲解:使用微软自动化机器学习框架Auto ML-NNI对lgb的超参进行优化
    主要思路:

    1. 设置需要优化的参数,用json格式保存为一个文件
    2. 设置yml文件,用于调参算法和文件的配置
    3. 写python文件,使用nni获取参数并调优参数
    4. 使用 nnictl create 命令运行yml文件实现调优
    5. 将调优后的网络参数放入默认参数中,运行python文件,实现调参优化并训练好模型

    2、数据介绍

    数据请到GitHub自行下载,参考文末的学习链接

    此数据为回归训练数据,第一列为标签列
    在这里插入图片描述
    此数据为回归测试数据,第一列为标签列
    在这里插入图片描述

    3、相关技术

    NNI (Neural Network Intelligence) 是一个轻量但强大的工具包,帮助用户自动的进行特征工程,神经网络架构搜索,超参调优以及模型压缩。

    NNI 管理自动机器学习 (AutoML) 的 Experiment,调度运行由调优算法生成的 Trial 任务来找到最好的神经网络架构和/或超参。

    GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛,通常被用于多分类、点击率预测、搜索排序等任务;在各种数据挖掘竞赛中也是致命武器,据统计Kaggle上的比赛有一半以上的冠军方案都是基于GBDT。而LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以快速处理海量数据等优点。
    ————————————————
    原文链接:https://blog.csdn.net/weixin_44023658/article/details/106732861

    4、完整代码和步骤

    首先请安装nni和lgb

    pip install nni lightgbm

    json文件如下:

    {
        "num_leaves":{"_type":"randint","_value":[20, 31]},
        "learning_rate":{"_type":"choice","_value":[0.01, 0.05, 0.1, 0.2]},
        "bagging_fraction":{"_type":"uniform","_value":[0.7, 1.0]},
        "feature_fraction":{"_type":"uniform","_value":[0.7, 1.0]},
        "bagging_freq":{"_type":"choice","_value":[1, 2, 4, 8, 10]}
    }
    

    yml文件如下

    authorName: default
    experimentName: example_auto-gbdt
    trialConcurrency: 1
    maxExecDuration: 10h
    maxTrialNum: 20
    #choice: local, remote, pai
    trainingServicePlatform: local
    searchSpacePath: search_space.json
    #choice: true, false
    useAnnotation: false
    tuner:
      #choice: TPE, Random, Anneal, Evolution, BatchTuner, MetisTuner, GPTuner
      #SMAC (SMAC should be installed through nnictl)
      builtinTunerName: TPE
      classArgs:
        #choice: maximize, minimize
        optimize_mode: minimize
    trial:
      command: python main.py
      codeDir: .
      gpuNum: 0
    

    代码输出如下:

    You can set force_col_wise=true to remove the overhead.
    [1] valid_0’s l2: 0.249547 valid_0’s auc: 0.717097
    Training until validation scores don’t improve for 5 rounds
    [2] valid_0’s l2: 0.248911 valid_0’s auc: 0.748828
    [3] valid_0’s l2: 0.24806 valid_0’s auc: 0.755783
    [4] valid_0’s l2: 0.247232 valid_0’s auc: 0.767229
    [5] valid_0’s l2: 0.246511 valid_0’s auc: 0.767581
    [6] valid_0’s l2: 0.245987 valid_0’s auc: 0.76611
    [7] valid_0’s l2: 0.245194 valid_0’s auc: 0.767887
    [8] valid_0’s l2: 0.244439 valid_0’s auc: 0.769296
    [9] valid_0’s l2: 0.243661 valid_0’s auc: 0.770051
    [10] valid_0’s l2: 0.242782 valid_0’s auc: 0.772751
    [11] valid_0’s l2: 0.242057 valid_0’s auc: 0.772154
    [12] valid_0’s l2: 0.241234 valid_0’s auc: 0.773714
    [13] valid_0’s l2: 0.240547 valid_0’s auc: 0.774013
    [14] valid_0’s l2: 0.239834 valid_0’s auc: 0.773551
    [15] valid_0’s auc: 0.775091 valid_0’s l2: 0.194493
    Start predicting…
    The rmse of prediction is: 0.4195613807319431
    [2021-06-20 12:27:06] INFO (nni/MainThread) Final result: 0.4195613807319431

    主运行程序入口

    '''
    This project is for automatically tuning parameters for GBDT.
    
    Trial(尝试) 是将一组参数组合(例如,超参)在模型上独立的一次尝试。
    定义 NNI 的 Trial,需要首先定义参数组(例如,搜索空间),并更新模型代码。
    nnictl create --config config.yml -p 8888
    '''
    import logging
    
    import lightgbm as lgb
    import nni
    import pandas as pd
    from sklearn.metrics import mean_squared_error
    
    
    LOG = logging.getLogger('auto-gbdt')
    
    # specify your configurations as a dict
    def get_default_parameters():
        # params = {
        #     'boosting_type': 'gbdt',
        #     'objective': 'regression',
        #     'metric': {'l2', 'auc'},
        #     'num_leaves': 31,
        #     'learning_rate': 0.05,
        #     'feature_fraction': 0.9,
        #     'bagging_fraction': 0.8,
        #     'bagging_freq': 5,
        #     'verbose': 0
        # }
        # The rmse of prediction is: 0.450357
        params = {
            'boosting_type': 'gbdt',
            'objective': 'regression',
            'metric': {'l2', 'auc'},
            'num_leaves': 28,
            'learning_rate': 0.2,
            'feature_fraction': 0.930,
            'bagging_fraction': 0.7656,
            'bagging_freq': 4,
            'verbose': 0
        }
        # 调参后的  The rmse of prediction is: 0.419561
        return params
    
    
    def load_data(train_path='./data/regression.train', test_path='./data/regression.test'):
        '''
        Load or create dataset
        '''
        print('Load data...')
        df_train = pd.read_csv(train_path, header=None, sep='\t')
        df_test = pd.read_csv(test_path, header=None, sep='\t')
        num = len(df_train)
        split_num = int(0.9 * num)
    
        y_train = df_train[0].values
        y_test = df_test[0].values
        y_eval = y_train[split_num:]
        y_train = y_train[:split_num]
    
        X_train = df_train.drop(0, axis=1).values
        X_test = df_test.drop(0, axis=1).values
        X_eval = X_train[split_num:, :]
        X_train = X_train[:split_num, :]
    
        # create dataset for lightgbm
        lgb_train = lgb.Dataset(X_train, y_train)
        lgb_eval = lgb.Dataset(X_eval, y_eval, reference=lgb_train)
    
        return lgb_train, lgb_eval, X_test, y_test
    
    def run(lgb_train, lgb_eval, params, X_test, y_test):
        print('Start training...')
    
        params['num_leaves'] = int(params['num_leaves'])
    
        # train
        gbm = lgb.train(params,
                        lgb_train,
                        num_boost_round=20,
                        valid_sets=lgb_eval,
                        early_stopping_rounds=5)
    
        print('Start predicting...')
    
        # predict
        y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
    
        # eval
        rmse = mean_squared_error(y_test, y_pred) ** 0.5
        print('The rmse of prediction is:', rmse)
    
        nni.report_final_result(rmse)
    
    if __name__ == '__main__':
        lgb_train, lgb_eval, X_test, y_test = load_data()
    
        try:
            # get parameters from tuner
            RECEIVED_PARAMS = nni.get_next_parameter()
            LOG.debug(RECEIVED_PARAMS)
            PARAMS = get_default_parameters()
            PARAMS.update(RECEIVED_PARAMS)
            LOG.debug(PARAMS)
    
            # train
            run(lgb_train, lgb_eval, PARAMS, X_test, y_test)
        except Exception as exception:
            LOG.exception(exception)
            raise
    

    运行方式:

    nnictl create --config config.yml -p 8888 --debug

    浏览器查看效果
    在这里插入图片描述
    调参后rmse下降了0.03个点

    5、学习链接

    NNI官方文档

    微软新工具 NNI 使用指南之Mnist-annotation例子分析篇

    github-nni

    微软AutoML平台NNI,ENAS基于参数共享的高效神经网络结构搜索

    数据地址

    展开全文
  • 机器学习-lgb

    千次阅读 2019-07-21 14:21:40
    1 特征工程:最大限度地数据中提取特征以供模型和算法使用,包括特征处理,特征选择,降维。 2 lgb 2.1 基本介绍: 一个梯度boosting框架,使用决策树,分布式,训练效率,准确率高,内存低,处理数据地规模大。 ...

    https://www.nowcoder.com/discuss/205955

    1 特征工程:最大限度地数据中提取特征以供模型和算法使用,包括特征处理,特征选择,降维。

    2 lgb

    2.1 基本介绍: 一个梯度boosting框架,使用决策树,分布式,训练效率,准确率高,内存低,处理数据地规模大。

    2.2 xgb的缺点:每次迭代都要遍历数据很多次:预排序法: 要保存数据的特征值以及特征排序的结果;遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的时间大;在预排序后,特征对梯度的访问是一种随机访问,特征的访问顺序也不一样,对cache 优化很不友好。

    2.3 LIghtGBM 的优化

    2.3.1 基于Histogram 的决策树算法

    基本做法是将连续的浮点特征值离散化为k个整数,同时构造一个宽度为k的直方图,在遍历数据的时候根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

    优点:降低内存消耗,直方图不需要额外存储预排序的结果,只需要保存特征离散化后的值,而且只用8位整数型存储,内存消耗可以降低为原来的1/8,然后在计算上的代价大幅度降低。

    2.3.2 带深度限制的·leaf-wise 的叶子生长策略

    level-wise 过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型的复杂度,不容易过拟合,但实际上level-wise 是低效的,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

    leaf-wise 则是一种更为高效的策略,每次从所有叶子中,找到分裂增益最大的一个叶子,然后分裂。如此循环,因此同level -wise 相比,分裂次数相同的情况下,leaf-wise 可以降低更多的误差,得到更好的精度,缺点是可能会长出较深的决策树,产生过拟合,因此要增加一个最大深度的限制。

    2.3.3 直方图做差加速

    一个叶子的直方图可以由它的父亲节点的直方图与它兄弟节点的直方图做差得到,速度可以提升一倍

    2.3.4 直接支持类别特征

    0/1 展开降低了空间和时间的效率,

    可以直接输入类别特征,不需要额外的0/1 展开,可以在决策树算法上增加了类别特征的决策规则。lgb 是第一个直接支持类别特征的GBDT 工具。

    2.3.5 cache 命中率优化

    2.3.6 多线程优化

    2.3.7 特征并行和数据并行:

    2.4 LightGBM和XGBoost有什么区别?他们的loss一样么? 算法层面有什么区别?

    lgb: 基于histogram 的决策树算法,leaf-wise 的叶子生长策略,cache 命中优化率,直接支持类别特征,

    xgb:预排序,level-wise 的阶级生长策略,特征对梯度的访问是一种随机访问

    2.5 LightGBM有哪些实现,各有什么区别?

    gdbt: :梯度提升决策树,串行速度慢,容易过拟合,

    rf: 随机森林,并行速度快,

    dart:训练较慢;goss:容易过拟合。

    参考:https://zhuanlan.zhihu.com/p/25308051

    https://www.jianshu.com/p/104c3e0622d3

    https://www.lizenghai.com/archives/21833.html

    3 lightgbm和xgboost区别。

    GBDT : 梯度提升数的基础上发展而来,在构建树的每一步的过程都是去拟合上一步模型在训练集上的残差,恰好是loss的梯度。

    特点:每次迭代获得的决策树模型都要乘以一个缩减系数,从而降低每棵树的作用,提升可学习空间,每次迭代拟合的是一阶梯度。

    Xgboost 是GDBT的变种,xgboost 是对目标函数做二阶泰勒展开,从而求出下步要拟合的树的叶子节点的权重,再根据loss 求出每一次分裂节点的损失减小的大小,从而根据分裂损失选择合适的属性进行分裂。

    先遍历所有节点的所有属性进行分裂,假设选择了这个a 属性的一个取值作为分裂节点,根据泰勒展开求得的公式可计算该树结构各个叶子节点的权重,从而计算损失减小的程度,从而综合各个属性选择使得损失减小最大的那个特征作为当前节点的分裂属性,依次类推,直到满足终止条件。

    特点: 1 除了类似GBDT 的缩减系数外,xgboost 对每棵树的叶子节点个数和权重都做了惩随机罚,避免过拟合

    2 类似随机森林,XGBoost 在构建树的过程中,对每棵随机选择一些属性作为分裂属性。

    3 分裂算法:(1) 精确的分裂:把每个属性的每个取值都当作一次阈值进行遍历,采用的决策树是CART(2)近似分裂算法: 

    对每个属性的取值进行分裂,按照各个桶之间的值划分阈值,xgboost 提出了一个特殊的分桶策略,一般分桶策略是每个样本的权重都是相同的,但是xgboost 使每个样本的权重为损失函数在该样本点的二阶导。

    4 xgboost 添加了对稀疏数据的支持,在计算分裂收益的时候只利用没有missing 值的那些样本,但是在推理的时候,也就是在确定了树的结构,需要将样本映射到叶子节点的时候,需要对含有缺失值的样本进行划分,xgboost 分别假设该样本属于左子树和右子树,比较两者分裂增益,选择增益较大的那一边作为该样本的分裂方向。

    5 xgboost 实现了并行化,不是类似rf 那样树和树之间的并行化,xgboost 和boosting 方法一样,在树的粒度上是串行的,但是在构建树的过程中,也就是在分裂节点的时候支持并行化,比如同时计算多个属性的多个取值作为分裂特征及其值,然后选择收益最大的特征及其取值对节点分裂。

    6 xgboost 在实现时,需要将所有数据导入内存,做一次pre-sort,这样在选择分裂节点时比较迅速,

    缺点: level-wise 建树方式对当前层的所有叶子节点一视同仁,有些叶子节点分裂收益非常小,对结果没影响,但是还是要分裂,加重了计算代价。

    预排序方法空间消耗比较大,不仅要保存特征值,也要保存特征的排序索引,同时时间消耗也大,在遍历每个分裂点时都要计算分裂增益。

    LightGBM:

    1 采用leaf-wise 策略:在当前所有叶子节点中选择分裂收益最大的节点进行分裂,如此递归进行,容易过拟合,容易陷入比较高的深度中,需要对最大深度做限制,从而避免过拟合。

    2 lgb 使用了基于histogram 的决策树算法,这一点不同与xgboost 中的exact 算法,histogram 算法在内存和计算代价上都有不小优势,内存优势: 直方图算法的内存消耗为:data *feature*1bytes ,(对特征分桶后只需要保存特征离散化后的值),xgboost 的exact 算法的内存消耗为:2*data*feature*4bytes,因为xgboost 既要保存原始的feature 的值,也要保存这个值的顺序索引,这些值需要32位的浮点数来保存。计算优势: 预排序算法在选择好分裂特征计算分裂收益时需要遍历所有样本的特征值,时间为data ,而直方图算法只需要遍历桶就行了,时间为bin

    3 直方图做差加速

    一个叶子节点的直方图可以通过父节点的直方图减去兄弟节点的直方图得到,从而加速计算

    4 lgb 支持直接输入categorical 的feature

    在对离散特征分裂时,每个取值都当作一个桶,分裂时的增益算的是是否属于某个category的gain ,类似于one-hot 编码,

    5 但实际上xgboost 的近似直方图算法页类似于lgb 的,为什么会慢,

    xgboost 在每一层都动态构建直方图,因为xgboost 的直方图算法不是针对每个特定的feature,而是所有feature 共享一个直方图(每个·样本的权重是二阶导,所以每一层都要重新构建直方图,而lgb 对每个特征都有一个直方图,所以构建一次直方图就够了。

    6 lgb 哪些方面做了并行:

    feature parallel

    一般的feature parallel 就是对数据做垂直分割,然后将分割后的数据分散到各个worker 上,各个worker 计算其拥有的数据的best split point,之后再汇总得到全局最优分割点,但是lgb 说这种方法通讯开销比较大,lgb 的做法是每个worker 有拥有所有数据,再分割。

    data parallel 

    传统的data parallel 是将对数据集进行划分,也叫平行分割,分散到各个workers 上,workers 对得到的数据做直方图,汇总各个workers 的直方图得到全局的直方图,但是通讯开销太大,lgb 的做法是使用Reduce  Scatter 机制,不汇总所有直方图,只汇总不同workers 的feature 的直方图,在这个汇总的直方图上做split,最后同步。

    参考:https://www.cnblogs.com/mata123/p/7440774.html

    四:随机森林和GBDT 的区别

    https://blog.csdn.net/login_sonata/article/details/73929426

    展开全文
  • LightGBM(lgb)详解

    万次阅读 多人点赞 2020-06-13 16:23:23
    LightGBM的基本原理 2.1 基于Histogram的决策树算法 (1)直方图算法 Histogram algorithm应该翻译为直方图算法,直方图算法的基本思想是:先把连续的浮点特征值离散化成 KKK个整数,同时构造一个宽度为 KKK的直方...
  • 矢量量化算法LGB矢量量化,是70年代后期发展起来的一种数据压缩技术是一种高效的有损数据压缩技术,它具有压缩比大、解码简单和失真较小等优点。其基本思想是将若干个标量数据组构成一个矢量,然后在矢量空间给以...
  • 提升算法——lightGBM原理学习笔记

    千次阅读 2018-10-31 17:22:27
    中文官方文档:http://lightgbm.apachecn.org/cn/latest/Installation-Guide.html 英文官方文档:... 1.lightGBM安装 在anaconda中输入:pip install lightGBM即可 输入import lightgbm as lgb做测试...
  • lgb使用方法与调参

    千次阅读 2020-07-19 13:28:54
    本文参考了lgb中文文档,和lgb调参笔记。 import lightgbm as lgb lgb参数 *type 1 不需要调试的参数 * boosting_type 1.gbdt 2.rf objective 1.regression 回归 2.binary 二分类(01) 3.multiclass 多分类(需要...
  • 2 LightGBM的基本原理 2.1 基于Histogram的决策树算法 (1)直方图算法 Histogram algorithm应该翻译为直方图算法,直方图算法的基本思想是:先把连续的浮点特征值离散化成 个整数,同时构造一个宽度为 的直方图...
  • XGB模型十分优秀,在很多大赛中表现很好,如果选出3个优秀的机器学习算法,XGB肯定能排上号。本部分将会总结XGB的众多关键点,同时对比其他相关的树模型,比如GBDT、LGB、RF等,理解了这些,拿下相关面试不在话下。 ...
  • python机器学习案例系列教程——LightGBM算法
  • 注意,下文的原始的...XGB知道吗,以XGB为例子说一下调参流程吧(个人的思路):一般来说采用贝叶斯优化或者遗传算法等启发式的优化算法确定相对最佳参数(如果不熟悉的话用随机搜索也是可以的,或者网格搜索但是...
  • 机器学习--LGB模型学习

    万次阅读 2018-05-16 16:23:12
    转自我的简书
  • 简介 微软DMTK团队在 github上开源了性能超越其他 boosting decision tree工具 ...属于监督学习算法。 通过调整模型参数w使得损失函数最小化,但一昧的最小化模型输出和数据标度的差异,可能会使得模型过拟合,所以通.
  • 1.矢量量化的基本思想: ...这里介绍一种算法---LBG算法。 LBG算法的思想: 1.随意选取n个图像块作为码矢量; 2.由这n个码矢量对所有的图像块进行划分,即分成n个集合,使每个集合中的图像块,都是与
  • 1. 写在前面如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法:监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,...
  • LightGBM 算法原理

    2019-04-23 14:21:00
    然后在计算上的代价也大幅降低,预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算k次(k可以认为是常数),时间复杂度从 O(#data #feature)优化到O(k #features)** 当然,Histogram...
  • LBG矢量量化算法

    千次阅读 2017-07-25 23:58:26
    LBG算法   1、矢量量化是一种数据压缩技术,是一种高效的有损数据压缩技术,它具有压缩比大、解码简单和失真较小等优点。其基本思想:将若干个标量数据组构成一个矢量,然后在矢量空间以整体量化,从而压缩了数据...
  • LightGBM算法详解

    千次阅读 2019-08-10 20:13:36
    1 LightGBM算法整体思路 2 本质区别:每轮迭代拟合残差树时增益公式(即分裂准则)推导 3 拟合该轮残差树前,用GOSS算法筛选样本 4 拟合该轮残差树前,用EFB算法减少特征量 <1> 如何发现互斥特征对; <2> 如何把互斥...
  • 1. LBG 算法介绍想直接从维基百科粘的…结果竟然没有这个词条! 英文维基内容也超!级!少! 最后找到了 这篇论文,是 LBG 算法最原始的原文了… 作为英文苦手呢,还是引用 CSDN 上 别人的博客 吧: LBG算法: ...
  • 在一个响应率模型中,使用传统的机器学习rf做二分类。通过特征入模后发现召回率和精确率较低该如何提升呢
  • 矢量量化——LBG算法

    千次阅读 2017-05-03 14:02:15
    我的运行环境为win7 vs2013,刚打开源代码时出现错误:#include 无法打开源代码,原因是头文件unistd.h是Linux/Unix的系统调用,所以必须把这个头文件加入到vs2013的头文件库里面,我的电脑是在 C:\Program ...
  • LBG演算法是一种在多传感器节点网络之中常用的一种演算法,LBG算法通过训练矢量集和一定的 迭代算法来逼近最优的分组数据,在这里,使用C#来实现对该演算法步骤的演示,并绘图表示。   本程序的流程图如下:   ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,624
精华内容 1,049
关键字:

lgb算法