从零开始弄懂LightGBM_参数篇

LightGBM 英文文档:https://lightgbm.readthedocs.io/en/latest/index.html
LightGBM 中文文档:https://lightgbm.apachecn.org/
LightGBM 原理可参考:深入理解LightGBM https://blog.csdn.net/program_developer/article/details/103838846

LightGBM是一款快速、分布式、高性能的基于决策树的梯度 Boosting 框架。可用于排序、分类、回归等机器学习任务中。

 

官方参数

以Scikit-learn API 的 LGBMRegressor 为例

# Scikit-learn API
class lightgbm.LGBMRegressor(boosting_type='gbdt', num_leaves=31, max_depth=-1, 
learning_rate=0.1, n_estimators=10, max_bin=255, subsample_for_bin=200000, objective=None, 
min_split_gain=0.0, min_child_weight=0.001, min_child_samples=20, subsample=1.0, 
subsample_freq=1, colsample_bytree=1.0, reg_alpha=0.0, reg_lambda=0.0, random_state=None, 
n_jobs=-1, silent=True, **kwargs)

boosting_type (string__, optional (default="gbdt")) – ‘gbdt’, traditional Gradient Boosting Decision Tree. ‘dart’, Dropouts meet Multiple Additive Regression Trees. ‘goss’, Gradient-based One-Side Sampling. ‘rf’, Random Forest.
默认的就挺好

num_leaves (int__, optional (default=31)) – Maximum tree leaves for base learners.
每个基学习器的最大叶子节点。LightGBM 使用的是 leaf-wise 的算法,因此在调节树的复杂程度时使用的是 num_leaves,它的值的设置应该小于 2^(max_depth)

max_depth (int__, optional (default=-1)) – Maximum tree depth for base learners, -1 means no limit.
每个基学习器的最大深度。当模型过拟合,首先降低max_depth 

learning_rate (float__, optional (default=0.1)) – Boosting learning rate.
梯度下降的步长。常用 0.1, 0.001, 0.003

n_estimators (int__, optional (default=10)) – Number of boosted trees to fit.
基学习器的数量 

max_bin (int__, optional (default=255)) – Number of bucketed bins for feature values.
存储feature的bin的最大数量,对应的是直方图的组数k  

subsample_for_bin (int__, optional (default=50000)) – Number of samples for constructing bins.
用来构建直方图的数据的样本数量

objective (string__, callable or None__, optional (default=None)) – Specify the learning task and the corresponding learning objective or a custom objective function to be used (see note below). default: ‘regression’ for LGBMRegressor, ‘binary’ or ‘multiclass’ for LGBMClassifier, ‘lambdarank’ for LGBMRanker.

min_split_gain(= min_gain_to_split) (float__, optional (default=0.)) – Minimum loss reduction required to make a further partition on a leaf node of the tree.
最小切分的信息增益值

min_child_weight(= min_sum_hessian_in_leaf) (float__, optional (default=1e-3)) – Minimum sum of instance weight(hessian) needed in a child(leaf).
决定最小叶子节点样本权重和(hessian)的最小阈值,若是基学习器切分后得到的叶节点中样本权重和低于该阈值则不会进一步切分,在线性模型中该阈值就对应每个节点的最小样本数。当它的值较大时,可以避免模型学习到局部的特殊样本,防止模型过拟合。但如果这个值过高,又会导致欠拟合

min_child_samples(= min_data_in_leaf) (int__, optional (default=20)) – Minimum number of data need in a child(leaf).
一个叶子节点中最小的数据量,调大可以防止过拟合

subsample (= bagging_fraction)(float__, optional (default=1.)) – Subsample ratio of the training instance.
这个参数控制对于每棵树,在非重复采样的情况下随机采样的比例。减小这个参数的值算法会更加保守,避免过拟合,加快运算速度。但是这个值设置的过小,它可能会导致欠拟合

subsample_freq(= bagging_freq) (int__, optional (default=1)) – Frequence of subsample, <=0 means no enable.
bagging 的频率, 0 意味着禁用 bagging. k 意味着每 k 次迭代执行bagging

colsample_bytree(= feature_fraction) (float__, optional (default=1.)) – Subsample ratio of columns when constructing each tree.
用来控制每棵随机采样的列数的占比(每一列是一个特征)。 调小可以防止过拟合,加快运算速度。典型值:0.5-1范围: (0,1]。一般设置成0.8左右。

reg_alpha(= lambda_l1)(float__, optional (default=0.)) – L1 regularization term on weights.
L1 正则化项的权重系数,越大模型越保守。防止过拟合,提高泛化能力

reg_lambda(= lambda_l2) (float__, optional (default=0.)) – L2 regularization term on weights.
L2 正则化项的权重系数,越大模型越保守。防止过拟合,提高泛化能力

random_state (int or None__, optional (default=None)) – Random number seed. Will use default seeds in c++ code if set to None.
计算机不能产生绝对的随机数,只能产生伪随机数。伪就是有规律的意思。如果每次使用一样的 随机种子,生成的随机数列就是一样的了

n_jobs (int__, optional (default=-1)) – Number of parallel threads.
多线程,表示可以在机器的多个核上并行的构造树以及计算预测值。不过受限于通信成本,可能效率并不会说分为k个线程就得到k倍的提升,不过整体而言相对需要构造大量的树或者构建一棵复杂的树而言还是高效的

silent (bool__, optional (default=True)) – Whether to print messages while running boosting.
在运行过程中是否打印流程

 

官方参数优化建议

针对 Leaf-wise (最佳优先) 树的参数优化

  • num_leaves. 这是控制树模型复杂度的主要参数. 理论上, 借鉴 depth-wise 树, 我们可以设置 num_leaves = 2^(max_depth) 但是, 这种简单的转化在实际应用中表现不佳. 这是因为, 当叶子数目相同时, leaf-wise 树要比 depth-wise 树深得多, 这就有可能导致过拟合. 因此, 当我们试着调整 num_leaves 的取值时, 应该让其小于 2^(max_depth). 举个例子, 当 max_depth=6 时(这里译者认为例子中, 树的最大深度应为7), depth-wise 树可以达到较高的准确率.但是如果设置 num_leaves 为 127 时, 有可能会导致过拟合, 而将其设置为 70 或 80 时可能会得到比 depth-wise 树更高的准确率. 其实, depth 的概念在 leaf-wise 树中并没有多大作用, 因为并不存在一个从 leaves 到 depth 的合理映射.
  • min_child_samplesmin_data_in_leaf). 这是处理 leaf-wise 树的过拟合问题中一个非常重要的参数. 它的值取决于训练数据的样本个树和 num_leaves. 将其设置的较大可以避免生成一个过深的树, 但有可能导致欠拟合. 实际应用中, 对于大数据集, 设置其为几百或几千就足够了.
  • max_depth. 你也可以利用 max_depth 来显式地限制树的深度

针对更快的训练速度

  • 通过设置 subsamplebagging_fraction subsample_freq(= bagging_freq) 参数来使用 bagging 方法进行采样提升训练速度(减小了数据集)
  • 通过设置 colsample_bytree(= feature_fraction)参数来使用特征的子抽样
  • 使用较小的 max_bin,较少的直方图数目
  • 使用 save_binary 将数据集被保存为二进制文件,下次加载数据时速度会变快
  • 通过并行训练来提速

针对更好的准确率

  • 使用较大的直方图数目 max_bin,这样会牺牲训练速度
  • 使用较小的学习率 learning_rate,这样会增加迭代次数
  • 使用较大的 num_leaves,可能导致过拟合
  • 使用更大的训练数据
  • 尝试 dart 模型(Dropouts meet Multiple Additive Regression Trees)

处理过拟合

  • 设置较少的直方图数目 max_bin
  • 设置较小的叶节点数 num_leaves
  • 使用 min_child_samples(min_data_in_leaf) 和  min_child_weight(= min_sum_hessian_in_leaf)
  • 通过设置  subsample(bagging_fraction) 和  subsample_freq(= bagging_freq)来使用 bagging
  • 通过设置 colsample_bytree(feature_fraction) 来使用特征子抽样
  • 使用更大的训练数据
  • 使用 reg_alpha(lambda_l1)reg_lambda(lambda_l2) 和 min_split_gain(min_gain_to_split) 来使用正则
  • 尝试 max_depth 来避免生成过深的树

 

附录1:其它调参参考

XGBoost和LightGBM的参数以及调参 https://www.jianshu.com/p/1100e333fcab
LightGBM算法总结  https://blog.csdn.net/weixin_39807102/article/details/81912566
LightGBM调参笔记 https://blog.csdn.net/u012735708/article/details/83749703

附录2:Hyperopt

使用 Hyperopt 对 LightGBM 进行自动调参 https://zhuanlan.zhihu.com/p/52660316
使用 Hyperopt 进行参数调优 https://www.jianshu.com/p/35eed1567463

附录3:LightGBM原生接口 和 scikit-learn接口 的使用示例

LightGBM原生接口

import lightgbm as lgb
from sklearn import datasets
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn.metrics import roc_auc_score, accuracy_score

# 加载数据
iris = datasets.load_iris()

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3)

# 转换成lgb特征的数据格式
train_data = lgb.Dataset(X_train, label=y_train)
validation_data = lgb.Dataset(X_test, label=y_test)

# 将参数写成字典格式
params = {
    'learning_rate': 0.1,
    'lambda_l1': 0.1,
    'lambda_l2': 0.2,
    'max_depth': 4,
    'objective': 'multiclass',
    'num_class': 3,
}

# 模型训练
gbm = lgb.train(params, train_data, valid_sets=[validation_data])

# 模型预测
y_pred = gbm.predict(X_test)

# 模型评估
print(accuracy_score(y_test, y_pred))

scikit-learn接口

from lightgbm import LGBMRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.externals import joblib
 
# 加载数据
iris = load_iris()
data = iris.data
target = iris.target
 
# 划分训练数据和测试数据
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
 
# 模型训练
gbm = LGBMRegressor(objective='regression', num_leaves=31, learning_rate=0.05, n_estimators=20)
gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1', early_stopping_rounds=5)
 
# 模型存储
joblib.dump(gbm, 'loan_model.pkl')
# 模型加载
gbm = joblib.load('loan_model.pkl')
 
# 模型预测
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)
 
# 模型评估
print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
 
# 特征重要度
print('Feature importances:', list(gbm.feature_importances_))
 
# 网格搜索,参数优化
estimator = 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('Best parameters found by grid search are:', gbm.best_params_)

 

你可能感兴趣的:(机器学习,机器学习)