Download as pdf or txt
Download as pdf or txt
You are on page 1of 19

LightGBM建模应用详解

引言

LightGBM是微软开发的boosting集成模型,和XGBoost一样是对GBDT的优化和高效实现,原理有一些相似之
处,但它很多方面比XGBoost有着更为优秀的表现。
本篇内容展开给大家讲解LightGBM的工程应用方法,对于LightGBM原理知识感兴趣的同学,欢迎参考
ShowMeAI的另外一篇文章 图解机器学习 | LightGBM模型详解。

1.LightGBM安装

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

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

1.2 工具库安装

(1) Linux/Mac等系统

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

1. pip install lightgbm

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

牛博带你学AI 搜集整理
1. 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 :一个字符串,表示问题类型。可以为:

regression 或 regression_l2 或 mean_squared_error 或 mse 或 l2_root 或


root_mean_squred_error 或 rmse :表示回归任务,但是使用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 :一个字符串,给出了基学习器模型算法。可以为:

牛博带你学AI 搜集整理
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 learner

feature :特征并行的tree learner

data :数据并行的tree learner


voting :投票并行的tree learner

num_threads 或者 num_thread 或者 nthread :一个整数,给出了LightGBM的线程数。默认


为 OpenMP_default 。

为了更快的速度,应该将它设置为真正的CPU内核数,而不是线程的数量(大多数CPU使用超线程来使
每个CPU内核生成2个线程)。

当数据集较小的时候,不要将它设置的过大。

对于并行学习,不应该使用全部的CPU核心,因为这会使得网络性能不佳。

device :一个字符串,指定计算设备。默认为 cpu 。可以为 gpu 、 cpu 。

建议使用较小的 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 :一个整数

牛博带你学AI 搜集整理
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参数

牛博带你学AI 搜集整理
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。在预测时,每个样本都会被分配到每棵树的某个叶子节点上。

牛博带你学AI 搜集整理
该参数就是要输出这些叶子节点的编号。该参数只用于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) 度量参数

牛博带你学AI 搜集整理
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-

牛博带你学AI 搜集整理
wise的树要远远深过level-wise树,非常容易导致过拟合。因此应该让num_leaves小于$2^{depth}$。在
leaf-wise树中,并不存在depth的概念。因为不存在一个从leaves到depth的合理映射。
min_data_in_leaf :每个叶节点的最少样本数量。
它是处理 leaf-wise 树的过拟合的重要参数。将它设为较大的值,可以避免生成一个过深的树。但是也
可能导致欠拟合。
max_depth :树的最大深度。该参数可以显式的限制树的深度。

(2) 更快的训练速度

通过设置 bagging_fraction 和 bagging_freq 参数来使用bagging方法。


通过设置 feature_fraction 参数来使用特征的子抽样。
使用较小的 max_bin 。
使用 save_binary 在未来的学习过程对数据加载进行加速。

(3) 更好的模型效果

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


使用较小的 learning_rate 和较大的 num_iterations 。
使用较大的 num_leaves (可能导致过拟合)。
使用更大的训练数据。
尝试 dart 。

(4) 缓解过拟合问题

牛博带你学AI 搜集整理
使用较小的 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 来避免生成过深的树。

3.LightGBM内置建模方式

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

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

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

1. ## coding: utf-8
2. import json
3. import lightgbm as lgb
4. import pandas as pd
5. from sklearn.metrics import mean_squared_error
6.
7.
8. ## 加载数据集合
9. print('加载数据...')
10. df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
11. df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
12.
13. ## 设定训练集和测试集
14. y_train = df_train[0].values
15. y_test = df_test[0].values
16. X_train = df_train.drop(0, axis=1).values
17. X_test = df_test.drop(0, axis=1).values
18.
19. ## 构建lgb中的Dataset格式
20. lgb_train = lgb.Dataset(X_train, y_train)
21. lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
22.
23. ## 敲定好一组参数
24. params = {
25. 'task': 'train',
26. 'boosting_type': 'gbdt',
27. 'objective': 'regression',
28. 'metric': {'l2', 'auc'},
29. 'num_leaves': 31,
30. 'learning_rate': 0.05,
31. 'feature_fraction': 0.9,
32. 'bagging_fraction': 0.8,
33. 'bagging_freq': 5,
34. 'verbose': 0
35. }
36.
37 print(' 开始训练 ')

牛博带你学AI 搜集整理
37. print(开始训练... )
38. ## 训练
39. gbm = lgb.train(params,
40. lgb_train,
41. num_boost_round=20,
42. valid_sets=lgb_eval,
43. early_stopping_rounds=5)
44.
45. ## 保存模型
保存模型...')
46. print('
47. ## 保存模型到文件中
48. gbm.save_model('model.txt')
49.
开始预测...')
50. print('
51. ## 预测
52. y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
53. ## 评估
预估结果的rmse为:')
54. print('
55. print(mean_squared_error(y_test, y_pred) ** 0.5)

1. 加载数据...
2. 开始训练...
3. [1] valid_0's l2: 0.24288 valid_0's auc: 0.764496
4. Training until validation scores don't improve for 5 rounds.
5. [2] valid_0's l2: 0.239307 valid_0's auc: 0.766173
6. [3] valid_0's l2: 0.235559 valid_0's auc: 0.785547
7. [4] valid_0's l2: 0.230771 valid_0's auc: 0.797786
8. [5] valid_0's l2: 0.226297 valid_0's auc: 0.805155
9. [6] valid_0's l2: 0.223692 valid_0's auc: 0.800979
10. [7] valid_0's l2: 0.220941 valid_0's auc: 0.806566
11. [8] valid_0's l2: 0.217982 valid_0's auc: 0.808566
12. [9] valid_0's l2: 0.215351 valid_0's auc: 0.809041
13. [10] valid_0's l2: 0.213064 valid_0's auc: 0.805953
14. [11] valid_0's l2: 0.211053 valid_0's auc: 0.804631
15. [12] valid_0's l2: 0.209336 valid_0's auc: 0.802922
16. [13] valid_0's l2: 0.207492 valid_0's auc: 0.802011
17. [14] valid_0's l2: 0.206016 valid_0's auc: 0.80193
18. Early stopping, best iteration is:
19. [9] valid_0's l2: 0.215351 valid_0's auc: 0.809041
20. 保存模型...
21. 开始预测...
22. 预估结果的rmse为:
23. 0.4640593794679212

3.2 设置样本权重

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

如下是一个典型的例子,其中 binary.train 和 binary.test 读取后加载为 lightgbm.Dataset 格式的输入,而


在 lightgbm.Dataset 的构建参数中可以设置样本权重(这个例子中是numpy array的形态)。再基
于 lightgbm.train 接口使用内置建模方式训练。

1. ## coding: utf-8
2. import json
3. import lightgbm as lgb
4. import pandas as pd
5. import numpy as np
6. from sklearn.metrics import mean_squared_error
7. import warnings
8. warnings.filterwarnings("ignore")
9.
10. ## 加载数据集
11. print('加载数据...')
12. df_train = pd.read_csv('./data/binary.train', header=None, sep='\t')
13. df_test = pd.read_csv('./data/binary.test', header=None, sep='\t')
14. W_train = pd.read_csv('./data/binary.train.weight', header=None)[0]
15. W_test = pd.read_csv('./data/binary.test.weight', header=None)[0]
16.
17. y_train = df_train[0].values
18. y_test = df_test[0].values
19. X_train = df_train.drop(0, axis=1).values
20. X_test = df_test.drop(0, axis=1).values
21.
22. num_train, num_feature = X_train.shape
23.
24. ## 加载数据的同时加载权重
25. lgb_train = lgb.Dataset(X_train, y_train,
26. weight=W_train, free_raw_data=False)
27. lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train,
28. weight=W_test, free_raw_data=False)
29.
30. ## 设定参数
31. params = {
32. 'boosting_type': 'gbdt',
33. 'objective': 'binary',
34. 'metric': 'binary_logloss',
35. 'num_leaves': 31,
36. 'learning_rate': 0.05,
37. 'feature_fraction': 0.9,
38. 'bagging_fraction': 0.8,
39. 'bagging_freq': 5,
40. 'verbose': 0
41. }
42.
43. ## 产出特征名称
44. feature_name = ['feature_' + str(col) for col in range(num_feature)]
45.
46. print(' 开始训练...')
47. gbm = lgb.train(params,
48. lgb_train,
49. num_boost_round=10,
50. valid_sets=lgb_train, # 评估训练集
51. feature_name=feature_name,

牛博带你学AI 搜集整理
52. categorical_feature=[21])

1. 加载数据...
2. 开始训练...
3. [1] training's binary_logloss: 0.68205
4. [2] training's binary_logloss: 0.673618
5. [3] training's binary_logloss: 0.665891
6. [4] training's binary_logloss: 0.656874
7. [5] training's binary_logloss: 0.648523
8. [6] training's binary_logloss: 0.641874
9. [7] training's binary_logloss: 0.636029
10. [8] training's binary_logloss: 0.629427
11. [9] training's binary_logloss: 0.623354
12. [10] training's binary_logloss: 0.617593

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

具体示例代码如下:

1. ## 查看特征名称
2. print('完成10轮训练...')
3. print('第7个特征为:')
4. print(repr(lgb_train.feature_name[6]))
5.
6. ## 存储模型
7. gbm.save_model('./model/lgb_model.txt')
8.
9. ## 特征名称
10. print('特征名称:')
11. print(gbm.feature_name())
12.
13. ## 特征重要度
特征重要度:')
14. print('
15. print(list(gbm.feature_importance()))
16.
17. ## 加载模型
加载模型用于预测')
18. print('
19. bst = lgb.Booster(model_file='./model/lgb_model.txt')
20.
21. ## 预测
22. y_pred = bst.predict(X_test)
23.
24. ## 在测试集评估效果
在测试集上的rmse为:')
25. print('
26. print(mean_squared_error(y_test, y_pred) ** 0.5)

牛博带你学AI 搜集整理
1. 完成10轮训练...
2. 第7个特征为:
3. 'feature_6'
4. 特征名称:
5. ['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']
6. 特征重要度:
7. [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]
8. 加载模型用于预测
9. 在测试集上的rmse为:
10. 0.4629245607636925

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

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

1. ## 继续训练
2. ## 从./model/model.txt中加载模型初始化
3. gbm = lgb.train(params,
4. lgb_train,
5. num_boost_round=10,
6. init_model='./model/lgb_model.txt',
7. valid_sets=lgb_eval)
8.
9. print(' 以旧模型为初始化,完成第 10-20 轮训练...')
10.
11. ## 在训练的过程中调整超参数
12. ## 比如这里调整的是学习率
13. gbm = lgb.train(params,
14. lgb_train,
15. num_boost_round=10,
16. init_model=gbm,
17. learning_rates=lambda iter: 0.05 * (0.99 ** iter),
18. valid_sets=lgb_eval)
19.
20. print(' 逐步调整学习率完成第 20-30 轮训练...')
21.
22. ## 调整其他超参数
23. gbm = lgb.train(params,
24. lgb_train,
25. num_boost_round=10,
26. init_model=gbm,
27. valid_sets=lgb_eval,
28. callbacks=[lgb.reset_parameter(bagging_fraction=[0.7] * 5 + [0.6] * 5)])
29.
30. print(' 逐步调整bagging比率完成第 30-40 轮训练...')

牛博带你学AI 搜集整理
1. [11] valid_0's binary_logloss: 0.616177
2. [12] valid_0's binary_logloss: 0.611792
3. [13] valid_0's binary_logloss: 0.607043
4. [14] valid_0's binary_logloss: 0.602314
5. [15] valid_0's binary_logloss: 0.598433
6. [16] valid_0's binary_logloss: 0.595238
7. [17] valid_0's binary_logloss: 0.592047
8. [18] valid_0's binary_logloss: 0.588673
9. [19] valid_0's binary_logloss: 0.586084
10. [20] valid_0's binary_logloss: 0.584033
11. 以旧模型为初始化,完成第 10-20 轮训练...
12. [21] valid_0's binary_logloss: 0.616177
13. [22] valid_0's binary_logloss: 0.611834
14. [23] valid_0's binary_logloss: 0.607177
15. [24] valid_0's binary_logloss: 0.602577
16. [25] valid_0's binary_logloss: 0.59831
17. [26] valid_0's binary_logloss: 0.595259
18. [27] valid_0's binary_logloss: 0.592201
19. [28] valid_0's binary_logloss: 0.589017
20. [29] valid_0's binary_logloss: 0.586597
21. [30] valid_0's binary_logloss: 0.584454
22. 逐步调整学习率完成第 20-30 轮训练...
23. [31] valid_0's binary_logloss: 0.616053
24. [32] valid_0's binary_logloss: 0.612291
25. [33] valid_0's binary_logloss: 0.60856
26. [34] valid_0's binary_logloss: 0.605387
27. [35] valid_0's binary_logloss: 0.601744
28. [36] valid_0's binary_logloss: 0.598556
29. [37] valid_0's binary_logloss: 0.595585
30. [38] valid_0's binary_logloss: 0.593228
31. [39] valid_0's binary_logloss: 0.59018
32. [40] valid_0's binary_logloss: 0.588391
33. 逐步调整bagging比率完成第 30-40 轮训练...

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

1. ## 自定义损失函数需要提供损失函数的一阶和二阶导数形式
2. def loglikelood(preds, train_data):
3. labels = train_data.get_label()
4. preds = 1. / (1. + np.exp(-preds))
5. grad = preds - labels

牛博带你学AI 搜集整理
6. hess = preds * (1. - preds)
7. return grad, hess
8.
9.
10. ## 自定义评估函数
11. def binary_error(preds, train_data):
12. labels = train_data.get_label()
13. return 'error', np.mean(labels != (preds > 0.5)), False
14.
15.
16. gbm = lgb.train(params,
17. lgb_train,
18. num_boost_round=10,
19. init_model=gbm,
20. fobj=loglikelood,
21. feval=binary_error,
22. valid_sets=lgb_eval)
23.
24. print(' 用自定义的损失函数与评估标准完成第40-50轮...')

1. [41] valid_0's binary_logloss: 0.614429 valid_0's error: 0.268


2. [42] valid_0's binary_logloss: 0.610689 valid_0's error: 0.26
3. [43] valid_0's binary_logloss: 0.606267 valid_0's error: 0.264
4. [44] valid_0's binary_logloss: 0.601949 valid_0's error: 0.258
5. [45] valid_0's binary_logloss: 0.597271 valid_0's error: 0.266
6. [46] valid_0's binary_logloss: 0.593971 valid_0's error: 0.276
7. [47] valid_0's binary_logloss: 0.591427 valid_0's error: 0.278
8. [48] valid_0's binary_logloss: 0.588301 valid_0's error: 0.284
9. [49] valid_0's binary_logloss: 0.586562 valid_0's error: 0.288
10. [50] valid_0's binary_logloss: 0.584056 valid_0's error: 0.288
11. 用自定义的损失函数与评估标准完成第40-50轮...

4.LightGBM预估器形态接口

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

1. ## coding: utf-8
2. import lightgbm as lgb
3. import pandas as pd
4. from sklearn.metrics import mean_squared_error

牛博带你学AI 搜集整理
5. from sklearn.model_selection import GridSearchCV
6.
7. ## 加载数据
加载数据...')
8. print('
9. df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
10. df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
11.
12. ## 取出特征和标签
13. y_train = df_train[0].values
14. y_test = df_test[0].values
15. X_train = df_train.drop(0, axis=1).values
16. X_test = df_test.drop(0, axis=1).values
17.
开始训练...')
18. print('
19. ## 初始化LGBMRegressor
20. gbm = lgb.LGBMRegressor(objective='regression',
21. num_leaves=31,
22. learning_rate=0.05,
23. n_estimators=20)
24.
25. ## 使用fit函数拟合
26. gbm.fit(X_train, y_train,
27. eval_set=[(X_test, y_test)],
28. eval_metric='l1',
29. early_stopping_rounds=5)
30.
31. ## 预测
32. print('开始预测...')
33. y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)
34. ## 评估预测结果
预测结果的rmse是:')
35. print('
36. print(mean_squared_error(y_test, y_pred) ** 0.5)

1. 加载数据...
2. 开始训练...
3. [1] valid_0's l1: 0.491735
4. Training until validation scores don't improve for 5 rounds.
5. [2] valid_0's l1: 0.486563
6. [3] valid_0's l1: 0.481489
7. [4] valid_0's l1: 0.476848
8. [5] valid_0's l1: 0.47305
9. [6] valid_0's l1: 0.469049
10. [7] valid_0's l1: 0.465556
11. [8] valid_0's l1: 0.462208
12. [9] valid_0's l1: 0.458676
[10] lid 0' l1 0 454998
牛博带你学AI 搜集整理
13. [10] valid_0's l1: 0.454998
14. [11] valid_0's l1: 0.452047
15. [12] valid_0's l1: 0.449158
16. [13] valid_0's l1: 0.44608
17. [14] valid_0's l1: 0.443554
18. [15] valid_0's l1: 0.440643
19. [16] valid_0's l1: 0.437687
20. [17] valid_0's l1: 0.435454
21. [18] valid_0's l1: 0.433288
22. [19] valid_0's l1: 0.431297
23. [20] valid_0's l1: 0.428946
24. Did not meet early stopping. Best iteration is:
25. [20] valid_0's l1: 0.428946
26. 开始预测...
27. 预测结果的rmse是:
28. 0.4441153344254208

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

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

1. ## 配合scikit-learn的网格搜索交叉验证选择最优超参数
2. estimator = lgb.LGBMRegressor(num_leaves=31)
3.
4. param_grid = {
5. 'learning_rate': [0.01, 0.1, 1],
6. 'n_estimators': [20, 40]
7. }
8.
9. gbm = GridSearchCV(estimator, param_grid)
10.
11. gbm.fit(X_train, y_train)
12.
13. print(' 用网格搜索找到的最优超参数为:')
14. print(gbm.best_params_)

1. 用网格搜索找到的最优超参数为:
2. {'learning_rate': 0.1, 'n_estimators': 40}

4.3 绘图解释

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

以下为参考代码:

1. ## coding: utf-8
2. import lightgbm as lgb
3. import pandas as pd
4.
5. try:
6. import matplotlib.pyplot as plt
7. except ImportError:
8. raise ImportError('You need to install matplotlib for plotting.')
9.
10. ## 加载数据集
11. print('加载数据...')
12. df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
13. df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
14.
15. ## 取出特征和标签
16. y_train = df_train[0].values
17. y_test = df_test[0].values
18. X_train = df_train.drop(0, axis=1).values
19. X_test = df_test.drop(0, axis=1).values
20.
21. ## 构建lgb中的Dataset数据格式
22. lgb_train = lgb.Dataset(X_train, y_train)
23. lgb_test = lgb.Dataset(X_test, y_test, reference=lgb_train)
24.
25. ## 设定参数
26. params = {
27. 'num_leaves': 5,
28. 'metric': ('l1', 'l2'),
29. 'verbose': 0
30. }
31.
32. evals_result = {} # to record eval results for plotting
33.
开始训练...')
34. print('
35. ## 训练
36. gbm = lgb.train(params,
37. lgb_train,
38. num_boost_round=100,
39. valid_sets=[lgb_train, lgb_test],
40. feature_name=['f' + str(i + 1) for i in range(28)],
41. categorical_feature=[21],
42. evals_result=evals_result,
43. verbose_eval=10)
44.
45. print(' 在训练过程中绘图...')
46. ax = lgb.plot_metric(evals_result, metric='l1')
47. plt.show()
48.
49. print(' 画出特征重要度...')
50. ax = lgb.plot_importance(gbm, max_num_features=10)
51. plt.show()
52.
53. print(' 画出第84颗树...')
54 l b l t t ( b t i d 83 fi i (20 8) h i f [' lit i '])
牛博带你学AI 搜集整理
54. ax = lgb.plot_tree(gbm, tree_index=83, figsize=(20, 8), show_info=['split_gain'])
55. plt.show()
56.
57. #print(' 用graphviz画出第84颗树...')
58. #graph = lgb.create_tree_digraph(gbm, tree_index=83, name='Tree84')
59. #graph.render(view=True)

1. 加载数据...
2. 开始训练...
3. [10] training's l2: 0.217995 training's l1: 0.457448 valid_1's l2: 0.21641 valid_1's l1: 0.456464
4. [20] training's l2: 0.205099 training's l1: 0.436869 valid_1's l2: 0.201616 valid_1's l1: 0.434057
5. [30] training's l2: 0.197421 training's l1: 0.421302 valid_1's l2: 0.192514 valid_1's l1: 0.417019
6. [40] training's l2: 0.192856 training's l1: 0.411107 valid_1's l2: 0.187258 valid_1's l1: 0.406303
7. [50] training's l2: 0.189593 training's l1: 0.403695 valid_1's l2: 0.183688 valid_1's l1: 0.398997
8. [60] training's l2: 0.187043 training's l1: 0.398704 valid_1's l2: 0.181009 valid_1's l1: 0.393977
9. [70] training's l2: 0.184982 training's l1: 0.394876 valid_1's l2: 0.178803 valid_1's l1: 0.389805
10. [80] training's l2: 0.1828 training's l1: 0.391147 valid_1's l2: 0.176799 valid_1's l1: 0.386476
11. [90] training's l2: 0.180817 training's l1: 0.388101 valid_1's l2: 0.175775 valid_1's l1: 0.384404
12. [100] training's l2: 0.179171 training's l1: 0.385174 valid_1's l2: 0.175321 valid_1's l1: 0.382929

牛博带你学AI 搜集整理

You might also like