赞
踩
我已经使用lightGBM一段时间了。这是我解决大多数结构化数据问题的首选算法。令人敬畏的功能列表很长,如果您还没有,我建议您看一下。
但我一直很想了解哪些参数对性能影响最大,以及我应该如何调整 lightGBM 参数以充分利用它。
我想我应该做一些研究,更多地了解 lightGBM 参数……并分享我的旅程。
具体我:
深入研究LightGBM 的文档
自己做了一些实验
在这样做的过程中,我获得了更多关于 lightGBM 参数的知识。我希望阅读本文后您能够回答以下问题:
LightGBM 中实现了哪些 Gradient Boosting 方法,它们有什么区别?
通常哪些参数很重要?
需要调整哪些正则化参数?
如何在 python 中调整 lightGBM 参数?
使用 LightGBM,您可以运行不同类型的梯度提升方法。您有:GBDT、DART 和 GOSS,它们可以用boosting参数指定。
在接下来的部分中,我将对这些方法进行解释和比较。
这种方法是论文首次提出的传统梯度提升决策树,是 XGBoost 和 pGBRT 等一些优秀库背后的算法。
如今,gbdt 由于其准确性、效率和稳定性而被广泛使用。您可能知道 gbdt 是决策树的集成模型,但它到底是什么意思呢?
它基于三个重要原则:
弱学习者(决策树)
梯度优化
升压技术
所以在 gbdt 方法中我们有很多决策树(弱学习者)。这些树是按顺序构建的:
第一棵树学习如何适应目标变量
第二棵树学习如何适应第一棵树的预测与地面实况之间的残差(差异)
第三棵树学习如何拟合第二棵树的残差,依此类推。
所有这些树都是通过在整个系统中传播错误梯度来训练的。
gbdt 的主要缺点是在每个树节点中找到最佳分割点是一项耗时且耗内存的操作,其他提升方法试图解决该问题。
在这篇出色的论文中,您可以了解有关 DART 梯度提升的所有内容,这是一种使用神经网络中的标准 dropout 来改进模型正则化并处理其他一些不太明显的问题的方法。
也就是说,gbdt 存在过度专业化的问题,这意味着在后期迭代中添加的树往往只会影响少数实例的预测,而对其余实例的贡献可以忽略不计。添加 dropout 会使树在以后的迭代中更难专注于那些少数样本,从而提高性能。
事实上,将这种方法命名为lightgbm最重要的原因是使用了基于这篇论文的Goss方法。Goss 是更新更轻的 gbdt 实现(因此是“light”gbm)。
标准 gbdt 是可靠的,但在大型数据集上速度不够快。因此,goss 提出了一种基于梯度的采样方法,以避免搜索整个搜索空间。我们知道,对于每个数据实例,当梯度很小时,这意味着不用担心数据训练得很好,而当梯度很大时,应该再次重新训练。所以我们这里有两个方面,具有大梯度和小梯度的数据实例。因此,goss 将所有数据都保留为大梯度,并在具有小梯度的数据上进行随机采样(这就是它称为单侧采样的原因)。这使得搜索空间更小,goss 可以更快地收敛。
让我们将这些差异放在表格中:
方法 | 笔记 | 需要更改这些参数 | 优势 | 坏处 |
Lgbm gbdt | 它是默认的提升类型 | 因为 gbdt 是 lgbm 的默认参数,所以您不必为它更改其余参数的值(仍然必须进行调整!) | 稳定可靠 | 过度专业化、耗时、耗内存 |
Lgbm dart | 尝试解决 gbdt 中的过度专业化问题 | drop_seed:选择丢弃模型的随机种子Uniform_dro:如果你想使用统一dropxgboost_dart_mode:设置为true,如果你想使用xgboost dart modeskip_drop:在提升迭代期间跳过dropout过程的概率max_dropdrop_rate:dropout率:在 dropout 期间要丢弃的先前树的一小部分 | 更好的准确性 | 太多的设置 |
Lgbm goss | goss 为 GBDT 提供了一种新的采样方法,将那些具有较大梯度的实例分开 | top_rate:大梯度数据的保留率other_rate:小梯度数据的保留率 | 更快收敛 | 数据集较小时过度拟合 |
笔记:
如果您将提升设置为 RF,那么 lightgbm 算法将表现为随机森林而不是提升树!根据文档,要使用 RF,您必须使用小于 1 的 bagging_fraction 和 feature_fraction。
在本节中,我将介绍 lightgbm 的一些重要正则化参数。显然,这些是您需要调整以对抗过度拟合的参数。
您应该知道,对于小型数据集(<10000 条记录),lightGBM 可能不是最佳选择。调整 lightgbm 参数可能对您没有帮助。
另外,lightgbm使用leaf-wise tree growth算法,而XGBoost使用depth-wise tree growth。Leaf-wise 方法允许树更快地收敛,但过度拟合的机会增加。
笔记:
如果有人问你 LightGBM 和 XGBoost 的主要区别是什么?您可以轻松地说,它们的区别在于它们的实现方式。
根据lightGBM 文档,当面临过度拟合时,您可能需要进行以下参数调整:
使用小的 max_bin
使用小的 num_leaves
使用 min_data_in_leaf 和 min_sum_hessian_in_leaf
通过设置 bagging_fraction 和 bagging_freq 使用 bagging
通过设置 feature_fraction 使用特征子采样
使用更大的训练数据
尝试 lambda_l1、lambda_l2 和 min_gain_to_split 进行正则化
尝试 max_depth 以避免生长深树
在接下来的部分中,我将更详细地解释每个参数。
Lambda_l1(和 lambda_l2)控制 l1/l2 并与 min_gain_to_split 一起用于对抗过度拟合。我强烈建议您使用参数调整(在后面的部分中探讨)来找出这些参数的最佳值。
当然,num_leaves是控制模型复杂性的最重要参数之一。使用它,您可以设置每个弱学习器拥有的最大叶子数。大的 num_leaves 增加了训练集的准确性,也增加了因过度拟合而受伤的机会。根据文档,一种简单的方法是num_leaves = 2^(max_depth)但是,考虑到在 lightgbm 中,逐叶树比逐层树更深,您需要小心过度拟合!因此,有必要一起调整num_leaves和max_depth 。
使用subsample(或 bagging_fraction),您可以指定每次树构建迭代使用的行的百分比。这意味着将随机选择一些行来适合每个学习者(树)。这提高了泛化能力,也提高了训练速度。
我建议对基线模型使用较小的子样本值,然后在完成其他实验(不同的特征选择、不同的树结构)后增加该值。
Feature fraction或 sub_feature 处理列采样,LightGBM 将在每次迭代(树)上随机选择一个特征子集。例如,如果将其设置为 0.6,则 LightGBM 会在训练每棵树之前选择 60% 的特征。
此功能有两种用法:
可用于加速训练
可用于处理过拟合
此参数控制每棵训练树的最大深度,并将影响:
num_leaves 参数的最佳值
模型性能
训练时间
注意如果您使用较大的max_depth值,您的模型可能会过度拟合 训练集。
分箱是一种以离散视图(直方图)表示数据的技术。Lightgbm 使用基于直方图的算法在创建弱学习器的同时找到最佳分割点。因此,每个连续的数字特征(例如视频的观看次数)应该被分成离散的容器。
此外,在这个GitHub repo 中,您可以找到一些全面的实验,这些实验完全解释了更改 max_bin 对 CPU 和 GPU 的影响。
500 次迭代后的时钟时间 – GitHub 存储库
如果您将 max_bin 定义为 255,这意味着每个特征最多可以有 255 个唯一值。然后小的 max_bin 导致更快的速度和大的值提高准确性。
训练时间!当您想使用 lightgbm 训练模型时,训练 lightgbm 模型时可能会出现的一些典型问题是:
培训是一个耗时的过程
处理计算复杂性(CPU/GPU RAM 限制)
处理分类特征
有一个不平衡的数据集
需要自定义指标
需要针对分类或回归问题进行的调整
在本节中,我们将尝试详细解释这些要点。
Num_iterations 指定提升迭代次数(要构建的树)。您构建的树越多,您的模型就越准确,但代价是:
更长的训练时间
过度拟合的可能性更高
从较少数量的树开始构建基线,然后在您想要从模型中挤出最后 一部分 时增加它。
建议使用较小的learning_rate和较大的num_iterations。此外,如果你想要更高的 num_iterations 停止你的训练,你应该使用 early_stopping_rounds 当它没有学到任何有用的东西时。
如果验证指标在最后一轮提前停止后没有改善,则此参数将停止训练。这应该与一些迭代一起定义。如果你将它设置得太大,你会增加过度拟合的机会(但你的模型可以更好)。
经验法则是将其设置为 num_iterations 的 10%。
使用 lightgbm 的优点之一是它可以很好地处理分类特征。是的,这个算法非常强大,但你必须小心如何使用它的参数。lightgbm 使用一种特殊的整数编码方法来处理分类特征
实验表明,这种方法比经常使用的one-hot encoding带来更好的性能。
它的默认值是“auto”,这意味着:让 lightgbm 决定 lightgbm 将推断哪些特征是分类的。
它并不总是很好用(一些实验说明了为什么在这里和这里),我强烈建议您使用这段代码手动设置分类特征
cat_col = dataset_name.select_dtypes('object').columns.tolist()
但是幕后发生了什么以及 lightgbm 如何处理分类特征?
根据lightgbm 的文档,我们知道树学习器不能很好地使用一种热编码方法,因为它们在树中深入生长。在所提出的替代方法中,树学习器是最佳构造的。例如,对于具有 k 个不同类别的一个特征,有 2^(k-1) – 1 个可能的分区,并且使用fisher方法可以 通过在排序的值直方图上找到最佳分割方式来改进到k * log(k)在分类特征中。
在二进制分类问题中,您可能面临的问题之一是如何处理不平衡的数据集。显然,您需要平衡正/负样本,但在 lightgbm 中您究竟如何做到这一点?
lightgbm 中有两个参数可以让你处理这个问题is_unbalance 和 scale_pos_weight,但是它们之间有什么区别以及如何使用它们?
当您设置 Is_unbalace: True 时,该算法将尝试自动平衡主导标签的权重(与训练集中的正/负分数)
sample_pos_weight = 负样本数/正样本数
有时你想定义一个自定义评估函数来衡量你的模型的性能,你需要创建一个feval函数。
Feval 函数应该接受两个参数:
预测值
训练数据
并返回
评估名称
评估结果
is_higher_better
让我们逐步创建自定义指标函数。
定义一个单独的python函数
- def feval_func(preds, train_data):
- # 定义一个计算结果的公式
- return ('feval_func_name', eval_result, False)
使用此函数作为参数:
- print('Start training...')
- lgb_train = lgb.train(...,
- metric=None,
- feval=feval_func)
笔记:
要使用 feval 函数而不是 metric,您应该将 metric 参数设置为“None”。
我之前提到的大多数事情对于分类和回归都是正确的,但有些事情需要调整。
具体来说,你应该:
参数名称 | 分类说明 | 回归注意事项 |
objective | 将其设置为二进制或多类 | 设置回归 |
metric | Binary_logloss 或 AUC 等。 | RMSE 或 mean_absolute_error 等。 |
is_unbalance | 对或错 | – |
scale_pos_weight | 仅用于二进制和多类应用程序 | – |
num_class | 仅用于多类分类应用 | – |
reg_sqrt | – | 用于拟合 sqrt(label) 而不是大范围标签的原始值 |
我们在前面的部分中回顾并了解了一些关于 lightgbm 参数的知识,但是没有提到 Laurae 的令人难以置信的基准测试,任何增强树文章都不会完整
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。