LightGBM 调参


一、LightGBM简介

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

  1)更快的训练效率
  2)低内存使用
  3)更高的准确率
  4)支持并行化学习
  5)可以处理大规模数据


  在讨论LightGBM时,不可避免的会提到XGboost,关于XGboost的不足之处主要有:

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

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

二、LightGBM原理

2.1 直方图算法

  直方图算法的基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。在XGBoost中需要遍历所有离散化的值,而在这里只要遍历k个直方图的值。
在这里插入图片描述
  使用直方图算法有很多优点。首先,最明显就是内存消耗的降低,直方图算法不仅不需要额外存储预排序的结果,而且可以只保存特征离散化后的值。
在这里插入图片描述
  然后在计算上的代价也大幅降低,XGBoost预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算k次(k可以认为是常数),时间复杂度从O(#data * #feature) 优化到O(k* #features)。
  当然,Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在不同的数据集上的结果表明,离散化的分割点对最终的精度影响并不是很大,甚至有时候会更好一点。原因是决策树本来就是弱模型,分割点是不是精确并不是太重要;较粗的分割点也有正则化的效果,可以有效地防止过拟合;即使单棵树的训练误差比精确分割的算法稍大,但在梯度提升(Gradient Boosting)的框架下没有太大的影响。

2.2 LightGBM的直方图做差加速

  一个容易观察到的现象:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的k个桶。利用这个方法,LightGBM可以在构造一个叶子的直方图后(父节点在上一轮就已经计算出来了),可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。
在这里插入图片描述

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

  Level-wise过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。
在这里插入图片描述
  Leaf-wise则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。
在这里插入图片描述

level_wise:多线程优化,控制模型复杂度,不易过拟合。
leaf-wise:计算代价较小,更精确,易过拟合(map_depth)。


3.4 直接支持类别特征(即不需要做one-hot编码)

  实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化到多维的one-hot编码特征,降低了空间和时间的效率。而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的one-hot编码展开。并在决策树算法上增加了类别特征的决策规则。在Expo数据集上的实验,相比0/1展开的方法,训练速度可以加速8倍,并且精度一致。

3.5 直接支持高效并行

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

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

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

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

使用场景:

特征并行:数据量小,但特征数量多;
数据并行:数据量较大,特征数量少;
投票并行:数据量大,特征数量多。

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

三、梯度提升的方法

  使用LightGBM,你可以运行不同类型的渐变增强提升方法。你有:GBDT、DART和GOSS,这些可以通过“boosting”参数指定。

3.1 梯度提升决策树(GBDT)

  该方法是传统梯度提升决策树,也是XGBoost和pGBRT等优秀库背后的算法。但由于其精度高、效率高、稳定性好,目前已得到广泛的应用。

  梯度提升决策树(GBDT)基于三个重要原则:

1、弱学习者(决策树)
2、梯度优化
3、提升技术

所以在gbdt方法中,我们有很多决策树(弱学习者)。这些树是按顺序构建的:

首先,第一棵树学习如何适应目标变量
第二棵树学习如何适合残差(差异)之间的预测,第一棵树和地面真相
第三棵树学习如何匹配第二棵树的残差,以此类推。

  所有这些树都是通过传播整个系统的误差梯度来训练的。

  gbdt的主要缺点是,在每个树节点中找到最佳分割点非常耗时,而且会消耗内存。其他的提升方法试图解决这个问题。

3.2 DART 梯度提升

  DART梯度提升数,是使用dropout(神经网络中的标准)的方法,来改进模型正则化和处理一些其他不太明显的问题。
  也就是说,gbdt存在过度专门化(over-specialization)的问题,这意味着在以后的迭代中添加的树往往只会影响对少数实例的预测,而对其余实例的贡献则可以忽略不计。添加dropout会使树在以后的迭代中更加难以专门化那些少数的示例,从而提高性能。

3.3 lgbm goss 基于梯度的单边采样

  标准的gbdt是可靠的,但在大型数据集上速度不够快。因此goss提出了一种基于梯度的采样方法来避免搜索整个搜索空间。我们知道,对于每个数据实例,当梯度很小时,这意味着不用担心数据是经过良好训练的,而当梯度很大时,应该重新训练。这里我们有两个方面,数据实例有大的和小的渐变。因此,goss以一个大的梯度保存所有数据,并对一个小梯度的数据进行随机抽样(这就是为什么它被称为单边抽样)。这使得搜索空间更小,goss的收敛速度更快

四、参数解释

Control Parameters(控制参数)含义用法
max_depth树的最大深度默认-1,无限制;当模型过拟合时,可以考虑首先降低 max_depth
num_leaves树的叶子数目默认31,取值应 <= 2 ^(max_depth), 超过此值会导致过拟合
min_data_in_leaf叶子最小记录数默认20,小于设置时不再分裂,过拟合时用
feature_fraction特征抽样,例如 为0.8时,意味着在每次迭代中随机选择80%的参数来建树默认为1, boosting 为 random forest 时用
bagging_fraction数据抽样默认1,用于加快训练速度和减小过拟合
bagging_freqbagging的频率,k意味着每k次迭代执行bagging默认0
early_stopping_round如果一次验证数据的一个度量在最近的early_stopping_round 回合中没有提高,模型将停止训练加速分析,减少过多迭代
lambda,正则化参数默认0,0~1
min_gain_to_split描述分裂的最小增益,小于该值不再分裂默认0,控制树的有用的分裂
max_cat_group在 group 边界上找到分割点当类别数量很多时,找分割点很容易过拟合时
num_iterations指定增强迭代的次数(要构建的树) 。建立的树越多,你的模型就越精确,代价是:较长的训练时间和过拟合的可能性更高。默认100,建议使用更小的learning_rate和更大的num_iteration。此外,如果您想要更高的num_iteration,那么您应该使用early_stopping_rounds,以便在无法学习任何有用的内容时停止训练。
early_stopping_rounds度量标准没有改善时停止训练如果验证度量在最后一轮停止后没有改进,此参数将停止训练。这应该与一些迭代成对地进行定义。如果你把它设置得太大,你就增加了过拟合的变化(但你的模型可以更好)。经验法则是让它占num_iterations的10%。
categorical_feature处理分类特征方法该方法比常用的单热编码方法具有更好的性能。默认值是“auto”,意思是:让lightgbm决定哪个表示lightgbm将推断哪些特性是绝对的。它并不总是工作得很好,可手动设置分类特性
tree-learner并行方式默认serial
max_bin最大bin数量默认255
max_bin_by_feature按特征设置bin数目
min_data_in_binbin内最少数据量3
pos_bagging_fraction正例抽样1
neg_bagging_fraction负例抽样1

Core Parameters(核心参数)含义用法
Task数据的用途默认train,选择 train 或者 predict
application模型的用途选择 regression: 回归时,binary: 二分类时,multiclass: 多分类时
boosting要用的算法默认gbdt, 随机森林: rf: random forest, dart: Dropouts meet Multiple Additive Regression Trees, goss: Gradient-based One-Side Sampling
objective目标函数默认回归regression;可选二分类:‘binary’,多分类:‘multiclass’,同时需设置类别数 class
num_boost_round迭代次数通常 100+
learning_rate如果一次验证数据的一个度量在最近的 early_stopping_round 回合中没有提高,模型将停止训练默认0.1,常用 0.1, 0.001, 0.003…
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
is_unbalance正负样本是否平衡True or False,True时,算法将尝试自动平衡占主导地位的标签的权重
scale_pos_weight正负样本权重默认情况下是1,这意味着假设正负标签都是相等的),在不平衡数据集的情况下,您可以使用以下公式来正确地设置它:sample_pos_weight = number of negative samples / number of positive samples

自定义度量函数:

def feval_func(preds, train_data):
   # Define a formula that evaluates the results
    return ('feval_func_name', eval_result, False)

#要使用feval函数代替度量,您应该设置度量参数 metric “None”。
print('Start training...')
lgb_train = lgb.train(..., 
                      metric=None, 
                      feval=feval_func)

五、调参步骤

  
LightGBM的调参过程和RF、GBDT等类似,其基本流程如下:

1、首先选择较高的学习率,大概0.1附近,这样是为了加快收敛的速度。这对于调参是很有必要的。
2、对决策树基本参数调参:
  2.1 max_depth和num_leaves
  2.2 min_data_in_leaf和min_sum_hessian_in_leaf
  2.3 feature_fraction和bagging_fraction
3、正则化参数调参
4、最后降低学习率,这里是为了最后提高准确率

  下表对应了不同情况下,参数如何调整。 Faster Speed ,better accuracy ,over-fitting 三种目的时,可以调的参数

Faster Speed(速率快)better accuracy(最好正确率)over-fitting(过拟合)
将 max_bin 设置小一些用较大的 max_binmax_bin 小一些
num_leaves 大一些num_leaves 小一些
用 feature_fraction 来做 sub-sampling用 feature_fraction
用 bagging_fraction 和 bagging_freq设定 bagging_fraction 和 bagging_freq
training data 多一些training data 多一些
用 save_binary 来加速数据加载直接用 categorical feature用 gmin_data_in_leaf 和 min_sum_hessian_in_leaf
用 parallel learning用 dart用 lambda_l1, lambda_l2 ,min_gain_to_split 做正则化
num_iterations 大一些,learning_rate 小一些用 max_depth 控制树的深度

5.1 原生实例

import lightgbm as lgb
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
 
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)
 
# 创建成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 显示信息
}
 
# 训练 cv and train
gbm = lgb.train(params, lgb_train, num_boost_round=20, valid_sets=lgb_eval, early_stopping_rounds=5)
 
# 保存模型到文件
gbm.save_model('model.txt')
 
# 预测数据集
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)

5.2 sklearn接口实例

import lightgbm as lgb
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
 
# 加载数据
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)
 
# 创建模型,训练模型
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)
 
# 测试集预测
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_)

原生API与sklearnAPI接口区别总结

  需要注意以下几点:

1、多分类时lgb.train除了’objective’:‘multiclass’,还要指定"num_class":5,而sklearn接口只需要指定’objective’:‘multiclass’。
2、lgb.train中正则化参数为"lambda_l1", “lambda_l2”,sklearn中则为’reg_alpha’, ‘reg_lambda’。
3、迭代次数在sklearn中是’n_estimators’:300,在初始化模型时指定。而在lgb.train中则可在参数params中指定,也可在函数形参中指出。


参考:
https://www.cnblogs.com/jiangxinyang/p/9337094.html
https://blog.csdn.net/qq_24591139/article/details/100085359
https://blog.csdn.net/qq_41940950/article/details/100061562
https://www.cnblogs.com/webRobot/p/10019448.html

在Python中进行LightGBM调参可以通过设置一系列参数来实现。首先,可以调整学习率和估计器的数目。学习率(learning_rate)控制每个估计器对于前一个估计器的权重。较小的学习率可以使模型更加稳定,但可能需要更多的估计器来达到最佳性能。估计器的数目(num_estimators)表示要使用的决策树的数量,较大的数目可能会增加模型的复杂度。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [LightGBM调参](https://blog.csdn.net/weixin_41917143/article/details/110421742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [提升机器算法LightGBM(图解+理论+增量训练python代码+lightGBM调参方法)](https://blog.csdn.net/lamusique/article/details/95631638)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [LightGBM 如何调参](https://blog.csdn.net/weixin_44116269/article/details/103269604)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值