FB1 WARNING:本文不含LightGBM原理解释,主要讲重要参数(较一般文章多、新)以及演示案例,文章中有相当部分的官网英文,担心自己翻译带有个人色彩,故摘选原文,如果英语太差看起来可能会有点蛋疼。
文章内容:
(1)一些基本介绍 (2)sklearn全部可见参数+少许其他参数 (3)原生接口大部分参数,远多于寻常文章(摘选了比较多,实际上一般情况用不到这么多,相当于记了一个笔记,也加入了一些中文翻译和自己的理解,忘记了可以没事翻一翻,免得看官网看得头皮发麻)
(4)lightgbm的cv方法
众所周知:LightGBM相对XGBoost,有几个特点:
1,Histogram算法:直方图算法,直方图并非light gbm独创,不过用直方图的确快很多;
2,GOSS算法:基于梯度的单边采样算法,大梯度样本+一部分小梯度样本*权重系数
3,EFB算法:互斥特征捆绑算法
4,使用leaf-wise生长策略,叶子结点分裂不是往下生成2个子叶子,而是选择梯度较大的那个,计算代价较小,更精确,但易过拟合(相对level_wise而言)
5,可以直接处理类别特征
6,支持并行学习等等。
写本文的目的:
在网上看到很多文章,写的参数都过时了,很多不能用,估计是版本更新所致,故自己写一个新的,其实参数有非常之多,特别是原生接口的参数字典,这里写一些常用的和不常用的,极其不常用的略。
力求手把手写明白,讲道理中文网上能找到的,比我这个还全的应该很少见。
我们先用案例实现来讲吧。
LightGBM都是来跟XGBoost作比较的:
LightGBM的Sklearn和原生接口的几个明显区别:
区别:原生接口predict,略有区别,二分类中直接给出了label=1的概率,而不是0和1的概率;自定义评估函数时,要返回三个值,多一个布尔值(is higher the better,True or False)不然报错;官网并没有写feval(自定义评估函数)的参数,即只看官网你根本不知道可以自定义评估函数,但自己写个评估函数,传给feval完全没问题且完美运行,即实际上原生接口train里面有feval参数,官网可能漏掉了。
相同处:两个版本接口很多参数名字都是有点神似有叫法不同,模型自带的评估函数,叫法也都看似懂又不确定是不是想要的那个,最好去官网看看。
一、Sklearn风格接口,从简到难,一步步来
sklearn接口,可以看做是原生接口的青春版、简易版,参数少、但基本常用的都有,并且这个接口比较好配合一些网格搜索调参,在问题并不复杂的情况下,就用这个得了,反正还是要调下参。
import sklearn
from sklearn import datasets
from sklearn.model_selection import train_test_split,cross_val_score,KFold
from sklearn.metrics import roc_auc_score,mean_squared_error,accuracy_score
import numpy as np
from matplotlib import pyplot as plt
import lightgbm as lgb
import pickle
from scipy.stats import rankdata
pd.options.display.max_columns=35
import pandas as pd
# 载入数据及前期处理
breast_cancer = datasets.load_breast_cancer(as_frame=True)
data = breast_cancer.data
target = breast_cancer.target
# 划分训练集和测试集
x_train,x_test,y_train,y_test
=train_test_split(data,target,test_size=0.2, random_state=1024,stratify=target)
1.1模型实例化参数
from lightgbm import LGBMClassifier
model_light = LGBMClassifier
(boosting_type='gbdt',num_leaves=31,max_depth=8
,learning_rate=0.1,n_estimators=1000,objective='binary'
,class_weight=None,min_child_weight=1e-4,min_child_samples=5
,subsample=0.8,subsample_freq=4
,colsample_bytree=0.8,reg_lambda=1
,random_state=1,n_jobs=-1,importance_type='gain')
咱们按照顺序挨个说: 有个黑方块即参数讲解,因为写这文章的逻辑顺序大改过一次,参数干脆不标序号了。
█boosting, default =gbdt, options:gbdt,rf,dart ,aliases:boosting_type,boost
既然用lightgbm,一般得选GBDT或者dart,随机森林肯定PASS掉;
DART会丢弃一些树,并将未被丢弃的树的预测值进行一定的权重变化,因为据研究GBDT存在过度专门化(over-specialization)的问题,请单独查看关于dart的文章。实测在sklearn接口中,这些半隐藏的参数,还是可以传进去的,但名字一定要写对,虽然说明文档也写了传‘多余’的参数进去可能引发未知问题,但这只是很保守的说法;
如使用dart,则产生相关的参数:
1 drop_rate , default = 0.1, type = double, aliases: rate_drop, constraints: 0.0 <= drop_rate <= 1.0
dropout rate: a fraction of previous trees to drop during the dropout
2 max_drop , default = 50, type = int
max number of dropped trees during one boosting iteration
3 skip_drop , default = 0.5, type = double, constraints: 0.0 <= skip_drop <= 1.0
probability of skipping the dropout procedure during a boosting iteration
4 xgboost_dart_mode , default = false, type = bool
set this to true, if you want to use xgboost dart mode
5 uniform_drop︎ , default = false, type = bool
set this to true, if you want to use uniform drop
6 drop_seed ︎, default = 4, type = int
random seed to choose dropping models
Note: internally, LightGBM uses gbdt mode for the first 1 / learning_rate iterations
█num_leaves ,default =31 ,这个数字最大值为2**max_depth -1 ,相当于在最大深度已限制的情况下,进一步防止过拟合,要设置在上限之下,lightgbm的叶子结点,是选择分裂增益大的那一边往下分(leaf_wise),所以在叶子结点总数相同的情况下,比XGBOOTS(level-wise)肯定要深很多,所以这个参数也是重要的要调参数。
█max_depth 最大深度,default =-1 ,<=0 means no limit,树模型调参重要参数。
在用sklearn接口时,会报这个警告,说你没有显示地指定这个>那个,这就无语了,忍忍吧。
【Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves.】
█learning_rate 学习率,一般0.1就算不小了,也是重要参数。
█n_estimators : int, optional (default=100),树的多少课或者叫迭代次数,skelarn接口并没有early_stop这种参数,但实际运行中,程序会报警告,说没有分裂增益了,会自动停止,看来属于内置了,所以设大点没问题。
█(不太重要)subsample_for_bin, int (default= 200000) 构建列直方图时,每个特征都会被分箱,此参数控制单个特征的单个箱子所能容纳的最多样本数。
-
number of data that sampled to construct feature discrete bins
-
setting this to larger value will give better training result, but may increase data loading time
-
set this to larger value if data is very sparse
-
Note: don’t set this to small values, otherwise, you may encounter unexpected errors and poor accuracy
█objective, default =regression ;可选的如下options:regression,regression_l1,huber,fair,poisson,quantile,mape,gamma,tweedie,binary,multiclass,multiclassova,cross_entropy,cross_entropy_lambda,lambdarank,rank_xendcg, aliases:objective_type,app,application,loss
-
回归用:regression,默认L2 LOSS,即MSE。
还有regression_l1,即mean_absolute_error,huber(综合MSE、MAE的一种)还有fair,poisson,quantile,mape,gamma,tweedie。
-
分类用:binary,二分类,要求标签是{0,1};
-
多分类,multiclass,num_class should be set as well,同时要告诉模型你有多少个类别。
还有multiclassova,cross_entropy,cross_entropy_lambda。
-
排序lambdarank,rank_xendcg
█ class_weight:dict, 'balanced' or None, optional (default=None)样本权重,按说明文档,多分类则指定该参数,balanced则自动,比如三类,0类10个,1类90个,2类900个,则自动将0类权重设为1000/10=100,1类为1000/90,2类为1000/900,该权重会乘在交叉熵损失函数前面,在不断迭代降低损失函数过程中,一个数值前面顶着一个很大的系数,会被优先照顾,一般设置了权重,则模型会重点找全这个类别,但隐患是可能会增加误判,简称召回棒棒哒、精确率血崩。如果传字典就要一一对应,比如{'0':100,'1':11,'2':1.1},默认无,大家都是1。
当然多分类别忘了 ▲num_class ,多分类指定有多少类别
如果是二分类,文档说明建议用:
█ is_unbalance,default =false, type = bool,正负比例是否均衡,设为TRUE,算法会自动平衡权重。
-
used only in binary and multiclassova applications
-
set this to true if training data are unbalanced
-
Note: while enabling this should increase the overall performance metric of your model, it will also result in poor estimates of the individual class probabilities
-
Note: this parameter cannot be used at the same time with scale_pos_weight, choose only one of them
█scale_pos_weight , default = 1.0, type = double, constraints: scale_pos_weight > 0.0,这个值的设置,比如样本中0有2000个,1有40个,则设为50。(=neg numbers/pos numbers)
-
used only in binary and multiclassova applications
-
weight of labels with positive class
-
Note: while enabling this should increase the overall performance metric of your model, it will also result in poor estimates of the individual class probabilities
-
Note: this parameter cannot be used at the same time with is_unbalance, choose only one of them
█min_split_gain,默认为0, the minimal gain to perform split,由于boosting算法训练中,会不断拟合残差,所以这个参数,不是特别好控制,如果出现过拟合,则尝试设置此值,一般先设得很小,再不停地试,就是下图右边那个gamma
█ min_child_weight , default = 1e-3, type = double,
minimal sum hessian in one leaf. Like min_data_in_leaf, it can be used to deal with over-fitting
用叶子的二阶导计算的数字,如果这个值设得越小,忽略其他参数的情况下,要求叶子更纯,如果达不到这么纯则可以继续分裂。
█min_child_samples,default =20, type = int, 一个叶子结点最少的样本数量
-
minimal number of data in one leaf. Can be used to deal with over-fitting.
-
Note: this is an approximation based on the Hessian, so occasionally you may observe splits which produce leaf nodes that have less than this many observations
同XGBOOST一样,是目标函数二阶导的和,在回归问题中,单个样本的二阶导是1,比较好理解和控制,设成多少,就是该结点最少样本数;在分类中,单个样本的二阶导,是sigmoid(1-sigmoid),一个数在0-1之间,相乘的最大值为0.5乘0.5,在后面的树中,如果该结点已经很确定标签是0还是1,则单个样本的sigmoid(1-sigmoid)值会很小,分类问题中,该值并不是特别好控制,如果将此参数设置得相对小,则要求一个叶子结点相对越“纯”,取值越"确定",如果还不够“纯”和"确定"就可以继续分裂,此参数太小则会过拟合(单论该参数而言,实际有其他参数同时控制过拟合),极限(不管其他参数的理想状态下)就是设为0,一直分裂到每个叶子结点都只有1个样本。
█subsample,行采样比例,0-1之间,一般设个0.6~0.8左右,有助于加快速度和控制过拟合,也是不放回抽样。
Note: to enable bagging, bagging_freq should be set to a non zero value as well
可知,设置行采样的同时,也要设置重新行采样迭代间隔次数。
█subsample_freq ,default =0, type = int, aliases:
0 means disable bagging; k means perform bagging at every k iteration. Every k-th iteration, LightGBM will randomly select bagging_fraction * 100 % of the data to use for the next k iterations。
这个算是个小创新,随机森林、xgboost都是每棵树重新采样一遍行,此处可以设置隔多少次迭代再重新采样行。
█colsample_bytree, 列采样比例,和行采样差不多,type = double,
对比 1.随机森林 2.XGBOOST 3.LightGbm的行抽样选择
# 行抽样对比
1.随机森林:默认bootstrap放回抽样,样本较多的情况,约有1/e约0.368的数据不会被抽到,直接可用作验证数据,不能进行不放回抽样,bootstrap设为false则直接用全部样本;
2.XGBOOST:有个subsample行抽样,是不放回抽样(不能进行放回抽样,如上例,8000个样本绝对不重复) ,当然还有平均抽样和按梯度抽样参数sampling_method
3.LightGbm: 也是不放回抽样,多了个隔多少次迭代重新抽样的参数bagging_freq,当然还有个正负样本抽样比例
# 列抽样对比
比如特征列有100列,我们将第一级列抽样参数设为0.6
1.随机森林: 每次分裂,考虑的列数为0.6*n_feature_in,每次分裂前都会选择一次,意味着每次分裂每个特征都有机会被选中然后遍历阈值进行分裂收益对比。
2.XGBOOST:每次建树之前,根据colsample_bytree先抽60个特征,其他40个特征在这棵树就不会出现,
当然还有colsample_bylevel,by_node这种二级、三级抽样参数;
3.LightGbm:也是建树之前按比例抽,同XGBOOST,有二级feature_fraction_bynode参数,
官网特别说明了这个二级参数并不会加快训练,一级列抽样参数可以。
# 如果看不明白得去官网看英文原文,其实看不看得明白根本无所谓,反正用就行了
█reg_alpha ,L1正则化,如果要用则必须>=0 。
█reg_lambda ,L2正则化,如果要用则必须>=0
█random_state,固定行、列抽样,一般行列都会选一大部分进行抽样,多次多折时,为保证一致,经常要固定种子。
█n_jobs ,default =0 ,0 means default number of threads in OpenMP;
即默认开启全核心训练,据说多台机器并行训练,得留出一些核心用于机器之间的通讯。
█importance_type: str, optional (default='split')
特征重要性计算方式,一个是算用到过多少次,一个是算分裂带来的增益,树模型在此处有个问题,就是一个特征一旦被使用,特别是第一个,往往会造成很高的增益,比如feature-A实际上只比feature-B,划分增益高一点,但模型肯定选了A,那么下一步B带来的增益会减很多,实际上B只比A稍微弱一点,但算gain的话,B会比A少很多,虽然随机抽列会降低这个影响,但并不能完全消除。
The type of feature importance to be filled into ``feature_importances_``. If 'split', result contains numbers of times the feature is used in a model. If 'gain', result contains total gains of splits which use the feature.
█**kwargs ,warning:\*\*kwargs is not supported in sklearn, it may cause unexpected issues.
☀☀☀经过实测,sklearn接口,虽然看起来参数少,但实际上可以传很多说明文档中没写的参数进去,前提是你了解原生接口的参数,所以这个简易版接口,似乎并没有看起来那么简单,这个警告只是一个很保守的说法☀☀☀
1.2 fit参数
model_light.fit(x_train,y_train,eval_set=[(x_train, y_train),(x_test,y_test)]
,eval_metric=[('auc','binary_error')],eval_names=['heihei','hehe'])
█ x █y,训练要传入的数据
█(不太重要)sample_weight , (default=None)这个同class_weight一样,如果两个都设置的话,会相乘,一般我们习惯只用class_weight
█(不太重要)init_score ,模型第一棵树,各个样本的初始值,其实不用传,因为模型迭代多了,就算初始值偏得十万八千里远,结果还是会掰正回来,硬要传要跟y_train形状一致。
█eval_set ,只传测试集,或者训练、测试都放进去,这样可以看到训练过程的损失不断降低。
█(不太重要)eval_names ,给eval_set 起个名字,没什么卵用。
█(不太重要)eval_sample_weight ,测试集权重,list of array (same types as ``sample_weight`` supports) (default=None)
█eval_class_weight,Class weights of eval data,还有一层,这关于权重的参数真多。
█(不太重要)eval_init_score,list of array (same types as ``init_score`` supports), or None, optional (default=None),测试集每个数据初始值,不用管这个。
█eval_metric,█metric,这个是个重点,在这里把两种接口的都说了。
训练过程中,一般的回归、分类都是让损失函数变小,但是评估模型的好坏的指标,可以自己指定,比如二分类有accuracy,auc,recall,回归有MSE、带百分比的rmspe等。模型自带的评估函数,和自定的评估函数可以一起和谐友好地使用,不建议写一大堆,两三个一般足够,毕竟都要计算拉长训练时长。该metric和sklearn里面的metrics,很多名字不一样,有时还得去官网查查要用的metric到底叫啥。
Parameters — LightGBM 4.3.0.99 documentation在官网搜索 Metric Parameters
█(不太重要)feature_name,list of str, or 'auto', optional (default='auto'), If 'auto' and data is pandas DataFrame, data columns names are used。基本不用管。
█(亮点)categorical_feature,list of str or int, or 'auto', optional (default='auto')
指定无序类别特征,都知道xgboost是不支持直接用类别特征的,类别特征一般分两种,一种是有序的比如说是0,1,2,3这样,这种类别特征比较好,直接丢进模型都没问题;另一种是比如财富等级,rich,poor,normal这种,基本是纯字符串,需要提前处理才能给xgboost喂;而lightgbm可以指定这些特征,哪些是无序类别型的,如果类别型特征很多,可以尝试使用,但大部分情况下,我们都会在数据预处理阶段,手动处理这些类别特征,用法自己看说明文档,不好写。
█callbacks,一般不怎么用这个,可以调整学习率之类的。
█init_model,模型位置,有已经保存的模型可以接着训练,或者直接预测,不过预测前要在这里fit一下,速度会很快。
个人认为,就X,Y,eval_set ,eval_metric,init_model常用。
1.3 predict参数
y_pred_label = model_light.predict(x_test)
█(不太重要)start_iteration ,int, optional (default=0)
If <= 0, starts from the first iteration,一般不动
█(不太重要)num_iteration ,int or None, optional (default=None)
Total number of iterations used in the prediction. If None, if the best iteration exists and start_iteration <= 0, the best iteration is used; otherwise, all iterations from ``start_iteration`` are used (no limits). If <= 0, all iterations from ``start_iteration`` are used (no limits).
这一看就给你设置好了,也不用动,除非你硬是要用全部迭代次数。
█(高阶应用)pred_leaf : bool, optional (default=False),如果设置为true,则返回给你这个样本,落在每棵树的哪个叶子上,是个index, shape=(len(x_test,num_iters)),有什么用呢?
在高维稀疏特征上,假设有n棵树,每个样本铁定落在其中一棵树的某一个叶子结点上,假设总共有m个叶子结点,那么每个样本可以变成一个1*m的向量,每个样本落在每颗树的哪个叶子节点,这也是一个新的特征,相当于特征衍生了,一般学到推荐系统就懂啦。
█(不太重要)pred_contrib,bool, optional (default=False),如果设置为true,则会返回一个shape(n_samples,n_classes,n_features +1)的数组,对每个预测数据,返回每个特征的贡献值,其实不需要用到,要了解的话,请查看SHAP值相关内容。
█(不太重要)validate_features ,验证预测数据集的特征列名,是否和fit训练过程中,传入的列名完全一致,数量不一致或者名称,多个空格都会报错,不太建议开启。
1.4 predict_prob
区别就是预测概率值了,一般想自由控制阈值的话,要手动切个片;
1.5 补充几个重要属性:
model_light.feature_name_ 获取训练数据列名
model_light.feature_importances_ 获取特征列重要性
# 一一对上
dict(zip(model_light.feature_name_,model_light.feature_importances_))
二、原生train方法:
2.1 转为Dataset数据格式
# 转换为Dataset数据格式
lgb_train = lgb.Dataset(x_train, y_train)
lgb_eval = lgb.Dataset(x_test, y_test, reference=lgb_train)
下面精炼简短点说,首先█data,█label 两个自不必说,在验证数据集上,有说明一般都要加上█reference=lgb_train;,既然这么说就加上。
█weight即给数据添加权重,不过不能用字典写,必须有个列表|数组一一对应;
█ group,█position排序问题才会用到;
█ init_score,初始值,无影响,不建用;
█ feature_name ,█ categorical_feature ,上面fit方法已说明;
█ free_raw_data ,bool, optional (default=True)别动它,用完数据就释放坑位解除占用。
2.2构造参数字典
一下子把大部分情况下,会用到的参数全写出来,其实根本用不到这么多,主打一个演示:
没用过lightgbm看到肯定得懵逼,如果你对其中一些参数不理解,可以参考下我夹杂在参数中的说明和理解。
# 参数dict
params = {
# 核心参数
'objective': 'binary',
'boosting_type': 'gbdt',
'data_sample_strategy':'bagging',
'metric': ['auc','binary_error'],
'num_iterations':300,
'learning_rate': 0.05,
'num_leaves': 63,
'tree_learner':'serial',
'nthread': -1,
'device_type':'cpu',
'seed':996,
# 训练控制参数
'force_row_wise':True,
'max_depth':6,
'min_data_in_leaf':5,
'min_samples_leaf':1e-3,
'min_sum_hessian_in_leaf':1e-3, # 搞不懂同样的东西为什么有两个
'bagging_fraction':0.8,
'bagging_freq':5,
'bagging_seed':9527,
'feature_fraction':0.8,
'feature_fraction_bynode':1,
'feature_fraction_seed':1414,
'early_stopping_round':5,
'first_metric_only':True,
'max_delta_step':0, # 设为0,该参数不好控制
'lambda_l2':1,
'min_gain_to_split':1e-1,
'feature_contri':None, # 特征增益控制不设
'path_smooth':2, # 叶子权重平滑
'verbosity': 0,
'use_quantized_grad':False,
# IO 参数
'max_bin':200,
'min_data_in_bin':5,
'data_random_seed':8848,
'is_enable_sparse':True,
'enable_bundle':True,
}
没有离散无序特征,dart,排序等相关参数,具体还是要看官网,参数是真多:
# 自定义评估函数
def accuracy1(preds, train_data):
labels = train_data.get_label()
preds = 1. / (1. + np.exp(-preds))
return 'accuracy', np.mean(labels == (preds > 0.5)), True
# 训练+预测
model = lgb.train(params,train_set=lgb_train,num_boost_round=200,valid_sets=lgb_eval
,valid_names='nonsense',feval=accuracy1)
y_ = model.predict(x_test)
y_
参数、分不同任务不同数据集不同传入方式等,有很多,具体参考---官网链接:
Core Parameters核心参数:
█objective-------------------同Sklearn中的
█boosting-------------------同Sklearn中的boosting_type
█data_sample_strategy , default = bagging, options: bagging, goss
bagging就和随机森林、XGBOOST一样,进行行抽样;
baggingis only effective whenbagging_freq>0(隔几个树重新行采样)andbagging_fraction<1.0(样本不放回抽样比例),默认使用bagging,比较不同的是,多了一个隔几棵树重新行采样,随机森林、XGB都是每棵树都按照行比例抽样。
▲goss, Gradient-based One-Side Sampling----这就是传说中的单边梯度采样,light gbm的名字由来,跟GOSS有很大关系,如果用了goss,则不可用行抽样和行抽样间隔,但是可以用列抽样。
与GOSS相关,亦产生两个参数:
▲top_rate:default=0.2, type=double
仅仅在 goss 时使用, 大梯度数据的保留比例
▲other_rate:default=0.1, type=int
仅仅在 goss 时使用, 小梯度数据的保留比例
比如样本数量总共100万,取前20%的大梯度样本,小梯度样本取10%,但是这样的信息增益会变少,如何解决,就是 1−�� ,(1-20%)/0.1,小梯度样本权重变为8倍,差不多可以近似还原本来的信息度。
█num_iterations ,default =100 迭代次数,在model.train()中,有个num_boost_round,也是迭代次数,实测参数字典中的num_iterations优先级要高一些,即是两个地方都设置了,会用参数字典里面那个。
█learning_rate,学习率
█(不重要)tree_learner:default =serial ,是否多个机器分布式计算,单人单机可直接忽略这个参数
-
serial, single machine tree learner 单机,默认值
-
feature, feature parallel tree learner, aliases: feature_parallel 特征并行
-
data, data parallel tree learner, aliases: data_parallel 数据并行
-
voting, voting parallel tree learner, aliases: voting_parallel 投票并行
-
refer to Distributed Learning Guide to get more details
█device_type ,default =cpu ,options:cpu,gpu,cuda(选CPU还是显卡,lightgbm因为比较快,一般CPU可以搞定)
-
cpu supports all LightGBM functionality and is portable across the widest range of operating systems and hardware
-
cuda offers faster training than gpu or cpu, but only works on GPUs supporting CUDA
-
gpu can be faster than cpu and works on a wider range of GPUs than CUDA
据说可以用AMD的显卡,没试过。
█(不重要)deterministic default =false, type = bool,当用不同版本、不同机器时让结果固定不变,看说明文档,大意是写着不用管这东西,并且setting this totruemay slow down the training。
-
used only with cpu device type
-
setting this to true should ensure the stable results when using the same data and the same parameters (and different num_threads)
█ seed ,this seed is used to generate other seeds, e.g. data_random_seed, feature_fraction_seed, etc.
这个种子优先级别比较低,如果设置了其他专门的种子,则会优先用其他种子。
█num_threads ,default =0 ,-------------------同Sklearn中的n_jobs ,aliases:num_thread,nthread,nthreads,n_jobs
Learning Control Parameters
█force_col_wise 和force_row_wise,两个参数只能选一个而且必须选一个为TRUE,而且实际运行必然一个为True,即传说中的直方图算法,而且必须用直方图。
█force_col_wise , default = false, type = bool used only with cpu device type
set this to true to force col-wise histogram building
enabling this is recommended when: 列直方图推荐场景
-
the number of columns is large, or the total number of bins is large
-
num_threads is large, e.g. > 20
-
you want to reduce memory cost
Note: when both force_col_wise and force_row_wise are false, LightGBM will firstly try them both, and then use the faster one. To remove the overhead of testing set the faster one to true manually。
从官方说明文档可知,LightGBM肯定会用列直方图、行直方图中的一种,如果两个参数都没有设,默认False,则会两个都试一下,会选择速度快的那一个,所以最好还是选定一个设置!不管行、列直方图,肯定会比不用直方图预排序快,列WISE减少内存占用,适合CPU核心超多的,行WISE会DOUBLE内存占用,适合CPU核心没有那么多的。
█force_row_wise,default =false, type = bool
used only with cpu device type
set this to true to force row-wise histogram building
enabling this is recommended when:行直方图推荐场景
-
the number of data points is large, and the total number of bins is relatively small
-
num_threads is relatively small, e.g. <= 16
-
you want to use small bagging_fraction or goss sample strategy to speed up
-
Note: setting this to true will double the memory cost for Dataset object. If you have not enough memory, you can try setting force_col_wise=true
-
Note: when both force_col_wise and force_row_wise are false, LightGBM will firstly try them both, and then use the faster one. To remove the overhead of testing set the faster one to true manually
█(不重要)histogram_pool_size , default =-1.0 ,max cache size in MB for historical histogram,< 0 means no limit。内存限制
█max_depth 最大深度,-------------------同Sklearn中的
█min_data_in_leaf,default =20, type = int--------------同Sklearn中的min_child_samples最小叶子样本数量
█min_samples_leaf,叶子结点二阶导之和,如果叶子结点已经分得比较纯了,再往下分,值小于这个,就不会再分裂。实测,如果分类问题,设置了min_data_in_leaf和min_samples_leaf,min_data_in_leaf优先级高一些。
>>>[Warning] min_data_in_leaf is set=5, min_samples_leaf=0.001 will be ignored. Current value: min_data_in_leaf=5
█min_gain_to_split,默认为0-------------------同Sklearn中的min_split_gain
█min_sum_hessian_in_leaf , default = 1e-3, type = double-------------------我个人的理解是和min_data_in_leaf是一个道理,都是叶子里面二阶导之和,回归的单个样本二阶导是1,分类的二阶导是sigmoid*(1-sigmoid),咱就说,一个参数完全控制叶子结点样本数,一个参数控制二阶导之和,可以理解,但这里又多一个,就有点让人捉摸不透,也可能是我只用过分类和回归,在其他任务里,可能有不同的作用!
█baggng_fraction,-------------------同Sklearn中的subsample
█bagging_freq, -------------------同Sklearn中的subsample_freq
█pos_bagging_fraction, █neg_bagging_fraction,正负样本采样比例,只在二分类中使用,在处理样本不平衡时使用, 默认都是1,表示disable,要用则两个都要设置,同时bagging_freq 也要设。
used for imbalanced binary classification problem, will randomly sample #pos_samples * pos_bagging_fraction positive samples in bagging, will randomly sample #neg_samples * neg_bagging_fractionnegative samples in bagging 意思是二分类,样本不平衡,直接设置正负样本的采样比例,两个要设都一起设, 并且会忽略bagging_fraction行采样比例这个参数。
-
Note: if both pos_bagging_fraction and neg_bagging_fraction are set to 1.0, balanced bagging is disabled
-
Note: if balanced bagging is enabled, bagging_fraction will be ignored
█bagging_seed ,default =3,random seed for bagging,固定行抽样结果的种子,多次运行进行结果比对,经常需要固定住种子。
█feature_fraction, 列采样比例-------------------同Sklearn中的colsample_bytree
█feature_fraction_bynode,子节点列采样比例,如果特征列非常多,可以考虑用, 例如数据本身一万个特征列,列采样选了8000行,下一级结点再乘0.8,再下一级再乘0.8,以此类推。官网特别说明了,这个并不能像列采样一样加速训练。
Note: unlike feature_fraction, this cannot speed up training
Note: if both feature_fraction and feature_fraction_bynode are smaller than 1.0, the final fraction of each node is feature_fraction * feature_fraction_bynode
█feature_fraction_seed , default =2,random seed for feature_fraction,固定列抽样种子。
█(不重要可忽略)extra_trees ,default =false, type = bool是否开启极限森林模式,听着就不是很聪明,if set to true, when evaluating node splits LightGBM will check only one randomly-chosen threshold for each feature,---------------------不建议用,极限森林是为每一个特征,随便瞎几把选一个分裂点(阈值threshold),然后对比分裂增益,在这些矮个里,挑最好的一个作为分裂条件,这里应该也是如此。同时还有一个extra_seed, random seed for selecting thresholds when extra_trees is true。
█early_stopping_round ,default =0, type = int,will stop training if one metric of one validation data doesn’t improve in last early_stopping_round rounds,重要,一般都要设置此参数,先把迭代次数搞大点,相当于设个berak机制。(许多两三年前的文章,都将此参数放在.train(early_..=20)里面,现在可能更新了,实测只能放字典里面不然报错)aliases:early_stopping_rounds,early_stopping,n_iter_no_change
█first_metric_only,default =false, type = bool, 配合early_stopping_round使用,如果有多个evaluation metrics(即参数字典里的metric),设为True则只用第一个,默认是只要评估函数列表里有一个没有变化,就会停止,这样可使模型更加专注你需要的那个结果;
█max_delta_step,default =0.0, type = double,限制每次迭代生成的树的叶子结点的结果最大值,the final max output of leaves is learning_rate * max_delta_step, 由于不太好控制,一般都不会优先考虑设此参数。
█lambda_l1,L1正则化,如果要用则必须>=0
█lambda_l2 ,L2正则化,如果要用则必须>=0
----------------------离散特征专属----------------
都知道Lightgbm可以直接处理离散特征,查看下面参数max_cat_to_onehot可猜测,如果类别特征,只有少数几个类别,则直接one_hot,如果太多,可能是转为数字0-n。
没自己测试过,原文抄下来,以后再研究!
█min_data_per_group , default = 100, type = int, constraints: min_data_per_group > 0 minimal number of data per categorical group
█max_cat_threshold,default =32, type = int.
-
used for the categorical features
-
can be used to speed up training
-
limit number of split points considered for categorical features.
-
See the documentation on how LightGBM finds optimal splits for categorical features for more details
█cat_l2,default =10.0, type = double,constraints:cat_l2>=0.0,
-
used for the categorical features
-
L2 regularization in categorical split
█cat_smooth,default =10.0,type = double, constraints:cat_smooth>=0.0,used for the categorical features.
this can reduce the effect of noises in categorical features, especially for categories with few data。
█max_cat_to_onehot 🔗︎, default = 4, type = int, constraints: max_cat_to_onehot > 0,when number of categories of one feature smaller than or equal to max_cat_to_onehot, one-vs-other split algorithm will be used
下面这个参数,可能有的时候比较重要,特征绑定:
█interaction_constraints, default ="", type =string
-
controls which features can appear in the same branch
-
by default interaction constraints are disabled, to enable them you can specify
-
for Python-package, list of lists, e.g. [[0, 1, 2], [2, 3]]
-
any two features can only appear in the same branch only if there exists a constraint containing both features
图来源 https://zhuanlan.zhihu.com/p/99069186
█verbosity, default =1,type = int, aliases:verbose < 0: Fatal, = 0: Error (Warning), = 1: Info, > 1: default =1,
Debug(许多以前的文章有silent,verbose_eval等类似xgboost里的参数,实测LGB里根本不叫这个名字,可能是版本更新替换掉了,可以用verbosity或者verbose,在sklearn里面用亦可,)
█(认为不太需要用到)feature_contri ︎, default = None, type = multi-double, aliases: feature_contrib, fc, fp, feature_penalty
-
used to control feature’s split gain, will use gain[i] = max(0, feature_contri[i]) * gain[i] to replace the split gain of i-th feature
-
you need to specify all features in order
█path_smooth︎, default = 0, type = double, constraints: path_smooth >= 0.0 这个看起来是一个船新的控制叶子结点权重的参数,LightGbm的叶子结点公式同xgboost如下:
-
controls smoothing applied to tree nodes
-
helps prevent overfitting on leaves with few samples
-
if set to zero, no smoothing is applied
-
if path_smooth > 0 then min_data_in_leaf must be at least 2
-
larger values give stronger regularization
-
the weight of each node is w * (n / path_smooth) / (n / path_smooth + 1) + w_p / (n / path_smooth + 1), where n is the number of samples in the node, w is the optimal node weight to minimise the loss (approximately -sum_gradients / sum_hessians), and w_p is the weight of the parent node
-
note that the parent output w_p itself has smoothing applied, unless it is the root node, so that the smoothing effect accumulates with the tree depth
█use_quantized_grad,default =false, type = bool,是否使用分位数梯度计算。
-
whether to use gradient quantization when training
-
enabling this will discretize (quantize) the gradients and hessians into bins of num_grad_quant_bins
-
with quantized training, most arithmetics in the training process will be integer operations
-
gradient quantization can accelerate training, with little accuracy drop in most cases
-
Note: can be used only with device_type = cpu
-
New in version 4.0.0
这个相当于对一阶导、二阶导进行了分位数化,相当于在直方图分箱的基础再,再变得粗糙一些。
█num_grad_quant_bins ,default =4, type = int,设置用多少个分位数。
-
number of bins to quantization gradients and hessians
-
with more bins, the quantized training will be closer to full precision training
-
Note: can be used only with device_type = cpu
-
New in 4.0.0
应该是配上上一个参数使用的,但是不用四个分位分,IQR怎么计算?
█quant_train_renew_leaf 🔗︎, default = false, type = bool,
-
whether to renew the leaf values with original gradients when quantized training
-
renewing is very helpful for good quantized training accuracy for ranking objectives
-
Note: can be used only with device_type=cpu
还是配上上个参数,在算叶子结点值的时候,把分位数化的一阶导、二阶导,转回原始的数据。
█stochastic_rounding 🔗︎, default = true, type = bool,当开启分位数梯度计算时,是否随机舍入,猜一下,可能是在四舍五入和floor round,ceil round之间,每次都随机三选一吧,默认是开,就不管了。
whether to use stochastic rounding in gradient quantization
IO Parameters
█max_bin , default =255 ,列的直方图,最大箱子数
-
max number of bins that feature values will be bucketed in
-
small number of bins may reduce training accuracy but may increase general power (deal with over-fitting)
█max_bin_by_feature , default =None ,个人理解,该参数是传入一个list或者字典,给每个特征指定bins,不过一般用Lightgbm都是特征多样本多,这参数估计不常用。
-
max number of bins for each feature
-
if not specified, will use max_bin for all features
█min_data_in_bin, default =3
-
minimal number of data inside one bin
-
use this to avoid one-data-one-bin (potential over-fitting)
█bin_construct_sample_cnt , default = 200000, type = int,-------------------同Sklearn中的subsample_for_bin,控制单个特征的单个箱子所能容纳的最多样本数。
█data_random_seed , default = 1, type = int, aliases: data_seed,构建直方图的seed,固定住可用于对比结果。
-
random seed for sampling data to construct histogram bins
█is_enable_sparse, default =true ,是否优化稀疏的特征,很多高维数据,很多都是0,1这种,但并没有解释怎么优化,而且并非互斥捆绑算法,反正默认开着就开着呗。
█enable_bundle,default =true,这就是传说中的互斥捆绑算法Exclusive Feature Bundling (EFB),看来参数都是默认开启了高性能快速模式。
Note: disabling this may cause the slow training speed for sparse datasets
█feature_pre_filter,default =true, type = bool
-
set this to true (the default) to tell LightGBM to ignore the features that are unsplittable based on min_data_in_leaf
-
as dataset object is initialized only once and cannot be changed after that, you may need to set this to false when searching parameters with min_data_in_leaf, otherwise features are filtered by min_data_in_leaf firstly if you don’t reconstruct dataset object
-
Note: setting this to false may slow down the training
-
按照文档解释,这个属于是预先过滤,比如min_data_in_leaf默认是20,而你几百万的数据中,有那么几个特征是只有19个是0,其余全是1,即可看做是异常值或者数据采集错误;或者更调皮的特征,比如19个1、2、3一直往下加到所有样本,这种特征即可提前过滤掉;同时也提醒了,调参的时候,要关掉此参数,因为会预先过滤特征。
█two_round ,default =false,
-
set this to true if data file is too big to fit in memory
-
by default, LightGBM will map data file to memory and load features from memory. This will provide faster data loading speed, but may cause run out of memory error when the data file is very big
-
Note: works only in case of loading data directly from text file
如果数据太大,内存不够,设为TRUE,应该较少用到。
█categorical_feature ,lightgbm的优势之一是它可以很好地处理分类特性,可以手动指定。如果很多,有段代码比较好用-----data.select_dtypes('object').columns.tolist(),直接变成列表放进去,其实就相当于自带了一个LabelEncoder()而已。
-
used to specify categorical features
-
use number for index, e.g. categorical_feature=0,1,2 means column_0, column_1 and column_2 are categorical features
-
add a prefix name: for column name, e.g. categorical_feature=name:c1,c2,c3 means c1, c2 and c3 are categorical features
-
Note: all values will be cast to int32 (integer codes will be extracted from pandas categoricals in the Python-package)
-
Note: index starts from 0 and it doesn’t count the label column when passing type is int
-
Note: all values should be less than Int32.MaxValue (2147483647)
-
Note: using large values could be memory consuming. Tree decision rule works best when categorical features are presented by consecutive integers starting from zero
-
Note: all negative values will be treated as missing values
-
Note: the output cannot be monotonically constrained with respect to a categorical feature
-
Note: floating point numbers in categorical features will be rounded towards 0
█precise_float_parser 🔗︎, default = false, type = bool
-
use precise floating point number parsing for text parser (e.g. CSV, TSV, LibSVM input)
-
Note: setting this to true may lead to much slower text parsing
猜测是使用类似于SQL里面的decimal,存储准确的浮点数,这样运算会很慢。
Objective Parameters
█ num_class,多分类要在参数字典里面设;
█ is_unbalance█ scale_pos_weight,上面sklearn已讲
在分类中,如果数据不平衡,比如二分类信用卡欺诈之类的案例,可能欺诈案例只占所有的万分之一,这两个参数,可以尝试挑一个设置,或者提前处理数据(Over-sampling和Under-sampling),不过个人感觉树模型,设置了样本比例,并没有那么显著的效果,不过如果原本的1:1效果太差,可以试着几个比例,依次调一下;
█sigmoid,default =1.0, type = double, constraints:sigmoid>0.0 ,used only in binary and multiclassova classification and in lambdarank applications
盲猜是设置sigmoid中的分母,默认是1,当然也可以改!
█boost_from_average,default =true, type = bool
used only in regression, binary, multiclassova and cross-entropy applications
第一棵树初始值,默认这样挺好的!
█reg_sqrt , default = false, type = bool,(感觉不聪明)有点像提前把预测值先log取对数,预测完毕返回时再exp指数搞回来,如果回归任务中数值标签数字太大的话,可以尝试,个人理解,数据分布比较偏态,取对数可以矫正回来,不过一般情况,我们都是自己手动先把数据调整再喂给模型,模型预测了再手动逆转回来,而且取对数还必须>0;
-
used only in regression application
-
used to fit sqrt(label) instead of original values and prediction result will be also automatically converted to prediction^2
-
might be useful in case of large-range labels
其他参数请查看官网。
Metric Parameters
█metric,同sklearn中的,模型自带很多,如果没有需要的要自定义;
█feval,自定义评估函数,xgboost里面就叫feval,官网里面并没有写feval,但实际上可以把这个传进去,证明维护人员肯定漏掉了他,没有feval的模型是没得灵魂的,一般的问题,metric里面的也够用了,可以跟自带的metric叠加,并不冲突。
同xgboost不同的是,该自定义的评估函数要返回三个值,eval_name、eval_result、is_higher_better,多了最后一个布尔型的
其他参数请查看官网。
Network Parameters
略
GPU Parameters
略
Predict Parameters
2.3 model.predict参数
predict里面,同sklearn基本差不多,不过一些名字叫法不同了,写几个不同的:
█pred_early_stop , default = false, type = bool,也就是如果设置了 early_stop,预测的时候,不会默认用最佳迭代,XGBOOST会默认用最佳迭代的,所以还是要手动设一下!!!
-
used only in prediction task
-
used only in classification and ranking applications
-
used only for predicting normal or raw scores
-
if true, will use early-stopping to speed up the prediction. May affect the accuracy
-
Note: cannot be used with rf boosting type or custom objective function
上述结果亦验证了,还是要指定最佳迭代次数的,不然为什么设置eval_metric
2.4 补充
lightgbm可能有2个东西偶尔会用到,from lightgbm import plot_importance,plot_tree,自带了一些方法,也有一些参数可以调整,这里只说明下,没怎么调整图形:
看来还没到树的最大深度,就停止了,一方面是数据集比较小,另一方面可能是其他参数限制住了,将就点看个样就行了。
三、lightgbm.cv
还是接上这个乳腺癌数据
# 有CV就直接传全部数据了,不分train,test
full_datasets = lgb.Dataset(data=data,label=target)
# 参数字典接原生接口,注释掉了early_stop和num_iterations(=300,优先级高会覆盖),其他同
light_cv = lgb.cv(params,full_datasets,num_boost_round=200,nfold=5
,stratified=True,shuffle=True,
metrics=['auc','binary_logloss'],feval=accuracy1, # 随便加了个自定义accuracy
seed=1024,eval_train_metric=False,return_cvbooster=False
)
cv_df = pd.DataFrame(light_cv)
cv_df
lightgbm.cv — LightGBM 4.3.0.99 documentation
结合官网的解释来看,同xgboost的CV几乎差不多,一般要设一个early_stop,这样可以用来寻找最佳迭代次数,但其实并没有太重要,因为其他的调参手段,比如Gridsearch,Randomsearch ,贝叶斯调参完全可以替代。
能看到这里,证明你已经饱受折磨,写这个也是因为看到很多文章,很多参数要么位置不对,要么名字错误,大家基本都会用原生train接口,报错就难受,索性直接去官网咬牙看完....