lightgbm_lightgbm安装 - CSDN
精华内容
参与话题
  • python机器学习案例系列教程——LightGBM算法

    万次阅读 多人点赞 2020-06-21 21:28:19
    安装pip install lightgbmgitup网址:https://github.com/Microsoft/LightGBM中文教程http://lightgbm.apachecn.org/cn/latest/index.htmllightGBM简介xgboost的出现,让数据民工们告别了传统的机器学习算法们:RF、...

    分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开

    购买文章,更多优惠,免费送视频课

    全栈工程师开发手册 (作者:栾鹏)
    python教程全解

    安装

    pip install lightgbm
    

    gitup网址:https://github.com/Microsoft/LightGBM

    中文教程

    http://lightgbm.apachecn.org/cn/latest/index.html

    lightGBM简介

    xgboost的出现,让数据民工们告别了传统的机器学习算法们:RF、GBM、SVM、LASSO………。现在微软推出了一个新的boosting框架,想要挑战xgboost的江湖地位。

    顾名思义,lightGBM包含两个关键点:light即轻量级,GBM 梯度提升机。

    LightGBM 是一个梯度 boosting 框架,使用基于学习算法的决策树。它可以说是分布式的,高效的,有以下优势:

    • 更快的训练效率

    • 低内存使用

    • 更高的准确率

    • 支持并行化学习

    • 可处理大规模数据

    xgboost缺点

    其缺点,或者说不足之处:

    每轮迭代时,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。

    预排序方法(pre-sorted):首先,空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如排序后的索引,为了后续快速的计算分割点),这里需要消耗训练数据两倍的内存。其次时间上也有较大的开销,在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。

    对cache优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。

    lightGBM特点

    以上与其说是xgboost的不足,倒不如说是lightGBM作者们构建新算法时着重瞄准的点。解决了什么问题,那么原来模型没解决就成了原模型的缺点。

    概括来说,lightGBM主要有以下特点:

    • 基于Histogram的决策树算法

    • 带深度限制的Leaf-wise的叶子生长策略

    • 直方图做差加速

    • 直接支持类别特征(Categorical Feature)

    • Cache命中率优化

    • 基于直方图的稀疏特征优化

    • 多线程优化

    前2个特点使我们尤为关注的。

    Histogram算法

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

    带深度限制的Leaf-wise的叶子生长策略

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

    Leaf-wise则是一种更为高效的策略:每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。

    Leaf-wise的缺点:可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度限制,在保证高效率的同时防止过拟合。

    xgboost和lightgbm

    决策树算法

    XGBoost使用的是pre-sorted算法,能够更精确的找到数据分隔点;

    • 首先,对所有特征按数值进行预排序。
    • 其次,在每次的样本分割时,用O(# data)的代价找到每个特征的最优分割点。
    • 最后,找到最后的特征以及分割点,将数据分裂成左右两个子节点。

    优缺点:

    这种pre-sorting算法能够准确找到分裂点,但是在空间和时间上有很大的开销。

    • i. 由于需要对特征进行预排序并且需要保存排序后的索引值(为了后续快速的计算分裂点),因此内存需要训练数据的两倍。
    • ii. 在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。

    LightGBM使用的是histogram算法,占用的内存更低,数据分隔的复杂度更低。

    其思想是将连续的浮点特征离散成k个离散值,并构造宽度为k的Histogram。然后遍历训练数据,统计每个离散值在直方图中的累计统计量。在进行特征选择时,只需要根据直方图的离散值,遍历寻找最优的分割点。

    Histogram 算法的优缺点:

    • Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在实际的数据集上表明,离散化的分裂点对最终的精度影响并不大,甚至会好一些。原因在于decision tree本身就是一个弱学习器,采用Histogram算法会起到正则化的效果,有效地防止模型的过拟合。
    • 时间上的开销由原来的O(#data * #features)降到O(k * #features)。由于离散化,#bin远小于#data,因此时间上有很大的提升。
    • Histogram算法还可以进一步加速。一个叶子节点的Histogram可以直接由父节点的Histogram和兄弟节点的Histogram做差得到。一般情况下,构造Histogram需要遍历该叶子上的所有数据,通过该方法,只需要遍历Histogram的k个捅。速度提升了一倍。

    决策树生长策略

    XGBoost采用的是按层生长level(depth)-wise生长策略,如Figure 1所示,能够同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合;但不加区分的对待同一层的叶子,带来了很多没必要的开销。因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

    这里写图片描述

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

    这里写图片描述

    网络通信优化

    XGBoost由于采用pre-sorted算法,通信代价非常大,所以在并行的时候也是采用histogram算法;LightGBM采用的histogram算法通信代价小,通过使用集合通信算法,能够实现并行计算的线性加速。

    LightGBM支持类别特征

    实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化one-hotting特征,降低了空间和时间的效率。而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。

    lightGBM调参

    所有的参数含义,参考:http://lightgbm.apachecn.org/cn/latest/Parameters.html

    调参过程:

    (1)num_leaves

    LightGBM使用的是leaf-wise的算法,因此在调节树的复杂程度时,使用的是num_leaves而不是max_depth。

    大致换算关系:num_leaves = 2^(max_depth)

    (2)样本分布非平衡数据集:可以param[‘is_unbalance’]=’true’

    (3)Bagging参数:bagging_fraction+bagging_freq(必须同时设置)、feature_fraction

    (4)min_data_in_leaf、min_sum_hessian_in_leaf

    sklearn接口形式的LightGBM示例

    这里主要以sklearn的使用形式来使用lightgbm算法,包含建模,训练,预测,网格参数优化。

    import lightgbm as lgb
    import pandas as pd
    from sklearn.metrics import mean_squared_error
    from sklearn.model_selection import GridSearchCV
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import  make_classification
    # 加载数据
    print('Load data...')
    
    iris = load_iris()
    data=iris.data
    target = iris.target
    X_train,X_test,y_train,y_test =train_test_split(data,target,test_size=0.2)
    
    # df_train = pd.read_csv('../regression/regression.train', header=None, sep='\t')
    # df_test = pd.read_csv('../regression/regression.test', header=None, sep='\t')
    # y_train = df_train[0].values
    # y_test = df_test[0].values
    # X_train = df_train.drop(0, axis=1).values
    # X_test = df_test.drop(0, axis=1).values
    
    print('Start training...')
    # 创建模型,训练模型
    gbm = lgb.LGBMRegressor(objective='regression',num_leaves=31,learning_rate=0.05,n_estimators=20)
    gbm.fit(X_train, y_train,eval_set=[(X_test, y_test)],eval_metric='l1',early_stopping_rounds=5)
    
    print('Start predicting...')
    # 测试机预测
    y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)
    # 模型评估
    print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
    
    # feature importances
    print('Feature importances:', list(gbm.feature_importances_))
    
    # 网格搜索,参数优化
    estimator = lgb.LGBMRegressor(num_leaves=31)
    
    param_grid = {
        'learning_rate': [0.01, 0.1, 1],
        'n_estimators': [20, 40]
    }
    
    gbm = GridSearchCV(estimator, param_grid)
    
    gbm.fit(X_train, y_train)
    
    print('Best parameters found by grid search are:', gbm.best_params_)
    
    

    原生形式使用lightgbm

    # coding: utf-8
    # pylint: disable = invalid-name, C0111
    import json
    import lightgbm as lgb
    import pandas as pd
    from sklearn.metrics import mean_squared_error
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import  make_classification
    
    iris = load_iris()
    data=iris.data
    target = iris.target
    X_train,X_test,y_train,y_test =train_test_split(data,target,test_size=0.2)
    
    
    # 加载你的数据
    # print('Load data...')
    # df_train = pd.read_csv('../regression/regression.train', header=None, sep='\t')
    # df_test = pd.read_csv('../regression/regression.test', header=None, sep='\t')
    #
    # y_train = df_train[0].values
    # y_test = df_test[0].values
    # X_train = df_train.drop(0, axis=1).values
    # X_test = df_test.drop(0, axis=1).values
    
    # 创建成lgb特征的数据集格式
    lgb_train = lgb.Dataset(X_train, y_train)
    lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
    
    # 将参数写成字典下形式
    params = {
        'task': 'train',
        '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,  # k 意味着每 k 次迭代执行bagging
        'verbose': 1 # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
    }
    
    print('Start training...')
    # 训练 cv and train
    gbm = lgb.train(params,lgb_train,num_boost_round=20,valid_sets=lgb_eval,early_stopping_rounds=5)
    
    print('Save model...')
    # 保存模型到文件
    gbm.save_model('model.txt')
    
    print('Start predicting...')
    # 预测数据集
    y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
    # 评估模型
    print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
    
    
    展开全文
  • LightGBM介绍

    2020-06-02 19:14:32
    1、LightGBM简介 LightGBM是一个梯度Boosting框架,使用基于决策树的学习算法。具有以下优势: a)更快的训练效率 b)低内存使用 c)更高的正确率 d)支持并行化学习 e)可以处理大规模数据 2、XGBoost的不足...

    1、LightGBM简介

    LightGBM是一个梯度Boosting框架,使用基于决策树的学习算法。具有以下优势:

    a)更快的训练效率

    b)低内存使用

    c)更高的正确率

    d)支持并行化学习

    e)可以处理大规模数据

    2、XGBoost的不足

    a)每轮迭代时,都需要遍历整个训练数据多次,如果把整个训练数据装进内存,则会限制训练数据的大小,如果不装进内存,反复读写训练数据又会消耗非常大的时间。

    b)预排序方法的时间和空间的消耗都很大.

    3、LightGBM原理

    1)直方图算法:把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。在XGBoost中需要遍历所有离散化的值,而在这里只要通过遍历k个直方图的值

    2)LightGBM的直方图做差加速:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到,且直方图做差仅遍历直方图的k个桶

    3)带深度限制的leaf-wise的叶子生长策略

    4)直接支持类别特征(即不需要组偶one-hot编码)

    5)支持高效并行:

    a)特征并行:在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优分割点

    b)数据并行:让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点

    4、LightGBM参数调优

    max_depth 树的最大深度 过拟合时,可以首先考虑降低参数
    min_data_in_leaf 叶子最小记录数 默认20,过拟合时用
    feature_fraction 例如为0.8时,意味着在每次迭代中随机选择80%的参数来建树 boosting为random forest时用
    bagging_fraction 每次迭代用的数据比例 用于加快训练速度和减少过拟合
    early_stopping_round 如果一次验证数据的一个度量在最近的early_stopping_round回合中没有提高,模型将停止训练 加速分析,减少过多迭代
    Task 数据的用途 选择train或者predict
    application 模型的用途

    回归:regression

    二分类:binary

    多分类:multiclass

    boosting 要用的算法

    gbdt

    rf:random forest

    dart:Dropouts meet Multiple Additive Regression Trees

    goss:Gradient-based One-Side Sampling

    num_boost_round 迭代次数 通常100+
    learning_rate 如果一次验证数据的要给度量,在最近的early_stopping_round回合中没有提高,模型将停止训练 通常为0.1
    num_leaves   默认31
    device   cpu或gpu
    metric  

    mae:mean absolute error

    mse:mean squared error

    binary_logloss:loss for binary classification

    multi_logloss:loss for multi classification

    4、Boosting的算法流程

    展开全文
  • Lightgbm基本原理介绍

    万次阅读 多人点赞 2018-09-23 22:11:51
    一、 前言 最近在做Kaggle比赛的...所以就对Lightgbm的原理探了个究竟,这里就对Lightgbm论文的理解以及对官网上对Lightgbm的介绍做一个学习笔记。 传统的boosting算法(如GBDT和XGBoost)已经有相当好的效率,...

    一、 前言

    最近在做Kaggle比赛的时候,看到别人的Kenels中都用到了lightgbm,自己也试图用了一下,发现效果很好,最重要的是它相对于XGBoost算法,大大的降低了运行的速度。所以就对Lightgbm的原理探了个究竟,这里就对Lightgbm论文的理解以及对官网上对Lightgbm的介绍做一个学习笔记。

    传统的boosting算法(如GBDT和XGBoost)已经有相当好的效率,但是在如今的大样本和高维度的环境下,传统的boosting似乎在效率和可扩展性上不能满足现在的需求了,主要的原因就是传统的boosting算法需要对每一个特征都要扫描所有的样本点来选择最好的切分点,这是非常的耗时。为了解决这种在大样本高纬度数据的环境下耗时的问题,Lightgbm使用了如下两种解决办法:一是GOSS(Gradient-based One-Side Sampling, 基于梯度的单边采样),不是使用所用的样本点来计算梯度,而是对样本进行采样来计算梯度;二是EFB(Exclusive Feature Bundling, 互斥特征捆绑) ,这里不是使用所有的特征来进行扫描获得最佳的切分点,而是将某些特征进行捆绑在一起来降低特征的维度,是寻找最佳切分点的消耗减少。这样大大的降低的处理样本的时间复杂度,但在精度上,通过大量的实验证明,在某些数据集上使用Lightgbm并不损失精度,甚至有时还会提升精度。下面就主要介绍这两种方法。

    本文的主要内容,首先介绍GOSS和EFB方法,然后再根据Lightgbm官网的介绍,谈一谈Lightgbm的特性以及调参。

    二、Gradient-based One-Side Sampling(GOSS)介绍

    GOSS(基于梯度的单边采样)方法的主要思想就是,梯度大的样本点在信息增益的计算上扮演着主要的作用,也就是说这些梯度大的样本点会贡献更多的信息增益,因此为了保持信息增益评估的精度,当我们对样本进行下采样的时候保留这些梯度大的样本点,而对于梯度小的样本点按比例进行随机采样即可。

    2.1 GOSS算法

    在AdaBoost算法中,我们在每次迭代时更加注重上一次错分的样本点,也就是上一次错分的样本点的权重增大,而在GBDT中并没有本地的权重来实现这样的过程,所以在AdaBoost中提出的采样模型不能应用在GBDT中。但是,每个样本的梯度对采样提供了非常有用的信息。也就是说,如果一个样本点的梯度小,那么该样本点的训练误差就小并且已经经过了很好的训练。一个直接的办法就是直接抛弃梯度小的样本点,但是这样做的话会改变数据的分布和损失学习的模型精度。GOSS的提出就是为了避免这两个问题的发生。下面就是GOSS算法的伪代码:

    下面将对上述算法进行描述。

    2.2 GOSS算法描述

    输入:训练数据,迭代步数d,大梯度数据的采样率a,小梯度数据的采样率b,损失函数和若学习器的类型(一般为决策树);

    输出:训练好的强学习器;

    (1)根据样本点的梯度的绝对值对它们进行降序排序;

    (2)对排序后的结果选取前a*100%的样本生成一个大梯度样本点的子集;

    (3)对剩下的样本集合(1-a)*100%的样本,随机的选取b*(1-a)*100%个样本点,生成一个小梯度样本点的集合;

    (4)将大梯度样本和采样的小梯度样本合并;

    (5)将小梯度样本乘上一个权重系数\frac{1-a}{b}

    (6)使用上述的采样的样本,学习一个新的弱学习器;

    (7)不断地重复(1)~(6)步骤直到达到规定的迭代次数或者收敛为止。

    通过上面的算法可以在不改变数据分布的前提下不损失学习器精度的同时大大的减少模型学习的速率。

    从上面的描述可知,当a=0时,GOSS算法退化为随机采样算法;当a=1时,GOSS算法变为采取整个样本的算法。在许多情况下,GOSS算法训练出的模型精确度要高于随机采样算法。另一方面,采样也将会增加若学习器的多样性,从而潜在的提升了训练出的模型泛化能力。

    三、Exclusive Feature Bundling(EFB)介绍

    Lightgbm实现中不仅进行了数据采样,也进行了特征抽样,使得模型的训练速度进一步的减少。但是该特征抽样又与一般的特征抽样有所不同,是将互斥特征绑定在一起从而减少特征维度。主要思想就是,通常在实际应用中高纬度的数据往往都是稀疏数据(如one-hot编码),这使我们有可能设计一种几乎无损的方法来减少有效特征的数量。尤其,在稀疏特征空间中许多特征都是互斥的(例如,很少同时出现非0值)。这就使我们可以安全的将互斥特征绑定在一起形成一个特征,从而减少特征维度。但是怎样的将互斥特征绑定在一起了?Lightgbm作者使用的是基于直方图(histograms)的方法。

    3.1 EFB算法

    由于将特征划分为更小的互斥绑定数量,这是一个NP-hard问题,即在多项式时间内不可能去找到准确的解决办法。所以这里使用的是一种近似的解决办法,即特征之间允许存在少数的样本点并不是互斥的(如存在某些对应的样本点之间不同时为非0值),允许小部分的冲突可以得到更小的特征绑定数量,更进一步的提高了计算的有效性。在理论上可以证明,通过允许小部分的冲突的话,使得模型的accuracy被影响O([(1-\gamma )n]^{-2/3}),这里的\gamma是每个绑定的最大冲突率。所以,当我们选择很小的\gamma时,我们可以在精确度和效率上获得很好的权衡。下面就是互斥特征绑定(Exclusive Feature Bundling)的算法:

    下面将对上述算法进行描述。

    3.2 EFB算法描述

    输入:特征F,最大冲突数K,图G;

    输出:特征捆绑集合bundles;

    (1)构造一个边带有权重的图,其权值对应于特征之间的总冲突;

    (2)通过特征在图中的度来降序排序特征;

    (3)检查有序列表中的每个特征,并将其分配给具有小冲突的现有bundling(由\gamma控制),或创建新bundling。

    上述算法的时间复杂度为O(\#feature^2)并且在模型训练之前仅仅被处理一次即可。在特征维度不是很大时,这样的复杂度是可以接受的。但是当样本维度较高时,这种方法就会特别的低效。所以对于此,作者又提出的另外一种更加高效的算法:按非零值计数排序,这类似于按度数排序,因为更多的非零值通常会导致更高的冲突概率。 这仅仅改变了上述算法的排序策略,所以只是针对上述算法将按度数排序改为按非0值数量排序,其他不变。

    3.3 合并互斥特征

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

    由于基于直方图的算法存储的是离散的bins而不是连续的特征值,我们可以通过让互斥特征驻留在不同的bins中来构造feature bundle。这可以通过增加特征原始值的偏移量来实现。比如,假设我们有两个特征,特征A的取值范围是[0,10),而特征B的取值范围是[0,20),我们可以给特征B增加偏移量10,使得特征B的取值范围为[10, 30),最后合并特征A和B,形成新的特征,取值范围为[0,30)来取代特征A和特征B。

    当然,Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在不同的数据集上的结果表明,离散化的分割点对最终的精度影响并不是很大,甚至有时候会更好一点。原因是决策树本来就是弱模型,分割点是不是精确并不是太重要;差一点的切分点也有正则化的效果,可以有效地防止过拟合;即使单棵树的训练误差比精确分割的算法稍大,但在Gradient Boosting的框架下没有太大的影响。

    Histogram算法有如下的一些优点:

    (1)减少分割增益的计算量:xgboost中默认使用的是pre-sorted算法,需要O(\#data)次的计算,而Histogram算法只需要计算O(\#bins)次,并且O(\#bins)远小于O(\#data)

    (2)通过直方图相减来进一步的加速模型的训练:在二叉树中可以通过利用叶节点的父节点和相邻节点的直方图的相减来获得该叶节点的直方图。所以仅仅需要为一个叶节点建立直方图 (其\#data小于它的相邻节点)就可以通过直方图的相减来获得相邻节点的直方图,而这花费的代价(O(\#bins))很小。

    (3)减少内存的使用:可以将连续的值替换为离散的bins。 如果\#bins较小, 可以利用较小的数据类型来存储训练数据并且无需为 pre-sorting 特征值存储额外的信息。

    (4)减少并行学习的通信代价。

    我们称使用GOSS算法和EFB算法的梯度提升树(GBDT)称之为LightGBM。

    四、Lightgbm的一些其它特性

    4.1 Leaf-wise的决策树生长策略

    大部分决策树的学习算法通过 level-wise 策略生长树,记一次分裂同一层的叶子,不加区分的对待同一层的叶子,而实际上很多叶子的分裂增益较低没必要进行分裂,带来了没必要的开销。如下图:

    LightGBM 通过 leaf-wise 策略来生长树。每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。但是,当样本量较小的时候,leaf-wise 可能会造成过拟合。 所以,LightGBM 可以利用额外的参数 max_depth 来限制树的深度并避免过拟合。

    4.2 类别特征值的最优分割

    对于类别型的数据,我们通常将类别特征转化为one-hot/哑变量编码。 然而,对于学习树来说这不是个好的解决方案。 原因是,对于一个基数较大的类别特征,学习树会生长的非常不平衡,并且需要非常深的深度才能来达到较好的准确率。

    事实上,最好的解决方案是将类别特征划分为两个子集,总共有2^{(k-1) }- 1种可能的切分。比如有一个颜色特征,每个样本的颜色特征是{红、黄、蓝、绿}四种类别中的一种,如果使用ne-hot/哑变量编码很好理解这里不再叙述,但是如果使用LightGBM的切分策略,就是将红、黄、蓝、绿对应的四类样本分为两类的所有可能策略,比如:红黄一类,蓝绿一类。那么就会有2^{(k-1) }- 1 种策略,这样才能充分的挖掘该维特征所包含的信息,找到最优的分割策略。 但是这样寻找最优分割策略的时间复杂度就会很大。对于回归树有个有效的解决方案。为了寻找最优的划分需要大约 k * log(k) 。基本的思想是根据训练目标的相关性对类别进行重排序。 更具体的说,根据累加值(sum\_gradient/sum\_hessian)重新对(类别特征的)直方图进行排序,然后在排好序的直方图中寻找最好的分割点。

    4.3 Lightgbm中的并行学习

    4.3.1 特征并行

    1、传统算法的的特征并行

    传统的特征并行算法旨在于在并行化决策树中的寻找最佳切分点,主要流程如下:

    (1)垂直切分数据(不同的Worker有不同的特征集);

    (2)在本地特征集寻找最佳切分点 {特征, 阈值};

    (3)在各个机器之间进行通信,拿出自己的最佳切分点,然后从所有的最佳切分点中推举出一个最好的切分点,作为全局的切分点;

    (4)以最佳划分方法对数据进行划分,并将数据划分结果传递给其他Worker;

    (5)其他Worker对接受到的数据进一步划分。

    2、传统的特征并行方法主要不足:

    (1)存在计算上的局限,传统特征并行无法加速特征切分(时间复杂度为 O(\#data))。 因此,当数据量很大的时候,难以加速。

    (2)需要对划分的结果进行通信整合,其额外的时间复杂度约为O(\#data/8)。(一个数据一个字节)

    3、LightGBM 中的特征并行

    在数据量很大时,传统并行方法无法有效地对特征进行并行,LightGBM 做了一些改变:不再垂直划分数据,即每个Worker都持有全部数据。 因此,LighetGBM中没有数据划分结果之间通信的开销,各个Worker都知道如何划分数据。 而且,样本量也不会变得更大,所以,使每个机器都持有全部数据是合理的。

    LightGBM 中特征并行的流程如下:

    (1)每个Worker都在本地特征集上寻找最佳划分点{特征, 阈值};

    (2)本地进行各个划分的通信整合并得到最佳划分;

    (3)执行最佳划分。

    然而,该特征并行算法在数据量很大时仍然存在计算上的局限。因此,建议在数据量很大时使用数据并行。

    4.3.2 数据并行

    1、传统的数据并行算法

    数据并行目的是并行化整个决策学习过程。数据并行的主要流程如下:

    (1)水平划分数据;

    (2)Worker以本地数据构建本地直方图;

    (3)将所有Worker的本地直方图整合成全局整合图;

    (4)在全局直方图中寻找最佳切分,然后执行此切分。

    2、传统数据并行的不足:

    高通讯开销。 如果使用点对点的通讯算法,一个Worker的通讯开销大约为O(\#machine * \#feature * \#bin)。 如果使用集体通讯算法(例如, “All Reduce”等),通讯开销大约为O(2 * \#feature * \#bin)

    3、LightGBM中的数据并行

    LightGBM 中通过减少数据并行过程中的通讯开销,来减少数据并行的开销:

    (1)不同于传统数据并行算法中的,整合所有本地直方图以形成全局直方图的方式,LightGBM 使用Reduce scatter的方式对不同Worker的不同特征(不重叠的)进行整合。 然后Worker从本地整合直方图中寻找最佳划分并同步到全局的最佳划分中。

    (2)如上面提到的,LightGBM 通过直方图做差法加速训练。 基于此,我们可以进行单叶子的直方图通讯,并且在相邻直方图上使用做差法。

    通过上述方法,LightGBM 将数据并行中的通讯开销减少到O(0.5 * \#feature * \#bin)

    4.3.3 投票并行

    投票并行进一步的减少数据并行的的通信消耗为常数级别。它使用两阶段的投票来减少特征直方图的通信消耗。

    五、LightGBM中的主要调节的参数

    5.1 针对 Leaf-wise(Best-first)树的参数优化

    (1)num_leaves这是控制树模型复杂度的主要参数。理论上, 借鉴 depth-wise 树, 我们可以设置 num_leaves= 2^{(max\_depth)} 但是, 这种简单的转化在实际应用中表现不佳. 这是因为, 当叶子数目相同时, leaf-wise 树要比 depth-wise 树深得多, 这就有可能导致过拟合. 因此, 当我们试着调整 num_leaves 的取值时, 应该让其小于 2^{(max\_depth)}. 举个例子, 当 max_depth=7时,depth-wise 树可以达到较高的准确率.但是如果设置 num_leaves 为 128 时, 有可能会导致过拟合, 而将其设置为 70 或 80 时可能会得到比 depth-wise 树更高的准确率. 其实, depth 的概念在 leaf-wise 树中并没有多大作用, 因为并不存在一个从 leaves 到 depth 的合理映射。

    (2)min_data_in_leaf. 这是处理 leaf-wise 树的过拟合问题中一个非常重要的参数. 它的值取决于训练数据的样本个树和 num_leaves. 将其设置的较大可以避免生成一个过深的树, 但有可能导致欠拟合. 实际应用中, 对于大数据集, 设置其为几百或几千就足够了。

    (3)max_depth(默认不限制,一般设置该值为5—10即可) 你也可以利用 max_depth 来显式地限制树的深度。

    5.2 针对更快的训练速度

    (1)通过设置 bagging_fraction 和 bagging_freq 参数来使用 bagging 方法;

    (2)通过设置 feature_fraction 参数来使用特征的子抽样;

    (3)使用较小的 max_bin

    (4)使用 save_binary 在以后的学习过程对数据进行加速加载。

    5.3 针对更好的准确率

    (1)使用较大的 max_bin (学习速度可能变慢);

    (2)使用较小的 learning_rate 和较大的 num_iterations;

    (3)使用较大的 num_leaves (可能导致过拟合);

    (4)使用更大的训练数据;

    (5)尝试 dart(一种在多元Additive回归树种使用dropouts的算法).

    5.4 处理过拟合

    (1)使用较小的 max_bin(默认为255

    (2)使用较小的 num_leaves(默认为31)

    (3)使用 min_data_in_leaf(默认为20) 和 min_sum_hessian_in_leaf(默认为e^{-3}

    (4)通过设置 bagging_fraction (默认为1.0)和 bagging_freq (默认为0,意味着禁用bagging,k表示每k次迭代执行一个bagging)来使用 bagging

    (5)通过设置 feature_fraction(默认为1.0) 来使用特征子抽样

    (6)使用更大的训练数据

    (7)使用 lambda_l1(默认为0lambda_l2 默认为0和 min_split_gain(默认为0,表示执行切分的最小增益) 来使用正则

    (8)尝试 max_depth 来避免生成过深的树

    六、参考文献

    (1)LightGBM: A Highly Efficient Gradient Boosting Decision Tree 论文

    (2)LightGBM官网

    展开全文
  • LightGBM是个快速的,分布式的,高性能的基于决策树算法的梯度提升框架。可用于排序,分类,回归以及很多其他的机器学习任务中。 在竞赛题中,我们知道XGBoost算法非常热门,它是一种优秀的拉动框架,但是在使用...

    前言

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

    在竞赛题中,我们知道XGBoost算法非常热门,它是一种优秀的拉动框架,但是在使用过程中,其训练耗时很长,内存占用比较大。在2017年年1月微软在GitHub的上开源了一个新的升压工具--LightGBM。在不降低准确率的前提下,速度提升了10倍左右,占用内存下降了3倍左右。因为他是基于决策树算法的,它采用最优的叶明智策略分裂叶子节点,然而其它的提升算法分裂树一般采用的是深度方向或者水平明智而不是叶,明智的。因此,在LightGBM算法中,当增长到相同的叶子节点,叶明智算法比水平-wise算法减少更多的损失。因此导致更高的精度,而其他的任何已存在的提升算法都不能够达。与此同时,它的速度也让人感到震惊,这就是该算法名字   的原因。

    • 2014年3月,XGBOOST最早作为研究项目,由陈天奇提出

         (XGBOOST的部分在我的另一篇博客里:https://blog.csdn.net/huacha__/article/details/81029680

    • 2017年1月,微软发布首个稳定版LightGBM

    在微软亚洲研究院AI头条分享中的「LightGBM简介」中,机器学习组的主管研究员王太峰提到:微软DMTK团队在github上开源了性能超越其它推动决策树工具LightGBM后,三天之内星了1000+次,叉了超过200次。知乎上有近千人关注“如何看待微软开源的LightGBM?”问题,被评价为“速度惊人”,“非常有启发”,“支持分布式” “代码清晰易懂”,“占用内存小”等。以下是微软官方提到的LightGBM的各种优点,以及该项目的开源地址。

    科普链接:如何玩转LightGBM https://v.qq.com/x/page/k0362z6lqix.html

    目录

    前言

    一、"What We Do in LightGBM?"

    二、在不同数据集上的对比

    三、LightGBM的细节技术

    1、直方图优化

    2、存储记忆优化

    3、深度限制的节点展开方法

    4、直方图做差优化

    5、顺序访问梯度

    6、支持类别特征

    7、支持并行学习

    四、MacOS安装LightGBM

    五、用python实现LightGBM算法


    一、"What We Do in LightGBM?"

    下面这个表格给出了XGBoost和LightGBM之间更加细致的性能对比,包括了树的生长方式,LightGBM是直接去选择获得最大收益的结点来展开,而XGBoost是通过按层增长的方式来做,这样呢LightGBM能够在更小的计算代价上建立我们需要的决策树。当然在这样的算法中我们也需要控制树的深度和每个叶子结点的最小数据量,从而减少过拟合。

    小小翻译一下,有问题还望指出

      XGBoost LightGBM
    树木生长算法

    按层生长的方式

    有利于工程优化,但对学习模型效率不高

    直接选择最大收益的节点来展开,在更小的计算代价上去选择我们需要的决策树

    控制树的深度和每个叶子节点的数据量,能减少过拟合

    划分点搜索算 法 对特征预排序的方法 直方图算法:将特征值分成许多小筒,进而在筒上搜索分裂点,减少了计算代价和存储代价,得到更好的性能。另外数据结构的变化使得在细节处的变化理上效率会不同
    内存开销 8个字节 1个字节
    划分的计算增益 数据特征 容器特征
    高速缓存优化 在Higgs数据集上加速40%
    类别特征处理 在Expo数据集上速度快了8倍

    二、在不同数据集上的对比

    higgs和expo都是分类数据,yahoo ltr和msltr都是排序数据,在这些数据中,LightGBM都有更好的准确率和更强的内存使用量。

    准确率   

    内存使用情况

    计算速度的对比,完成相同的训练量XGBoost通常耗费的时间是LightGBM的数倍之上,在higgs数据集上,它们的差距更是达到了15倍以上。

    三、LightGBM的细节技术

    1、直方图优化

    XGBoost中采用预排序的方法,计算过程当中是按照value的排序,逐个数据样本来计算划分收益,这样的算法能够精确的找到最佳划分值,但是代价比较大同时也没有较好的推广性。

    在LightGBM中没有使用传统的预排序的思路,而是将这些精确的连续的每一个value划分到一系列离散的域中,也就是筒子里。以浮点型数据来举例,一个区间的值会被作为一个筒,然后以这些筒为精度单位的直方图来做。这样一来,数据的表达变得更加简化,减少了内存的使用,而且直方图带来了一定的正则化的效果,能够使我们做出来的模型避免过拟合且具有更好的推广性。

    看下直方图优化的细节处理

    可以看到,这是按照bin来索引“直方图”,所以不用按照每个“特征”来排序,也不用一一去对比不同“特征”的值,大大的减少了运算量。

    2、存储记忆优化

    当我们用数据的bin描述数据特征的时候带来的变化:首先是不需要像预排序算法那样去存储每一个排序后数据的序列,也就是下图灰色的表,在LightGBM中,这部分的计算代价是0;第二个,一般bin会控制在一个比较小的范围,所以我们可以用更小的内存来存储

    3、深度限制的节点展开方法

    LightGBM使用了带有深度限制的节点展开方法(Leaf-wise)来提高模型精度,这是比XGBoost中Level-wise更高效的方法。它可以降低训练误差得到更好的精度。但是单纯的使用Leaf-wise可能会生长出比较深的树,在小数据集上可能会造成过拟合,因此在Leaf-wise之上多加一个深度限制

    4、直方图做差优化

    直方图做差优化可以达到两倍的加速,可以观察到一个叶子节点上的直方图,可以由它的父亲节点直方图减去它兄弟节点的直方图来得到。根据这一点我们可以构造出来数据量比较小的叶子节点上的直方图,然后用直方图做差来得到数据量比较大的叶子节点上的直方图,从而达到加速的效果。

    5、顺序访问梯度

    预排序算法中有两个频繁的操作会导致cache-miss,也就是缓存消失(对速度的影响很大,特别是数据量很大的时候,顺序访问比随机访问的速度快4倍以上  )。

    • 对梯度的访问:在计算增益的时候需要利用梯度,对于不同的特征,访问梯度的顺序是不一样的,并且是随机的
    • 对于索引表的访问:预排序算法使用了行号和叶子节点号的索引表,防止数据切分的时候对所有的特征进行切分。同访问梯度一样,所有的特征都要通过访问这个索引表来索引。

    这两个操作都是随机的访问,会给系统性能带来非常大的下降。

    LightGBM使用的直方图算法能很好的解决这类问题。首先。对梯度的访问,因为不用对特征进行排序,同时,所有的特征都用同样的方式来访问,所以只需要对梯度访问的顺序进行重新排序,所有的特征都能连续的访问梯度。并且直方图算法不需要把数据id到叶子节点号上(不需要这个索引表,没有这个缓存消失问题)

    6、支持类别特征

    传统的机器学习一般不能支持直接输入类别特征,需要先转化成多维的0-1特征,这样无论在空间上还是时间上效率都不高。LightGBM通过更改决策树算法的决策规则,直接原生支持类别特征,不需要转化,提高了近8倍的速度

    7、支持并行学习

    LightGBM原生支持并行学习,目前支持特征并行(Featrue Parallelization)数据并行(Data Parallelization)两种,还有一种是基于投票的数据并行(Voting Parallelization)

    • 特征并行的主要思想是在不同机器、在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。
    • 数据并行则是让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点

    LightGBM针对这两种并行方法都做了优化。

    • 特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信。
    • 数据并行中使用分散规约 (Reduce scatter) 把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。
    • 基于投票的数据并行(Voting Parallelization)则进一步优化数据并行中的通信代价,使通信代价变成常数级别。在数据量很大的时候,使用投票并行可以得到非常好的加速效果。

    下图更好的说明了以上这三种并行学习的整体流程:

    在直方图合并的时候,通信代价比较大,基于投票的数据并行能够很好的解决这一点。

     

    四、MacOS安装LightGBM

    #先安装cmake和gcc,安装过的直接跳过前两步
    brew install cmake
    brew install gcc
    
    git clone --recursive https://github.com/Microsoft/LightGBM 
    cd LightGBM
    
    #在cmake之前有一步添加环境变量
    export CXX=g++-7 CC=gcc-7
    mkdir build ; cd build
    
    cmake ..
    make -j4
    cd ../python-package
    sudo python setup.py install

    来测试一下:

    大功告成!

    值得注意的是:pip list里面没有lightgbm,以后使用lightgbm需要到特定的文件夹中运行。我的地址是:

    /Users/ fengxianhe / LightGBM /python-package

     

    五,用python实现LightGBM算法

    为了演示LightGBM在蟒蛇中的用法,本代码以sklearn包中自带的鸢尾花数据集为例,用lightgbm算法实现鸢尾花种类的分类任务。

    # coding: utf-8
    # pylint: disable = invalid-name, C0111
    
    # 函数的更多使用方法参见LightGBM官方文档:http://lightgbm.readthedocs.io/en/latest/Python-Intro.html
    
    import json
    import lightgbm as lgb
    import pandas as pd
    from sklearn.metrics import mean_squared_error
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import  make_classification
    
    iris = load_iris()   # 载入鸢尾花数据集
    data=iris.data
    target = iris.target
    X_train,X_test,y_train,y_test =train_test_split(data,target,test_size=0.2)
    
    
    # 加载你的数据
    # print('Load data...')
    # df_train = pd.read_csv('../regression/regression.train', header=None, sep='\t')
    # df_test = pd.read_csv('../regression/regression.test', header=None, sep='\t')
    #
    # y_train = df_train[0].values
    # y_test = df_test[0].values
    # X_train = df_train.drop(0, axis=1).values
    # X_test = df_test.drop(0, axis=1).values
    
    # 创建成lgb特征的数据集格式
    lgb_train = lgb.Dataset(X_train, y_train) # 将数据保存到LightGBM二进制文件将使加载更快
    lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)  # 创建验证数据
    
    # 将参数写成字典下形式
    params = {
        'task': 'train',
        '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,  # k 意味着每 k 次迭代执行bagging
        'verbose': 1 # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
    }
    
    print('Start training...')
    # 训练 cv and train
    gbm = lgb.train(params,lgb_train,num_boost_round=20,valid_sets=lgb_eval,early_stopping_rounds=5) # 训练数据需要参数列表和数据集
    
    print('Save model...') 
    
    gbm.save_model('model.txt')   # 训练后保存模型到文件
    
    print('Start predicting...')
    # 预测数据集
    y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration) #如果在训练期间启用了早期停止,可以通过best_iteration方式从最佳迭代中获得预测
    # 评估模型
    print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5) # 计算真实值和预测值之间的均方根误差

    输出结果:

    可以看到预测值和真实值之间的均方根误差为0.722972。

    展开全文
  • LightGBM算法总结

    万次阅读 多人点赞 2018-08-22 09:09:09
    1 LightGBM原理 1.1 GBDT和 LightGBM对比 ​ GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、...
  • LightGBM的一点理解

    千次阅读 2018-09-06 15:13:07
    LightGBM是微软团队2017年发表在NIPS的一篇论文,也是一种基于GBDT的Boosting的方法。之前有了各种Boosting方法,以及在各类数据比赛中大放异彩的XGBoost,LightGBM的优势在哪里呢? LightGBM是一种基于GBDT的提升...
  • LightGBM参数介绍

    万次阅读 多人点赞 2018-01-10 17:30:21
    Xgboost和LightGBM部分参数对照: Xgboots LightGbm   booster(default=gbtree) boosting(default=gbdt) eta(default=0.3) learning_rate(default=0.1) max_depth(default=6)
  • lightgbm

    2019-08-13 23:50:14
    LightGBM 虽然xgboost在GBDT实现上做了一些改进,但是在数据纬度高,数据量大的情况下依旧不能满足需求。lightGBM主要解决速度问题的,在精度上也做了一点改进。主要从减少数据量和特征量两个角度来提速,针对这两...
  • Lightgbm.rar

    2020-07-30 23:33:17
    Lightgbm算法的简单应用,Lightgbm的算法原理参考https://blog.csdn.net/luanpeng825485697/article/details/80236759这个博客学习一下
  • LightGBM安装教程

    万次阅读 2020-04-13 09:48:25
    LightGBM安装教程,使用教程
  • LightGBM官方中文文档上线啦!

    万次阅读 多人点赞 2018-01-04 16:49:23
    走过路过的大佬请点个star让我以后好装逼,谢谢各位了,Orz主页地址:http://lightgbm.apachecn.org/cn/latest/index.htmlGithub:https://github.com/apachecn/lightgbm-doc-zh请点进Github帮忙点个star,
  • lightgbm python基本使用 --mac下操作

    万次阅读 2017-06-09 13:02:56
    好几天没有更新博客,最近指标压力大,没去摸索算法,今天写这个博客算是忙里偷闲吧,lightgbm的基本使用,python接口,这个工具微软开源的,号称比xgboost快,具体没怎么对比,先看看如何使用的. 安装编译...
  • 在Windows下安装LightGBM的Python包

    万次阅读 2016-12-22 15:12:20
    LightGBM是微软旗下DMTK推出的Gradient Boosting框架,因为其快速高效,以后或许会成为数据挖掘竞赛中的又一个大杀器。1.下载源代码git clone --recursive https://github.com/Microsoft/LightGBM2.编译DLL 进入...
  • lightGBM安装及入门
  • LightGBM处理imbalanced数据集

    万次阅读 2018-08-11 14:22:56
    在用LightGBM做分类器时如何处理样本类别分布不均衡的问题? 一个简单的方法是设置is_unbalance参数为True或者设置scale_pos_weight,二者只能选一个。 设置is_unbalance参数为True时会把负样本的权重设为:正样本...
  • lightgbm 特征重要性选择 / 看所有特征哪个重要

    万次阅读 热门讨论 2018-06-06 16:06:36
    print(pd.DataFrame({ 'column': feature_names, 'importance': lgb_trained_model.feature_importance(), }).sort_values(by='importance'))
  • 通过pip install lightgbm安装lightgbm成功,import lightgbm报错: ModuleNotFoundError: No module named ‘lightgbm’ 原因: lightgbm默认安装在本地python环境中,而anaconda的python路径与本地路径不同,不...
  • 本文是一个关于LightGBM的安装教程。 在使用LightGBM的时候要先编译一下,windows的玩家可以略过这步,我这里上传一个已经编译好的版本。大家自行下载,然后按照下面的教程,几步就可以完成安装(不超过5分钟) 第...
  • lightgbm 使用经验总结教训】

    万次阅读 2019-12-28 20:50:54
    做快手公司举办的2018中国高校计算机大赛--大数据...我怀疑的是特征的问题,但是今天6月13日,我仔细看了lightgbm算法的说明文档后才发现,我用的earlystopping方法一直没有用迭代最好的那一次去预测,即这个 同...
  • lightgbm参数说明

    万次阅读 2018-01-17 11:23:45
    关于lightgbm params的说明 # 配置目标是用于训练 task = train # 训练方式 boosting_type = gbdt #目标 二分类 objective = binary # 损失函数 metric = binary_logloss,auc # frequence ...
1 2 3 4 5 ... 20
收藏数 5,827
精华内容 2,330
关键字:

lightgbm