LightGBM是个什么东东?好像很耳熟啊,怎么玩啊?如何调参?一文搞定!

点击上方“AI公园”,关注公众号,选择加“星标“或“置顶”


作者:Pushkar Mandot

编译:ronghuaiyang


前戏

前几天分享了几篇梯度提升算法,随机森林相关的文章,大家很喜欢,反馈也很好,那么今天再接再厉,给大家带来一篇LightGBM的文章,既有梯度提升,又有随机森林,这可是个神器,号称Kaggle必备!不过大家去看官方文档的话,估计会被几百个参数吓尿。其实没那么复杂,看完你就明白了!


机器学习是世界上发展最快的领域。每天都会出现大量的新算法,有些不怎么样,有些非常成功。我正在接触一个非常成功的机器学习算法,LightGBM。

写这篇博客的初衷是什么?

当我在做Kaggle比赛的时候,我用过很多的强大的算法,LightGBM是其中之一。LightGBM算法相等的新,网上也没有什么相关的资源。对于初学者来说,很难从文档中长长的列表中选择合适的参数。为了帮助新人,我来写这个博客。

我尽量让这个博客简短,太多的信息会把你绕晕的。

LightGBM是什么?

LightGBM是一个梯度提升框架,使用基于树的学习算法。

和其他的基于树的算法有什么不同?

LightGBM树的生长方式是垂直方向的,其他的算法都是水平方向的,也就是说Light GBM生长的是树的叶子,其他的算法生长的是树的层次。LightGBM选择具有最大误差的树叶进行生长,当生长同样的树叶,生长叶子的算法可以比基于层的算法减少更多的loss。

下面的图解释了LightGBM和其他的提升算法的实现。

640?wx_fmt=png

Explains how LightGBM works

640?wx_fmt=png

How other boosting algorithm works

为什么LightGBM这么受欢迎?

数据的数量每天都在增加,对于传统的数据科学算法来说,很难快速的给出结果。LightGBM的前缀‘Light’表示速度很快。LightGBM可以处理大量的数据,运行时占用很少的内存。另外一个理由,LightGBM为什么这么受欢迎是因为它把重点放在结果的准确率上。LightGBM还支持GPU学习,因此,数据科学家广泛的使用LightGBM来进行数据科学应用的部署。

我们可以不管什么地方都用LightGBM吗?

不可以!不建议在小数据集上使用LightGBM。LightGBM对过拟合很敏感,对于小数据集非常容易过拟合。对于多小属于小数据集,并没有什么阈值,但是从我的经验,我建议对于10000+以上的数据的时候,再使用LightGBM。

我们简单的讨论了一下LightGBM的概念,现在,如何实现?

实现LightGBM非常简单,复杂的是参数的调试。LightGBM有超过100个参数,但是不用担心,你不需要所有的都学。

对于实现的人来说,知道一些基本的参数是非常重要的。如果仔细的过一遍LightGBM的参数,你会发现这个强大的算法就是小菜一碟。

我们开始讨论参数。

参数

控制参数

maxdepth: 描述了树的最大深度。这个参数用来处理过拟合问题。一旦你发现你的模型过拟合了,首先就是减小maxdepth。

mindatain_leaf: 一个树叶上可以有的数据的最小数量。默认是20,最优值。也是用来处理过拟合。

feature_fraction: 在你的提升方法是随机森林的时候用。0.8 feature fraction表示每个迭代,LightGBM会随机选择80%的参数来构建树。

bagging_fraction: 指定每个迭代用的数据的比例,通常用来加速训练,防止过拟合。

earlystoppinground: 这个参数帮助你加速分析。如果一个验证集上的一个评估方法在earlystoppinground数量的几轮中没有提升,就会减掉过多的迭代。

lambda: 正则化的参数,从0~1。

mingainto_split: 这个参数表示进行树的分裂时,最小的增长,可以用来控制树中有用的分裂的数量。

maxcatgroup: 当类别的数量很大,找到分裂点非常容易过拟合。所以,LightGBM将它们合并成 ‘maxcatgroup’ 组,找到组的分裂点进行分裂,默认:64。

核心参数

Task: 指定了需要在数据上做的任务,训练或者是预测。

application: 这是最重要的参数,指定了你的模型的应用,回归或者是分类。LightGBM默认是回归模型。

  • regression: 回归

  • binary: 二元分类

  • multiclass: 多类分类

boosting: 定义了你想要运行的算法的类型,默认是gdbt

  • gbdt: 传统的梯度提升树

  • rf: 随机森林

  • dart: 使用dropout的多重回归树相加

  • goss: 基于梯度的单边采样

numboostround: 提升的迭代数量,一般100+

learning_rate: 这个影响每棵树的最终的结果。GBM 的利用每一棵树的输出得到初始预测,然后开始迭代,学习率控制了预测的变化的大小程度,典型值:0.1, 0.001, 0.003…

num_leaves: 完整数的叶子的数量,默认:31

device: 默认:cpu,也可以传入gpu

度量参数

metric: 也是一个非常重要的参数,指定了模型的损失函数。下面是几种常用的回归和分类的损失函数。

  • mae: 绝对值平均误差

  • mse: 均方误差

  • binary_logloss: 二元分类对数损失

  • multi_logloss:多分类对数损失

输入输出参数

max_bin: 表示特征被分箱的最大数量。

categoricalfeature: 表示类别特征的索引。如果categoricalfeatures=0,1,2 ,那么第0列,第1列,第2列都是类别变量。

ignorecolumn: 和categoricalfeatures一样,不过不是认为是类别变量,而是完全忽略。

save_binary: 如果你的数据量对于你的内存来说太大了,将这个参数设为‘True’。这样可以将你的数据集存为二进制文件,这个二进制文件下次读的时候,会节省很多时间。

了解和使用上面的参数一定会有助于与你实现这个模型。记住我说的,实现LightGBM很容易,调试很难。所以,第一步先实现它,然后我会教你如何调试参数。

实现

安装LGBM:

安装LightGBM很重要。我发现这里是教你如何安装的最好的资源。

我使用Anaconda安装LightGBM,只要运行下面的命令就可以了。

conda install -c conda-forge lightgbm

数据集:

这个数据集很小,只有400行,5列(专门是学习用的)。这是个分类问题,我们预测用户是否会购买网站上给的广告中的商品。我就不解释这个数据集了,非常简单。你可以从这里下载数据集。

注意:这个数据集是清洗过的,没有确实数据。选这个小数据集的主要的目的是让事情简单明了。

我假设你有基础的python知识。过一遍数据预处理阶段,非常的简单。

数据预处理:

import numpy as np	
import matplotlib.pyplot as plt	
import pandas as pd	
# Importing the dataset	
dataset = pd.read_csv('...input\\Social_Network_Ads.csv')	
X = dataset.iloc[:, [2, 3]].values	
y = dataset.iloc[:, 4].values	
# Splitting the dataset into the Training set and Test set	
from sklearn.cross_validation import train_test_split	
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)	
# Feature Scaling	
from sklearn.preprocessing import StandardScaler	
sc = StandardScaler()	
x_train = sc.fit_transform(x_train)	
x_test = sc.transform(x_test)

模型构建和训练:

我们需要将我们的训练数据转换成LightGBM的数据集格式,这是强制的要求。

数据集转换完成之后,我用参数和对应的值创建一个python字典。你的模型的准确率依赖于你提供的这些参数。

在代码最后,我简单的训练100个迭代。

import lightgbm as lgb	
d_train = lgb.Dataset(x_train, label=y_train)	
params = {}	
params['learning_rate'] = 0.003	
params['boosting_type'] = 'gbdt'	
params['objective'] = 'binary'	
params['metric'] = 'binary_logloss'	
params['sub_feature'] = 0.5	
params['num_leaves'] = 10	
params['min_data'] = 50	
params['max_depth'] = 10	
clf = lgb.train(params, d_train, 100)

几个参数中需要注意的事情:

  • 使用‘binary’ 作为目标(这是个二分类问题)

  • 使用 ‘binary_logloss’ 作为度量(这是个二分类问题)

  • ‘num_leaves’=10 (这是个小数据集)

  • ‘boosting type’ 是gbdt, 我们实现的是梯度提升算法(你也可以试试随机森林)

模型预测:

我们一行代码就可以进行预测。

输出的是一个概率的列表。我使用threshold=0.5将概率转换为二分类预测。

#Prediction	
y_pred=clf.predict(x_test)	
#convert into binary values	
for i in range(0,99):	
    if y_pred[i]>=.5:       # setting threshold to .5	
       y_pred[i]=1	
    else:  	
       y_pred[i]=0

结果:

我可以使用混淆矩阵或者直接计算准确率来查看结果。

代码:

#Confusion matrix	
from sklearn.metrics import confusion_matrix	
cm = confusion_matrix(y_test, y_pred)	
#Accuracy	
from sklearn.metrics import accuracy_score	
accuracy=accuracy_score(y_pred,y_test)

结果截图:

640?wx_fmt=png

混淆矩阵

640?wx_fmt=png

准确率

你们许多人可能会想,我用这么小的数据集,准确率还有92%,为什么没有过拟合?原因很简单,我调试了模型参数。

现在,我们开始进入调参。

调参:

数据科学家在使用参数的时候,总是很挣扎。理想的参数应该长什么样呢?

下面的一组练习可以用来提升你的模型效率。

  1. num_leaves: 这个是控制树的复杂度的主要的参数。理想情况下,叶子的数量的值应该小于等于 $2^{max_depth}$,大于这个值会导致过拟合。

  2. mindatain_leaf: 设置成一个比较大的值可以避免树生长太深,但是可能会导致过拟合。实际使用中,对于大数据集设置成几百到几千就足够了。

  3. maxdepth: 你可以使用maxdepth来显式的限制深度。

追求速度:

  • 通过设置 bagging_fraction 和 bagging_freq来使用bagging

  • 通过设置 feature_fraction来使用特征下采样

  • 使用小的 max_bin

  • 使用 save_binary 来加速加载数据

  • 使用并行学习,参考parallel learning guide

追求更高的准确率:

  • 使用大的 max_bin (可能速度会慢)

  • 使用小 learning_rate 大的 num_iterations

  • 使用大的 num_leaves(可能会过拟合)

  • 使用大训练数据集

  • 试试 dart

  • 尝试直接使用类别特征

处理过拟合:

  • 使用小的 max_bin

  • 使用小的 num_leaves

  • 使用 min_data_in_leaf 和 min_sum_hessian_in_leaf

  • 通过设置 bagging_fraction 和 bagging_freq来使用bagging

  • 通过设置 feature_fraction来使用特征下采样`

  • 使用大训练数据集

  • 尝试使用 lambda_l1lambda_l2 和 min_gain_to_split 来进行正则化

  • 尝试使用 max_depth 来避免生成的树太深

结论:

我在好几个数据集上都用过LightGBM,发现它的准确率相比其他的提升算法还是比较好的。从我的经验来看,我建议你至少试一次这个算法。

英文原文链接:https://medium.com/@pushkarmandot/https-medium-com-pushkarmandot-what-is-lightgbm-how-to-implement-it-how-to-fine-tune-the-parameters-60347819b7fc

640?wx_fmt=png

往期精彩回顾

1、最全的AI速查表|神经网络,机器学习,深度学习,大数据

2、资源|10个机器学习和深度学习的必读免费课程

3、经验之谈|别再在CNN中使用Dropout了

4、我们从region based物体检测器 (Faster R-CNN, R-FCN, FPN)中能学到些什么?

5、我们从一阶段的物体检测器SSD,YOLOv3,FPN & Focal loss (RetinaNet)中学到了什么?

6、Python代码实践|随机森林是“黑盒子”?不存在的,撸完代码你就懂了

7、非常好用的Python图像增强工具,适用多个框架

8、算法理解|从头开始理解梯度提升算法

9、在深度学习中处理不均衡数据集

10、经验之谈|处理不平衡数据集的7个技巧


本文可以任意转载,转载时请注明作者及原文地址

640?wx_fmt=jpeg

请长按或扫描二维码关注本公众号


640?wx_fmt=png

请帮忙点击下方的广告,这么大冷的天,每天晚上写公众号,都累瘦了,各位就当是给我加点营养了,点击一下,然后关掉就行,谢谢大家!

640?wx_fmt=png
  • 4
    点赞
  • 77
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

ronghuaiyang

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值