前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习实战 | LightGBM建模应用详解

机器学习实战 | LightGBM建模应用详解

原创
作者头像
ShowMeAI
发布2022-03-21 23:40:35
2.8K0
发布2022-03-21 23:40:35
举报
文章被收录于专栏:ShowMeAI研究中心

作者:韩信子@ShowMeAI

教程地址http://www.showmeai.tech/tutorials/41

本文地址http://www.showmeai.tech/article-detail/205

声明:版权所有,转载请联系平台与作者并注明出处

收藏ShowMeAI查看更多精彩内容


引言

LightGBM是微软开发的boosting集成模型,和XGBoost一样是对GBDT的优化和高效实现,原理有一些相似之处,但它很多方面比XGBoost有着更为优秀的表现。

本篇内容ShowMeAI展开给大家讲解LightGBM的工程应用方法,对于LightGBM原理知识感兴趣的同学,欢迎参考ShowMeAI的另外一篇文章 **图解机器学习 | LightGBM模型详解**

1.LightGBM安装

LightGBM作为常见的强大Python机器学习工具库,安装也比较简单。

1.1 Python与IDE环境设置

python环境与IDE设置可以参考ShowMeAI文章 **图解python | 安装与环境设置** 进行设置。

1.2 工具库安装

(1) Linux/Mac等系统

这些系统下的XGBoost安装,大家只要基于pip就可以轻松完成了,在命令行端输入命令如下命令即可等待安装完成。

代码语言:text
复制
pip install lightgbm

大家也可以选择国内的pip源,以获得更好的安装速度:

代码语言:text
复制
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lightgbm

(2) Windows系统

对于windows系统而言,比较高效便捷的安装方式是:在网址http://www.lfd.uci.edu/~gohlke/pythonlibs/ 中去下载对应版本的的LightGBM安装包,再通过如下命令安装。

pip install lightgbm‑3.3.2‑cp310‑cp310‑win_amd64.whl

2.LightGBM参数手册

ShowMeAI的前一篇内容 **XGBoost工具库建模应用详解** 中,我们讲解到了Xgboost的三类参数通用参数,学习目标参数,Booster参数。而LightGBM可调参数更加丰富,包含核心参数,学习控制参数,IO参数,目标参数,度量参数,网络参数,GPU参数,模型参数,这里我常修改的便是核心参数,学习控制参数,度量参数等。下面我们对这些模型参数做展开讲解,更多的细节可以参考LightGBM中文文档

2.1 参数介绍

(1) 核心参数

  • config或者config\_file:一个字符串,给出了配置文件的路径。默认为空字符串。
  • task:一个字符串,给出了要执行的任务。可以为:
  • train或者training:表示是训练任务。默认为train
  • predict或者prediction或者test:表示是预测任务。
  • convert\_model:表示是模型转换任务。将模型文件转换成if-else格式。
  • application或者objective或者app:一个字符串,表示问题类型。可以为:
  • regressionregression\_l2mean\_squared\_errormsel2\_rootroot\_mean\_squred\_errorrmse:表示回归任务,但是使用L2损失函数。默认为regression
  • regression\_l1或者mae或者mean\_absolute\_error:表示回归任务,但是使用L1损失函数。
  • huber:表示回归任务,但是使用huber损失函数。
  • fair:表示回归任务,但是使用fair损失函数。
  • poisson:表示Poisson回归任务。
  • quantile:表示quantile回归任务。
  • quantile\_l2:表示quantile回归任务,但是使用了L2损失函数。
  • mape或者mean\_absolute\_precentage\_error:表示回归任务,但是使用MAPE损失函数
  • gamma:表示gamma回归任务。
  • tweedie:表示tweedie回归任务。
  • binary:表示二分类任务,使用对数损失函数作为目标函数。
  • multiclass:表示多分类任务,使用softmax函数作为目标函数。必须设置num\_class参数
  • multiclassova或者multiclass\_ova或者ova或者ovr:表示多分类任务,使用one-vs-all的二分类目标函数。必须设置num\_class参数。
  • xentropy或者cross\_entropy:目标函数为交叉熵(同时具有可选择的线性权重)。要求标签是0,1之间的数值。
  • xentlambda或者cross\_entropy\_lambda:替代了参数化的cross\_entropy。要求标签是0,1之间的数值。
  • lambdarank:表示排序任务。在lambdarank任务中,标签应该为整数类型,数值越大表示相关性越高。label\_gain参数可以用于设置整数标签的增益(权重)。
  • boosting或者boost或者boosting\_type:一个字符串,给出了基学习器模型算法。可以为:
  • gbdt:表示传统的梯度提升决策树。默认值为gbdt
  • rf:表示随机森林。
  • dart:表示带dropout的gbdt。
  • goss:表示Gradient-based One-Side Sampling 的gbdt。
  • data或者train或者train\_data:一个字符串,给出了训练数据所在的文件的文件名。默认为空字符串。LightGBM将使用它来训练模型。
  • valid或者test或者valid\_data或者test\_data:一个字符串,表示验证集所在的文件的文件名。默认为空字符串。LightGBM将输出该数据集的度量。如果有多个验证集,则用逗号分隔。
  • num\_iterations或者num\_iteration或者num\_tree或者num\_trees或者num\_round或者num\_rounds或者num\_boost\_round一个整数,给出了boosting的迭代次数。默认为100。
  • 对于Python/R包,该参数是被忽略的。对于Python,使用train()/cv()的输入参数num\_boost\_round来代替。
  • 在内部,LightGBM对于multiclass问题设置了num\_class\*num\_iterations棵树。
  • learning\_rate或者shrinkage\_rate:个浮点数,给出了学习率。默认为1。在dart中,它还会影响dropped trees的归一化权重。
  • num\_leaves或者num\_leaf:一个整数,给出了一棵树上的叶子数。默认为31。
  • tree\_learner或者tree:一个字符串,给出了tree learner,主要用于并行学习。默认为serial。可以为:
  • serial:单台机器的tree learne
  • feature:特征并行的tree learne
  • data:数据并行的tree learne
  • voting:投票并行的tree learne
  • num\_threads或者num\_thread或者nthread:一个整数,给出了LightGBM的线程数。默认为OpenMP\_default
  • 为了更快的速度,应该将它设置为真正的CPU内核数,而不是线程的数量(大多数CPU使用超线程来使每个CPU内核生成2个线程)。
  • 当数据集较小的时候,不要将它设置的过大。
  • 对于并行学习,不应该使用全部的CPU核心,因为这会使得网络性能不佳。
  • device:一个字符串,指定计算设备。默认为cpu。可以为gpucpu
  • 建议使用较小的max\_bin来获得更快的计算速度。
  • 为了加快学习速度,GPU默认使用32位浮点数来求和。你可以设置gpu\_use\_dp=True来启动64位浮点数,但是它会使得训练速度降低。

(2) 学习控制参数

  • max\_depth:一个整数,限制了树模型的最大深度,默认值为-1。如果小于0,则表示没有限制。
  • min\_data\_in\_leaf或者min\_data\_per\_leaf或者min\_data或者min\_child\_samples:一个整数,表示一个叶子节点上包含的最少样本数量。默认值为20。
  • min\_sum\_hessian\_in\_leaf或者min\_sum\_hessian\_per\_leaf或者min\_sum\_hessian或者min\_hessian或者min\_child\_weight:一个浮点数,表示一个叶子节点上的最小hessian之和。(也就是叶节点样本权重之和的最小值)默认为1e-3。
  • feature\_fraction或者sub\_feature或者colsample\_bytree:一个浮点数,取值范围为0.0,1.0,默认值为0。如果小于1.0,则LightGBM会在每次迭代中随机选择部分特征。如0.8表示:在每棵树训练之前选择80%的特征来训练。
  • feature\_fraction\_seed:一个整数,表示feature\_fraction的随机数种子,默认为2。
  • bagging\_fraction或者sub\_row或者subsample:一个浮点数,取值范围为0.0,1.0,默认值为0。如果小于1.0,则LightGBM会在每次迭代中随机选择部分样本来训练(非重复采样)。如0.8表示:在每棵树训练之前选择80%的样本(非重复采样)来训练。
  • bagging\_freq或者subsample\_freq:一个整数,表示每bagging\_freq次执行bagging。如果该参数为0,表示禁用bagging。
  • bagging\_seed或者bagging\_fraction\_seed:一个整数,表示bagging的随机数种子,默认为3。
  • early\_stopping\_round或者early\_stopping\_rounds或者early\_stopping:一个整数,默认为0。如果一个验证集的度量在early\_stopping\_round循环中没有提升,则停止训练。如果为0则表示不开启早停。
  • lambda\_l1或者reg\_alpha:一个浮点数,表示L1正则化系数。默认为0。
  • lambda\_l2或者reg\_lambda:一个浮点数,表示L2正则化系数。默认为0。
  • min\_split\_gain或者min\_gain\_to\_split:一个浮点数,表示执行切分的最小增益,默认为0。
  • drop\_rate:一个浮点数,取值范围为0.0,1.0,表示dropout的比例,默认为1。该参数仅在dart中使用。
  • skip\_drop:一个浮点数,取值范围为0.0,1.0,表示跳过dropout的概率,默认为5。该参数仅在dart中使用。
  • max\_drop:一个整数,表示一次迭代中删除树的最大数量,默认为50。如果小于等于0,则表示没有限制。该参数仅在dart中使用。
  • uniform\_drop:一个布尔值,表示是否想要均匀的删除树,默认值为False。该参数仅在dart中使用。
  • xgboost\_dart\_mode:一个布尔值,表示是否使用xgboost dart模式,默认值为False。该参数仅在dart中使用。
  • drop\_seed:一个整数,表示dropout的随机数种子,默认值为4。该参数仅在dart中使用。
  • top\_rate:一个浮点数,取值范围为0.0,1.0,表示在goss中,大梯度数据的保留比例,默认值为2。该参数仅在goss中使用。
  • other\_rate:一个浮点数,取值范围为0.0,1.0,表示在goss中,小梯度数据的保留比例,默认值为1。该参数仅在goss中使用。
  • min\_data\_per\_group:一个整数,表示每个分类组的最小数据量,默认值为100。用于排序任务
  • max\_cat\_threshold:一个整数,表示category特征的取值集合的最大大小。默认为32。
  • cat\_smooth:一个浮点数,用于category特征的概率平滑。默认值为10。它可以降低噪声在category特征中的影响,尤其是对于数据很少的类。
  • cat\_l2:一个浮点数,用于category切分中的L2正则化系数。默认为10。
  • top\_k或者topk:一个整数,用于投票并行中。默认为20。将它设置为更大的值可以获得更精确的结果,但是会降低训练速度。

(3) IO参数

  • max\_bin:一个整数,表示最大的桶的数量。默认值为255。LightGBM会根据它来自动压缩内存。如max\_bin=255时,则LightGBM将使用uint8来表示特征的每一个值。
  • min\_data\_in\_bin:一个整数,表示每个桶的最小样本数。默认为3。该方法可以避免出现一个桶只有一个样本的情况。
  • data\_random\_seed:一个整数,表示并行学习数据分隔中的随机数种子。默认为1它不包括特征并行。
  • output\_model或者model\_output或者model\_out:一个字符串,表示训练中输出的模型被保存的文件的文件名。默认txt。
  • input\_model或者model\_input或者model\_in:一个字符串,表示输入模型的文件的文件名。默认空字符串。对于prediction任务,该模型将用于预测数据,对于train任务,训练将从该模型继续
  • output\_result或者predict\_result或者prediction\_result:一个字符串,给出了prediction结果存放的文件名。默认为txt。
  • pre\_partition或者is\_pre\_partition:一个布尔值,指示数据是否已经被划分。默认值为False。如果为true,则不同的机器使用不同的partition来训练。它用于并行学习(不包括特征并行)
  • is\_sparse或者is\_enable\_sparse或者enable\_sparse:一个布尔值,表示是否开启稀疏优化,默认为True。如果为True则启用稀疏优化。
  • two\_round或者two\_round\_loading或者use\_two\_round\_loading:一个布尔值,指示是否启动两次加载。默认值为False,表示只需要进行一次加载。默认情况下,LightGBM会将数据文件映射到内存,然后从内存加载特征,这将提供更快的数据加载速度。但是当数据文件很大时,内存可能会被耗尽。如果数据文件太大,则将它设置为True
  • save\_binary或者is\_save\_binary或者is\_save\_binary\_file:一个布尔值,表示是否将数据集(包括验证集)保存到二进制文件中。默认值为False。如果为True,则可以加快数据的加载速度。
  • verbosity或者verbose:一个整数,表示是否输出中间信息。默认值为1。如果小于0,则仅仅输出critical信息;如果等于0,则还会输出error,warning信息;如果大于0,则还会输出info信息。
  • header或者has\_header:一个布尔值,表示输入数据是否有头部。默认为False。
  • label或者label\_column:一个字符串,表示标签列。默认为空字符串。你也可以指定一个整数,如label=0表示第0列是标签列。你也可以为列名添加前缀,如label=prefix:label\_name
  • weight或者weight\_column:一个字符串,表示样本权重列。默认为空字符串。你也可以指定一个整数,如weight=0表示第0列是权重列。注意:它是剔除了标签列之后的索引。假如标签列为0,权重列为1,则这里weight=0。你也可以为列名添加前缀,如weight=prefix:weight\_name
  • query或者query\_column或者gourp或者group\_column:一个字符串,query/groupID列。默认为空字符串。你也可以指定一个整数,如query=0表示第0列是query列。注意:它是剔除了标签列之后的索引。假如标签列为0,query列为1,则这里query=0。你也可以为列名添加前缀,如query=prefix:query\_name
  • ignore\_column或者ignore\_feature或者blacklist:一个字符串,表示训练中忽略的一些列,默认为空字符串。可以用数字做索引,如ignore\_column=0,1,2表示第0,1,2列将被忽略。注意:它是剔除了标签列之后的索引。
  • 你也可以为列名添加前缀,如ignore\_column=prefix:ign\_name1,ign\_name2
  • categorical\_feature或者categorical\_column或者cat\_feature或者cat\_column:一个字符串,指定category特征的列。默认为空字符串。可以用数字做索引,如categorical\_feature=0,1,2表示第0,1,2列将作为category特征。注意:它是剔除了标签列之后的索引。你也可以为列名添加前缀,如categorical\_feature=prefix:cat\_name1,cat\_name2在categorycal特征中,负的取值被视作缺失值。
  • predict\_raw\_score或者raw\_score或者is\_predict\_raw\_score:一个布尔值,表示是否预测原始得分。默认为False。如果为True则仅预测原始得分。该参数只用于prediction任务。
  • predict\_leaf\_index或者leaf\_index或者is\_predict\_leaf\_index:一个布尔值,表示是否预测每个样本在每棵树上的叶节点编号。默认为False。在预测时,每个样本都会被分配到每棵树的某个叶子节点上。该参数就是要输出这些叶子节点的编号。该参数只用于prediction任务。
  • predict\_contrib或者contrib或者is\_predict\_contrib:一个布尔值,表示是否输出每个特征对于每个样本的预测的贡献。默认为False。输出的结果形状为nsamples,nfeatures+1,之所以+1是考虑到bais的贡献。所有的贡献加起来就是该样本的预测结果。该参数只用于prediction任务。
  • bin\_construct\_sample\_cnt或者subsample\_for\_bin:一个整数,表示用来构建直方图的样本的数量。默认为200000。如果数据非常稀疏,则可以设置为一个更大的值,如果设置更大的值,则会提供更好的训练效果,但是会增加数据加载时间。
  • num\_iteration\_predict:一个整数,表示在预测中使用多少棵子树。默认为-1。小于等于0表示使用模型的所有子树。该参数只用于prediction任务。
  • pred\_early\_stop:一个布尔值,表示是否使用早停来加速预测。默认为False。如果为True,则可能影响精度。
  • pred\_early\_stop\_freq:一个整数,表示检查早停的频率。默认为10
  • pred\_early\_stop\_margin:一个浮点数,表示早停的边际阈值。默认为0
  • use\_missing:一个布尔值,表示是否使用缺失值功能。默认为True如果为False则禁用缺失值功能。
  • zero\_as\_missing:一个布尔值,表示是否将所有的零(包括在libsvm/sparse矩阵中未显示的值)都视为缺失值。默认为False。如果为False,则将nan视作缺失值。如果为True,则np.nan和零都将视作缺失值。
  • init\_score\_file:一个字符串,表示训练时的初始化分数文件的路径。默认为空字符串,表示train_data_file+”.init”(如果存在)
  • valid\_init\_score\_file:一个字符串,表示验证时的初始化分数文件的路径。默认为空字符串,表示valid_data_file+”.init”(如果存在)。如果有多个(对应于多个验证集),则可以用逗号,来分隔。

(4) 目标参数

  • sigmoid:一个浮点数,用sigmoid函数的参数,默认为0。它用于二分类任务和lambdarank任务。
  • alpha:一个浮点数,用于Huber损失函数和Quantileregression,默认值为0。它用于huber回归任务和Quantile回归任务。
  • fair\_c:一个浮点数,用于Fair损失函数,默认值为0。它用于fair回归任务。
  • gaussian\_eta:一个浮点数,用于控制高斯函数的宽度,默认值为0。它用于regression_l1回归任务和huber回归任务。
  • posson\_max\_delta\_step:一个浮点数,用于Poisson regression的参数,默认值为7。它用于poisson回归任务。
  • scale\_pos\_weight:一个浮点数,用于调整正样本的权重,默认值为0它用于二分类任务。
  • boost\_from\_average:一个布尔值,指示是否将初始得分调整为平均值(它可以使得收敛速度更快)。默认为True。它用于回归任务。
  • is\_unbalance或者unbalanced\_set:一个布尔值,指示训练数据是否均衡的。默认为True。它用于二分类任务。
  • max\_position:一个整数,指示将在这个NDCG位置优化。默认为20。它用于lambdarank任务。
  • label\_gain:一个浮点数序列,给出了每个标签的增益。默认值为0,1,3,7,15,….它用于lambdarank任务。
  • num\_class或者num\_classes:一个整数,指示了多分类任务中的类别数量。默认为1它用于多分类任务。
  • reg\_sqrt:一个布尔值,默认为False。如果为True,则拟合的结果为:\sqrt{label}。同时预测的结果被自动转换为:{pred}^2。它用于回归任务。

(5) 度量参数

  • metric:一个字符串,指定了度量的指标,默认为:对于回归问题,使用l2;对于二分类问题,使用binary\_logloss;对于lambdarank问题,使用ndcg。如果有多个度量指标,则用逗号,分隔。
  • l1或者mean\_absolute\_error或者mae或者regression\_l1:表示绝对值损失。
  • l2或者mean\_squared\_error或者mse或者regression\_l2或者regression:表示平方损失。
  • l2\_root或者root\_mean\_squared\_error或者rmse:表示开方损失。
  • quantile:表示Quantile回归中的损失。
  • mape或者mean\_absolute\_percentage\_error:表示MAPE损失。
  • huber:表示huber损失。
  • fair:表示fair损失。
  • poisson:表示poisson回归的负对数似然。
  • gamma:表示gamma回归的负对数似然。
  • gamma\_deviance:表示gamma回归的残差的方差。
  • tweedie:表示Tweedie回归的负对数似然。
  • ndcg:表示NDCG。
  • map或者mean\_average\_precision:表示平均的精度。
  • auc:表示AUC。
  • binary\_logloss或者binary:表示二类分类中的对数损失函数。
  • binary\_error:表示二类分类中的分类错误率。
  • multi\_logloss或者multiclass或者softmax或者‘multiclassova或者multiclass_ova,或者ova或者ovr`:表示多类分类中的对数损失函数。
  • multi\_error:表示多分类中的分类错误率。
  • xentropy或者cross\_entropy:表示交叉熵。
  • xentlambda或者cross\_entropy\_lambda:表示intensity加权的交叉熵。
  • kldiv或者kullback\_leibler:表示KL散度。
  • metric\_freq或者output\_freq:一个正式,表示每隔多少次输出一次度量结果。默认为1。
  • train\_metric或者training\_metric或者is\_training\_metric:一个布尔值,默认为False。如果为True,则在训练时就输出度量结果。
  • ndcg\_at或者ndcg\_eval\_at或者eval\_at:一个整数列表,指定了NDCG评估点的位置。默认为1、2、3、4、5。

2.2 参数影响与调参建议

以下为总结的核心参数对模型的影响,及与之对应的调参建议。

(1) 对树生长控制

  • num\_leaves:叶节点的数目。它是控制树模型复杂度的主要参数。
  • 如果是level-wise,则该参数为$2^{depth}$,其中depth为树的深度。但是当叶子数量相同时,leaf-wise的树要远远深过level-wise树,非常容易导致过拟合。因此应该让num_leaves小于$2^{depth}$。在leaf-wise树中,并不存在depth的概念。因为不存在一个从leaves到depth的合理映射。
  • min\_data\_in\_leaf:每个叶节点的最少样本数量。
  • 它是处理leaf-wise树的过拟合的重要参数。将它设为较大的值,可以避免生成一个过深的树。但是也可能导致欠拟合。
  • max\_depth:树的最大深度。该参数可以显式的限制树的深度。

(2) 更快的训练速度

  • 通过设置bagging\_fractionbagging\_freq参数来使用bagging方法。
  • 通过设置feature\_fraction参数来使用特征的子抽样。
  • 使用较小的max\_bin
  • 使用save\_binary在未来的学习过程对数据加载进行加速。

(3) 更好的模型效果

  • 使用较大的max\_bin(学习速度可能变慢)。
  • 使用较小的learning\_rate和较大的num\_iterations
  • 使用较大的num\_leaves(可能导致过拟合)。
  • 使用更大的训练数据。
  • 尝试dart

(4) 缓解过拟合问题

  • 使用较小的max\_bin
  • 使用较小的num\_leaves
  • 使用min\_data\_in\_leafmin\_sum\_hessian\_in\_leaf
  • 通过设置bagging\_fractionbagging\_freq来使用bagging
  • 通过设置feature\_fraction来使用特征子抽样。
  • 使用更大的训练数据。
  • 使用lambda\_l1lambda\_l2min\_gain\_to\_split来使用正则。
  • 尝试max\_depth来避免生成过深的树。

3.LightGBM内置建模方式

3.1 内置建模方式

LightGBM内置了建模方式,有如下的数据格式与核心训练方法:

  • 基于lightgbm.Dataset格式的数据。
  • 基于lightgbm.train接口训练。

下面是官方的一个简单示例,演示了读取libsvm格式数据(成Dataset格式)并指定参数建模的过程。

代码语言:python
代码运行次数:0
复制
# coding: utf-8

import json

import lightgbm as lgb

import pandas as pd

from sklearn.metrics import mean\_squared\_erro





# 加载数据集合

print('加载数据...')

df\_train = pd.read\_csv('./data/regression.train.txt', header=None, sep='\t')

df\_test = pd.read\_csv('./data/regression.test.txt', 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中的Dataset格式

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,

    'verbose': 0

}



print('开始训练...')

# 训练

gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=20,

                valid\_sets=lgb\_eval,

                early\_stopping\_rounds=5)



# 保存模型

print('保存模型...')

# 保存模型到文件中

gbm.save\_model('model.txt')



print('开始预测...')

# 预测

y\_pred = gbm.predict(X\_test, num\_iteration=gbm.best\_iteration)

# 评估

print('预估结果的rmse为:')

print(mean\_squared\_error(y\_test, y\_pred) \*\* 0.5)
代码语言:txt
复制
加载数据...

开始训练...

[1]  valid\_0's l2: 0.24288   valid\_0's auc: 0.764496

Training until validation scores don't improve for 5 rounds.

[2]  valid\_0's l2: 0.239307  valid\_0's auc: 0.766173

[3]  valid\_0's l2: 0.235559  valid\_0's auc: 0.785547

[4]  valid\_0's l2: 0.230771  valid\_0's auc: 0.797786

[5]  valid\_0's l2: 0.226297  valid\_0's auc: 0.805155

[6]  valid\_0's l2: 0.223692  valid\_0's auc: 0.800979

[7]  valid\_0's l2: 0.220941  valid\_0's auc: 0.806566

[8]  valid\_0's l2: 0.217982  valid\_0's auc: 0.808566

[9]  valid\_0's l2: 0.215351  valid\_0's auc: 0.809041

[10] valid\_0's l2: 0.213064  valid\_0's auc: 0.805953

[11] valid\_0's l2: 0.211053  valid\_0's auc: 0.804631

[12] valid\_0's l2: 0.209336  valid\_0's auc: 0.802922

[13] valid\_0's l2: 0.207492  valid\_0's auc: 0.802011

[14] valid\_0's l2: 0.206016  valid\_0's auc: 0.80193

Early stopping, best iteration is:

[9]  valid\_0's l2: 0.215351  valid\_0's auc: 0.809041

保存模型...

开始预测...

预估结果的rmse为:

0.4640593794679212

3.2 设置样本权重

LightGBM的建模非常灵活,它可以支持我们对于每个样本设置不同的权重学习,设置的方式也非常简单,我们需要提供给模型一组权重数组数据,长度和样本数一致。

如下是一个典型的例子,其中binary.trainbinary.test读取后加载为lightgbm.Dataset格式的输入,而在lightgbm.Dataset的构建参数中可以设置样本权重(这个例子中是numpy array的形态)。再基于lightgbm.train接口使用内置建模方式训练。

代码语言:python
代码运行次数:0
复制
# coding: utf-8

import json

import lightgbm as lgb

import pandas as pd

import numpy as np

from sklearn.metrics import mean\_squared\_erro

import warnings

warnings.filterwarnings("ignore")



# 加载数据集

print('加载数据...')

df\_train = pd.read\_csv('./data/binary.train', header=None, sep='\t')

df\_test = pd.read\_csv('./data/binary.test', header=None, sep='\t')

W\_train = pd.read\_csv('./data/binary.train.weight', header=None)[0]

W\_test = pd.read\_csv('./data/binary.test.weight', header=None)[0]



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



num\_train, num\_feature = X\_train.shape



# 加载数据的同时加载权重

lgb\_train = lgb.Dataset(X\_train, y\_train,

                        weight=W\_train, free\_raw\_data=False)

lgb\_eval = lgb.Dataset(X\_test, y\_test, reference=lgb\_train,

                       weight=W\_test, free\_raw\_data=False)



# 设定参数

params = {

    'boosting\_type': 'gbdt',

    'objective': 'binary',

    'metric': 'binary\_logloss',

    'num\_leaves': 31,

    'learning\_rate': 0.05,

    'feature\_fraction': 0.9,

    'bagging\_fraction': 0.8,

    'bagging\_freq': 5,

    'verbose': 0

}



# 产出特征名称

feature\_name = ['feature\_' + str(col) for col in range(num\_feature)]



print('开始训练...')

gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=10,

                valid\_sets=lgb\_train,  # 评估训练集

                feature\_name=feature\_name,

                categorical\_feature=[21])
代码语言:txt
复制
加载数据...

开始训练...

[1]  training's binary\_logloss: 0.68205

[2]  training's binary\_logloss: 0.673618

[3]  training's binary\_logloss: 0.665891

[4]  training's binary\_logloss: 0.656874

[5]  training's binary\_logloss: 0.648523

[6]  training's binary\_logloss: 0.641874

[7]  training's binary\_logloss: 0.636029

[8]  training's binary\_logloss: 0.629427

[9]  training's binary\_logloss: 0.623354

[10] training's binary\_logloss: 0.617593

3.3 模型存储与加载

上述建模过程得到的模型对象,可以通过save_model成员函数进行保存。保存好的模型可以通过lgb.Booster加载回内存,并对测试集进行预测。

具体示例代码如下:

代码语言:python
代码运行次数:0
复制
# 查看特征名称

print('完成10轮训练...')

print('第7个特征为:')

print(repr(lgb\_train.feature\_name[6]))



# 存储模型

gbm.save\_model('./model/lgb\_model.txt')



# 特征名称

print('特征名称:')

print(gbm.feature\_name())



# 特征重要度

print('特征重要度:')

print(list(gbm.feature\_importance()))



# 加载模型

print('加载模型用于预测')

bst = lgb.Booster(model\_file='./model/lgb\_model.txt')



# 预测

y\_pred = bst.predict(X\_test)



# 在测试集评估效果

print('在测试集上的rmse为:')

print(mean\_squared\_error(y\_test, y\_pred) \*\* 0.5)
代码语言:txt
复制
完成10轮训练...

第7个特征为:

'feature\_6'

特征名称:

['feature\_0', 'feature\_1', 'feature\_2', 'feature\_3', 'feature\_4', 'feature\_5', 'feature\_6', 'feature\_7', 'feature\_8', 'feature\_9', 'feature\_10', 'feature\_11', 'feature\_12', 'feature\_13', 'feature\_14', 'feature\_15', 'feature\_16', 'feature\_17', 'feature\_18', 'feature\_19', 'feature\_20', 'feature\_21', 'feature\_22', 'feature\_23', 'feature\_24', 'feature\_25', 'feature\_26', 'feature\_27']

特征重要度:

[8, 5, 1, 19, 7, 33, 2, 0, 2, 10, 5, 2, 0, 9, 3, 3, 0, 2, 2, 5, 1, 0, 36, 3, 33, 45, 29, 35]

加载模型用于预测

在测试集上的rmse为:

0.4629245607636925

3.4 继续训练

LightGBM为boosting模型,每一轮训练会增加新的基学习器,LightGBM还支持基于现有模型和参数继续训练,无需每次从头训练。

如下是典型的示例,我们加载已经训练10轮(即10颗树集成)的lgb模型,在此基础上继续训练(在参数层面做了一些改变,调整了学习率,增加了一些bagging等缓解过拟合的处理方法)

代码语言:python
代码运行次数:0
复制
# 继续训练

# 从./model/model.txt中加载模型初始化

gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=10,

                init\_model='./model/lgb\_model.txt',

                valid\_sets=lgb\_eval)



print('以旧模型为初始化,完成第 10-20 轮训练...')



# 在训练的过程中调整超参数

# 比如这里调整的是学习率

gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=10,

                init\_model=gbm,

                learning\_rates=lambda iter: 0.05 \* (0.99 \*\* iter),

                valid\_sets=lgb\_eval)



print('逐步调整学习率完成第 20-30 轮训练...')



# 调整其他超参数

gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=10,

                init\_model=gbm,

                valid\_sets=lgb\_eval,

                callbacks=[lgb.reset\_parameter(bagging\_fraction=[0.7] \* 5 + [0.6] \* 5)])



print('逐步调整bagging比率完成第 30-40 轮训练...')
代码语言:txt
复制
[11] valid\_0's binary\_logloss: 0.616177

[12] valid\_0's binary\_logloss: 0.611792

[13] valid\_0's binary\_logloss: 0.607043

[14] valid\_0's binary\_logloss: 0.602314

[15] valid\_0's binary\_logloss: 0.598433

[16] valid\_0's binary\_logloss: 0.595238

[17] valid\_0's binary\_logloss: 0.592047

[18] valid\_0's binary\_logloss: 0.588673

[19] valid\_0's binary\_logloss: 0.586084

[20] valid\_0's binary\_logloss: 0.584033

以旧模型为初始化,完成第 10-20 轮训练...

[21] valid\_0's binary\_logloss: 0.616177

[22] valid\_0's binary\_logloss: 0.611834

[23] valid\_0's binary\_logloss: 0.607177

[24] valid\_0's binary\_logloss: 0.602577

[25] valid\_0's binary\_logloss: 0.59831

[26] valid\_0's binary\_logloss: 0.595259

[27] valid\_0's binary\_logloss: 0.592201

[28] valid\_0's binary\_logloss: 0.589017

[29] valid\_0's binary\_logloss: 0.586597

[30] valid\_0's binary\_logloss: 0.584454

逐步调整学习率完成第 20-30 轮训练...

[31] valid\_0's binary\_logloss: 0.616053

[32] valid\_0's binary\_logloss: 0.612291

[33] valid\_0's binary\_logloss: 0.60856

[34] valid\_0's binary\_logloss: 0.605387

[35] valid\_0's binary\_logloss: 0.601744

[36] valid\_0's binary\_logloss: 0.598556

[37] valid\_0's binary\_logloss: 0.595585

[38] valid\_0's binary\_logloss: 0.593228

[39] valid\_0's binary\_logloss: 0.59018

[40] valid\_0's binary\_logloss: 0.588391

逐步调整bagging比率完成第 30-40 轮训练...

3.5 自定义损失函数

LightGBM支持在训练过程中,自定义损失函数和评估准则,其中损失函数的定义需要返回损失函数一阶和二阶导数的计算方法,评估准则部分需要对数据的label和预估值进行计算。其中损失函数用于训练过程中的树结构学习,而评估准则很多时候是用在验证集上进行效果评估。

代码语言:python
代码运行次数:0
复制
# 自定义损失函数需要提供损失函数的一阶和二阶导数形式

def loglikelood(preds, train\_data):

    labels = train\_data.get\_label()

    preds = 1. / (1. + np.exp(-preds))

    grad = preds - labels

    hess = preds \* (1. - preds)

    return grad, hess





# 自定义评估函数

def binary\_error(preds, train\_data):

    labels = train\_data.get\_label()

    return 'error', np.mean(labels != (preds > 0.5)), False





gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=10,

                init\_model=gbm,

                fobj=loglikelood,

                feval=binary\_error,

                valid\_sets=lgb\_eval)



print('用自定义的损失函数与评估标准完成第40-50轮...')
代码语言:txt
复制
[41] valid\_0's binary\_logloss: 0.614429  valid\_0's error: 0.268

[42] valid\_0's binary\_logloss: 0.610689  valid\_0's error: 0.26

[43] valid\_0's binary\_logloss: 0.606267  valid\_0's error: 0.264

[44] valid\_0's binary\_logloss: 0.601949  valid\_0's error: 0.258

[45] valid\_0's binary\_logloss: 0.597271  valid\_0's error: 0.266

[46] valid\_0's binary\_logloss: 0.593971  valid\_0's error: 0.276

[47] valid\_0's binary\_logloss: 0.591427  valid\_0's error: 0.278

[48] valid\_0's binary\_logloss: 0.588301  valid\_0's error: 0.284

[49] valid\_0's binary\_logloss: 0.586562  valid\_0's error: 0.288

[50] valid\_0's binary\_logloss: 0.584056  valid\_0's error: 0.288

用自定义的损失函数与评估标准完成第40-50轮...

4.LightGBM预估器形态接口

4.1 SKLearn形态预估器接口

和XGBoost一样,LightGBM也支持用SKLearn中统一的预估器形态接口进行建模,如下为典型的参考案例,对于读取为Dataframe格式的训练集和测试集,可以直接使用LightGBM初始化LGBMRegressor进行fit拟合训练。使用方法与接口,和SKLearn中其他预估器一致。

代码语言:python
代码运行次数:0
复制
# coding: utf-8

import lightgbm as lgb

import pandas as pd

from sklearn.metrics import mean\_squared\_erro

from sklearn.model\_selection import GridSearchCV



# 加载数据

print('加载数据...')

df\_train = pd.read\_csv('./data/regression.train.txt', header=None, sep='\t')

df\_test = pd.read\_csv('./data/regression.test.txt', 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('开始训练...')

# 初始化LGBMRegresso

gbm = lgb.LGBMRegressor(objective='regression',

                        num\_leaves=31,

                        learning\_rate=0.05,

                        n\_estimators=20)



# 使用fit函数拟合

gbm.fit(X\_train, y\_train,

        eval\_set=[(X\_test, y\_test)],

        eval\_metric='l1',

        early\_stopping\_rounds=5)



# 预测

print('开始预测...')

y\_pred = gbm.predict(X\_test, num\_iteration=gbm.best\_iteration\_)

# 评估预测结果

print('预测结果的rmse是:')

print(mean\_squared\_error(y\_test, y\_pred) \*\* 0.5)
代码语言:txt
复制
加载数据...

开始训练...

[1]  valid\_0's l1: 0.491735

Training until validation scores don't improve for 5 rounds.

[2]  valid\_0's l1: 0.486563

[3]  valid\_0's l1: 0.481489

[4]  valid\_0's l1: 0.476848

[5]  valid\_0's l1: 0.47305

[6]  valid\_0's l1: 0.469049

[7]  valid\_0's l1: 0.465556

[8]  valid\_0's l1: 0.462208

[9]  valid\_0's l1: 0.458676

[10] valid\_0's l1: 0.454998

[11] valid\_0's l1: 0.452047

[12] valid\_0's l1: 0.449158

[13] valid\_0's l1: 0.44608

[14] valid\_0's l1: 0.443554

[15] valid\_0's l1: 0.440643

[16] valid\_0's l1: 0.437687

[17] valid\_0's l1: 0.435454

[18] valid\_0's l1: 0.433288

[19] valid\_0's l1: 0.431297

[20] valid\_0's l1: 0.428946

Did not meet early stopping. Best iteration is:

[20] valid\_0's l1: 0.428946

开始预测...

预测结果的rmse是:

0.4441153344254208

4.2 网格搜索调参

上面提到LightGBM的预估器接口,整体使用方法和SKLearn中其他预估器一致,所以我们也可以使用SKLearn中的超参数调优方法来进行模型调优。

如下是一个典型的网格搜索交法调优超参数的代码示例,我们会给出候选参数列表字典,通过GridSearchCV进行交叉验证实验评估,选出LightGBM在候选参数中最优的超参数。

代码语言:python
代码运行次数:0
复制
# 配合scikit-learn的网格搜索交叉验证选择最优超参数

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('用网格搜索找到的最优超参数为:')

print(gbm.best\_params\_)
代码语言:txt
复制
用网格搜索找到的最优超参数为:

{'learning\_rate': 0.1, 'n\_estimators': 40}

4.3 绘图解释

LightGBM支持对模型训练进行可视化呈现与解释,包括对于训练过程中的损失函数取值与评估准则结果的可视化、训练完成后特征重要度的排序与可视化、基学习器(比如决策树)的可视化。

以下为参考代码:

代码语言:python
代码运行次数:0
复制
# coding: utf-8

import lightgbm as lgb

import pandas as pd



try:

    import matplotlib.pyplot as plt

except ImportError:

    raise ImportError('You need to install matplotlib for plotting.')



# 加载数据集

print('加载数据...')

df\_train = pd.read\_csv('./data/regression.train.txt', header=None, sep='\t')

df\_test = pd.read\_csv('./data/regression.test.txt', 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中的Dataset数据格式

lgb\_train = lgb.Dataset(X\_train, y\_train)

lgb\_test = lgb.Dataset(X\_test, y\_test, reference=lgb\_train)



# 设定参数

params = {

    'num\_leaves': 5,

    'metric': ('l1', 'l2'),

    'verbose': 0

}



evals\_result = {}  # to record eval results for plotting



print('开始训练...')

# 训练

gbm = lgb.train(params,

                lgb\_train,

                num\_boost\_round=100,

                valid\_sets=[lgb\_train, lgb\_test],

                feature\_name=['f' + str(i + 1) for i in range(28)],

                categorical\_feature=[21],

                evals\_result=evals\_result,

                verbose\_eval=10)



print('在训练过程中绘图...')

ax = lgb.plot\_metric(evals\_result, metric='l1')

plt.show()



print('画出特征重要度...')

ax = lgb.plot\_importance(gbm, max\_num\_features=10)

plt.show()



print('画出第84颗树...')

ax = lgb.plot\_tree(gbm, tree\_index=83, figsize=(20, 8), show\_info=['split\_gain'])

plt.show()



#print('用graphviz画出第84颗树...')

#graph = lgb.create\_tree\_digraph(gbm, tree\_index=83, name='Tree84')

#graph.render(view=True)
代码语言:txt
复制
加载数据...

开始训练...

[10] training's l2: 0.217995 training's l1: 0.457448 valid\_1's l2: 0.21641   valid\_1's l1: 0.456464

[20] training's l2: 0.205099 training's l1: 0.436869 valid\_1's l2: 0.201616  valid\_1's l1: 0.434057

[30] training's l2: 0.197421 training's l1: 0.421302 valid\_1's l2: 0.192514  valid\_1's l1: 0.417019

[40] training's l2: 0.192856 training's l1: 0.411107 valid\_1's l2: 0.187258  valid\_1's l1: 0.406303

[50] training's l2: 0.189593 training's l1: 0.403695 valid\_1's l2: 0.183688  valid\_1's l1: 0.398997

[60] training's l2: 0.187043 training's l1: 0.398704 valid\_1's l2: 0.181009  valid\_1's l1: 0.393977

[70] training's l2: 0.184982 training's l1: 0.394876 valid\_1's l2: 0.178803  valid\_1's l1: 0.389805

[80] training's l2: 0.1828   training's l1: 0.391147 valid\_1's l2: 0.176799  valid\_1's l1: 0.386476

[90] training's l2: 0.180817 training's l1: 0.388101 valid\_1's l2: 0.175775  valid\_1's l1: 0.384404

[100]   training's l2: 0.179171 training's l1: 0.385174 valid\_1's l2: 0.175321  valid\_1's l1: 0.382929

参考资料

ShowMeAI系列教程推荐

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 1.LightGBM安装
    • 1.1 Python与IDE环境设置
      • 1.2 工具库安装
        • (1) Linux/Mac等系统
        • (2) Windows系统
    • 2.LightGBM参数手册
      • 2.1 参数介绍
        • (1) 核心参数
        • (2) 学习控制参数
        • (3) IO参数
        • (4) 目标参数
        • (5) 度量参数
      • 2.2 参数影响与调参建议
        • (1) 对树生长控制
        • (2) 更快的训练速度
        • (3) 更好的模型效果
        • (4) 缓解过拟合问题
    • 3.LightGBM内置建模方式
      • 3.1 内置建模方式
        • 3.2 设置样本权重
          • 3.3 模型存储与加载
            • 3.4 继续训练
              • 3.5 自定义损失函数
              • 4.LightGBM预估器形态接口
                • 4.1 SKLearn形态预估器接口
                  • 4.2 网格搜索调参
                    • 4.3 绘图解释
                      • 参考资料
                      • ShowMeAI系列教程推荐
                      相关产品与服务
                      GPU 云服务器
                      GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于生成式AI,自动驾驶,深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档