你应该知道的LightGBM各种操作!

2020 年 10 月 19 日 AINLP

LightGBM是基于XGBoost的一款可以快速并行的树模型框架,内部集成了多种集成学习思路,在代码实现上对XGBoost的节点划分进行了改进,内存占用更低训练速度更快。

LightGBM官网:https://lightgbm.readthedocs.io/en/latest/

参数介绍:https://lightgbm.readthedocs.io/en/latest/Parameters.html

本文内容如下,原始代码获取方式见文末。

  • 1 安装方法

  • 2 调用方法

    • 2.1 定义数据集

    • 2.2 模型训练

    • 2.3 模型保存与加载

    • 2.4 查看特征重要性

    • 2.5 继续训练

    • 2.6 动态调整模型超参数

    • 2.7 自定义损失函数

  • 2.8 调参方法

    • 人工调参

    • 网格搜索

    • 贝叶斯优化

1 安装方法

LightGBM的安装非常简单,在Linux下很方便的就可以开启GPU训练。可以优先选用从pip安装,如果失败再从源码安装。

  • 安装方法:从源码安装

git clone --recursive https://github.com/microsoft/LightGBM ; 
cd LightGBM
mkdir build ; cd build
cmake ..

#
 开启MPI通信机制,训练更快
# cmake -DUSE_MPI=ON ..

#
 GPU版本,训练更快
# cmake -DUSE_GPU=1 ..
make -j4
  • 安装方法:pip安装
# 默认版本
pip install lightgbm

# MPI版本
pip install lightgbm --install-option=--mpi

# GPU版本
pip install lightgbm --install-option=--gpu

2 调用方法

在Python语言中LightGBM提供了两种调用方式,分为为原生的API和Scikit-learn API,两种方式都可以完成训练和验证。当然原生的API更加灵活,看个人习惯来进行选择。

2.1 定义数据集

df_train = pd.read_csv('https://cdn.coggle.club/LightGBM/examples/binary_classification/binary.train', header=None, sep='\t')
df_test = pd.read_csv('https://cdn.coggle.club/LightGBM/examples/binary_classification/binary.test', header=None, sep='\t')
W_train = pd.read_csv('https://cdn.coggle.club/LightGBM/examples/binary_classification/binary.train.weight', header=None)[0]
W_test = pd.read_csv('https://cdn.coggle.club/LightGBM/examples/binary_classification/binary.test.weight', header=None)[0]

y_train = df_train[0]
y_test = df_test[0]
X_train = df_train.drop(0, axis=1)
X_test = df_test.drop(0, axis=1)
num_train, num_feature = X_train.shape

# create dataset for lightgbm
# if you want to re-use data, remember to set free_raw_data=False

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)

2.2 模型训练

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
}

# generate feature names
feature_name = ['feature_' + str(col) for col in range(num_feature)]
gbm = lgb.train(params,
                lgb_train,
                num_boost_round=10,
                valid_sets=lgb_train,  # eval training data
                feature_name=feature_name,
                categorical_feature=[21])

2.3 模型保存与加载

# save model to file
gbm.save_model('model.txt')

print('Dumping model to JSON...')
model_json = gbm.dump_model()

with open('model.json''w+') as f:
    json.dump(model_json, f, indent=4)

2.4 查看特征重要性

# feature names
print('Feature names:', gbm.feature_name())

# feature importances
print('Feature importances:', list(gbm.feature_importance()))

2.5 继续训练

# continue training
# init_model accepts:
# 1. model file name
# 2. Booster()
gbm = lgb.train(params,
                lgb_train,
                num_boost_round=10,
                init_model='model.txt',
                valid_sets=lgb_eval)
print('Finished 10 - 20 rounds with model file...')

2.6 动态调整模型超参数

# decay learning rates
# learning_rates accepts:
# 1. list/tuple with length = num_boost_round
# 2. function(curr_iter)
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('Finished 20 - 30 rounds with decay learning rates...')

# change other parameters during training
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('Finished 30 - 40 rounds with changing bagging_fraction...')

2.7 自定义损失函数

# self-defined objective function
# f(preds: array, train_data: Dataset) -> grad: array, hess: array
# log likelihood loss
def loglikelihood(preds, train_data):
    labels = train_data.get_label()
    preds = 1. / (1. + np.exp(-preds))
    grad = preds - labels
    hess = preds * (1. - preds)
    return grad, hess

# self-defined eval metric
# f(preds: array, train_data: Dataset) -> name: string, eval_result: float, is_higher_better: bool
# binary error
NOTE: when you do customized loss function, the default prediction value is margin
# This may make built-in evalution metric calculate wrong results
# For example, we are doing log likelihood loss, the prediction is score before logistic transformation
# Keep this in mind when you use the customization
def binary_error(preds, train_data):
    labels = train_data.get_label()
    preds = 1. / (1. + np.exp(-preds))
    return 'error', np.mean(labels != (preds > 0.5)), False

gbm = lgb.train(params,
                lgb_train,
                num_boost_round=10,
                init_model=gbm,
                fobj=loglikelihood,
                feval=binary_error,
                valid_sets=lgb_eval)
print('Finished 40 - 50 rounds with self-defined objective function and eval metric...')

2.8 调参方法

人工调参

For Faster Speed

  • Use bagging by setting bagging_fraction and bagging_freq
  • Use feature sub-sampling by setting feature_fraction
  • Use small max_bin
  • Use save_binary to speed up data loading in future learning
  • Use parallel learning, refer to Parallel Learning Guide <./Parallel-Learning-Guide.rst>__

For Better Accuracy

  • Use large max_bin (may be slower)
  • Use small learning_rate with large num_iterations
  • Use large num_leaves (may cause over-fitting)
  • Use bigger training data
  • Try dart

Deal with Over-fitting

  • Use small max_bin
  • Use small num_leaves
  • Use min_data_in_leaf and min_sum_hessian_in_leaf
  • Use bagging by set bagging_fraction and bagging_freq
  • Use feature sub-sampling by set feature_fraction
  • Use bigger training data
  • Try lambda_l1, lambda_l2 and min_gain_to_split for regularization
  • Try max_depth to avoid growing deep tree
  • Try extra_trees
  • Try increasing path_smooth

网格搜索

lg = lgb.LGBMClassifier(silent=False)
param_dist = {"max_depth": [4,5, 7],
              "learning_rate" : [0.01,0.05,0.1],
              "num_leaves": [300,900,1200],
              "n_estimators": [50, 100, 150]
             }

grid_search = GridSearchCV(lg, n_jobs=-1, param_grid=param_dist, cv = 5, scoring="roc_auc", verbose=5)
grid_search.fit(train,y_train)
grid_search.best_estimator_, grid_search.best_score_

贝叶斯优化

import warnings
import time
warnings.filterwarnings("ignore")
from bayes_opt import BayesianOptimization
def lgb_eval(max_depth, learning_rate, num_leaves, n_estimators):
    params = {
             "metric" : 'auc'
        }
    params['max_depth'] = int(max(max_depth, 1))
    params['learning_rate'] = np.clip(0, 1, learning_rate)
    params['num_leaves'] = int(max(num_leaves, 1))
    params['n_estimators'] = int(max(n_estimators, 1))
    cv_result = lgb.cv(params, d_train, nfold=5, seed=0, verbose_eval =200,stratified=False)
    return 1.0 * np.array(cv_result['auc-mean']).max()

lgbBO = BayesianOptimization(lgb_eval, {'max_depth': (4, 8),
                                            'learning_rate': (0.05, 0.2),
                                            'num_leaves' : (20,1500),
                                            'n_estimators': (5, 200)}, random_state=0)

lgbBO.maximize(init_points=5, n_iter=50,acq='ei')
print(lgbBO.max)


由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方"AINLP",进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

欢迎加入AINLP技术交流群
进群请添加AINLP小助手微信 AINLPer(id: ainlper),备注NLP技术交流

推荐阅读

这个NLP工具,玩得根本停不下来

征稿启示| 200元稿费+5000DBC(价值20个小时GPU算力)

完结撒花!李宏毅老师深度学习与人类语言处理课程视频及课件(附下载)

从数据到模型,你可能需要1篇详实的pytorch踩坑指南

如何让Bert在finetune小数据集时更“稳”一点

模型压缩实践系列之——bert-of-theseus,一个非常亲民的bert压缩方法

文本自动摘要任务的“不完全”心得总结番外篇——submodular函数优化

Node2Vec 论文+代码笔记

模型压缩实践收尾篇——模型蒸馏以及其他一些技巧实践小结

中文命名实体识别工具(NER)哪家强?

学自然语言处理,其实更应该学好英语

斯坦福大学NLP组Python深度学习自然语言处理工具Stanza试用

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLPer(id:ainlper),备注工作/研究方向+加群目的。


阅读至此了,分享、点赞、在看三选一吧🙏

登录查看更多
5

相关内容

【经典书】Python金融大数据分析,566页pdf
专知会员服务
119+阅读 · 2020年8月1日
Python图像处理,366页pdf,Image Operators Image Processing in Python
Python导论,476页pdf,现代Python计算
专知会员服务
253+阅读 · 2020年5月17日
【经典书】机器学习高斯过程,266页pdf
专知会员服务
193+阅读 · 2020年5月2日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
94+阅读 · 2019年12月4日
wafw00f 简单利用
黑白之道
10+阅读 · 2019年6月23日
Python3.8新特性概览
Python程序员
4+阅读 · 2018年12月8日
LightGBM 大战 XGBoost,谁将夺得桂冠?
AI研习社
7+阅读 · 2018年4月17日
比xgboost强大的LightGBM:调参指南(带贝叶斯优化代码)
数据挖掘入门与实战
23+阅读 · 2018年4月9日
使用网格搜索优化CatBoost参数
论智
3+阅读 · 2018年4月6日
lightgbm algorithm case of kaggle(上)
R语言中文社区
8+阅读 · 2018年3月20日
Xgboost算法——Kaggle案例
R语言中文社区
13+阅读 · 2018年3月13日
案例 | lightgbm算法优化-不平衡二分类问题(附代码)
如何用TensorFlow和TF-Slim实现图像标注、分类与分割
数据挖掘入门与实战
3+阅读 · 2017年11月17日
Arxiv
0+阅读 · 2020年12月1日
Arxiv
0+阅读 · 2020年11月30日
Arxiv
0+阅读 · 2020年11月30日
Meta-Learning with Implicit Gradients
Arxiv
13+阅读 · 2019年9月10日
VIP会员
相关VIP内容
相关资讯
wafw00f 简单利用
黑白之道
10+阅读 · 2019年6月23日
Python3.8新特性概览
Python程序员
4+阅读 · 2018年12月8日
LightGBM 大战 XGBoost,谁将夺得桂冠?
AI研习社
7+阅读 · 2018年4月17日
比xgboost强大的LightGBM:调参指南(带贝叶斯优化代码)
数据挖掘入门与实战
23+阅读 · 2018年4月9日
使用网格搜索优化CatBoost参数
论智
3+阅读 · 2018年4月6日
lightgbm algorithm case of kaggle(上)
R语言中文社区
8+阅读 · 2018年3月20日
Xgboost算法——Kaggle案例
R语言中文社区
13+阅读 · 2018年3月13日
案例 | lightgbm算法优化-不平衡二分类问题(附代码)
如何用TensorFlow和TF-Slim实现图像标注、分类与分割
数据挖掘入门与实战
3+阅读 · 2017年11月17日
Top
微信扫码咨询专知VIP会员