LightGBM调参

LightGMB的参数类型

  • 核心参数
  • 学习控制参数
  • IO参数
  • 目标函数参数
  • 度量参数等

调参时不需要关注这么多参数,只需记住常用的一些参数。


从四个方向优化参数

1. 针对leaf-wise树的参数优化

  • 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 不要在单棵树分的太细
  • 使用 lambda_l1, lambda_l2min_gain_to_split来使用正则
  • 尝试 max_depth 来避免生成过深的树
  • 使用 min_data_in_leafmin_sum_hessian_in_leaf, 确保叶子节点有足够多的数据

LightGBM的调参过程和RF、GBDT等类似,其基本流程如下:

  1. 首先选择较高的学习率,大概0.1附近,这样是为了加快收敛的速度。这对于调参是很有必要的。
  2. 对决策树基本参数调参
  3. 正则化参数调参
  4. 最后降低学习率,这里是为了最后提高准确率

具体过程

Step1: 学习率和迭代次数
我们先把学习率先定一个较高的值,这里取 learning_rate = 0.1,其次确定估计器boosting/boost/boosting_type的类型,不过默认都会选gbdt。

Step2: 迭代的次数
也可以说是残差树的数目,参数名为n_estimators/num_iterations/num_round/num_boost_round。我们可以先将该参数设成一个较大的数,然后在cv结果中查看最优的迭代次数,具体如代码。

在这之前,我们必须给其他重要的参数一个初始值。初始值的意义不大,只是为了方便确定其他参数。下面先给定一下初始值:


主要参数:

'boosting_type'/'boosting': 'gbdt'
'objective': 'binary'
'metric': 'auc'
    
# 以下是选择的初始值
'max_depth': 5     # 由于数据集不是很大,所以选择了一个适中的值,其实4-10都无所谓。
'num_leaves': 30   # 由于lightGBM是leaves_wise生长,官方说法是要小于2^max_depth
'subsample'/'bagging_fraction':0.8           # 数据采样
'colsample_bytree'/'feature_fraction': 0.8   # 特征采样

调参过程

Step1:建立二分类lightGBM CV模型
此处以乳腺癌数据集作为示例。

%%time
# step1:基本参数,输出最优迭代
import pandas as pd
import lightgbm as lgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
canceData=load_breast_cancer()
X=canceData.data
y=canceData.target
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=2021,test_size=0.2)
data_train = lgb.Dataset(X_train, y_train)
# 基本参数设置
params = {    
          'boosting_type': 'gbdt',
          'objective': 'binary',
          'metric': 'auc',
          'nthread':4,
          'learning_rate':0.1,
          'num_leaves':30, 
          'max_depth': 5,   
          'subsample': 0.8, 
          'colsample_bytree': 0.8, 
    }
cv_results = lgb.cv(params, data_train, num_boost_round=1000, nfold=5, stratified=False, shuffle=True, metrics='auc',early_stopping_rounds=50,seed=0)
print('best n_estimators:', len(cv_results['auc-mean']))
print('best cv score:', pd.Series(cv_results['auc-mean']).max())

根据输出结果得到最优迭代 n_estimators

Step2: 更新n_estimators的值,确定max_depth和num_leaves
这是提高精确度的最重要的参数。这里我们引入sklearn里的GridSearchCV()函数进行搜索。

%%time
# update n_estimators,search max_depth and num_leaves
from sklearn.model_selection import GridSearchCV
params_test1={'max_depth': range(3,8,1), 
              'num_leaves':range(5, 100, 5)}

estimator = lgb.LGBMClassifier(boosting_type='gbdt',
                               objective='binary',
                               metrics='auc',
                               learning_rate=0.1, 
                               n_estimators=137, 
                               max_depth=6, 
                               bagging_fraction = 0.8,
                               feature_fraction = 0.8)

gsearch1 = GridSearchCV(estimator, param_grid = params_test1, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch1.fit(X_train,y_train)
print(gsearch1.best_params_)

gsearch1.best_params_得到最优的max_depthnum_leaves

Step3: 确定min_data_in_leaf和max_bin

%%time
# step3:update max_depth and num_leaves,search max_bin and min_data_in_leaf
params_test2={'max_bin': range(5,256,10), 'min_data_in_leaf':range(1,102,10)}
estimator = lgb.LGBMClassifier(boosting_type='gbdt',
                               objective='binary',
                               metrics='auc',
                               learning_rate=0.1, 
                               n_estimators=137, 
                               max_depth=4, 
                               num_leaves=10,
                               bagging_fraction = 0.8,
                               feature_fraction = 0.8)

gsearch2 = GridSearchCV(estimator,param_grid = params_test2, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch2.fit(X_train,y_train)
print(gsearch2.best_params_)

gsearch2.best_params_得到最优的max_binmin_data_in_leaf

Step4: 确定feature_fraction、bagging_fraction、bagging_freq

%%time
# step4:update max_bin and min_data_in_leaf,search feature_fraction,bagging_fraction,bagging_freq
params_test3={'feature_fraction': [0.6,0.7,0.8,0.9,1.0],
              'bagging_fraction': [0.6,0.7,0.8,0.9,1.0],
              'bagging_freq': range(0,81,10)
}
estimator = lgb.LGBMClassifier(boosting_type='gbdt',
                               objective='binary',
                               metrics='auc',
                               learning_rate=0.1, 
                               n_estimators=137, 
                               max_depth=4, 
                               num_leaves=10,
                               max_bin=35,
                               min_data_in_leaf=41)
gsearch3 = GridSearchCV(estimator,param_grid = params_test3, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch3.fit(X_train,y_train)
print(gsearch3.best_params_)

Step5: 确定lambda_l1和lambda_l2

%%time
# step5:update feature_fraction,bagging_fraction,bagging_freq, search lambda_l1 and lambda_l2
params_test4={'lambda_l1': [1e-5,1e-3,1e-1,0.0,0.1,0.3,0.5,0.7,0.9,1.0],
              'lambda_l2': [1e-5,1e-3,1e-1,0.0,0.1,0.3,0.5,0.7,0.9,1.0]
}
estimator = lgb.LGBMClassifier(boosting_type='gbdt',
                               objective='binary',
                               metrics='auc',
                               learning_rate=0.1, 
                               n_estimators=137, 
                               max_depth=4, 
                               num_leaves=10,
                               max_bin=35,
                               min_data_in_leaf=41,
                               bagging_fraction=0.6,
                               bagging_freq= 0, 
                               feature_fraction= 0.8)      
gsearch4 = GridSearchCV(estimator,param_grid = params_test4, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch4.fit(X_train,y_train)
print(gsearch4.best_params_)

Step6:确定 min_split_gain

%%time
# step6:update lambda_l1 and lambda_l2,search min_split_gain
params_test5={'min_split_gain':[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]}
estimator = lgb.LGBMClassifier(boosting_type='gbdt',
                               objective='binary',
                               metrics='auc',
                               learning_rate=0.1, 
                               n_estimators=137,
                               max_depth=4, 
                               num_leaves=10,
                               max_bin=35,
                               min_data_in_leaf=41,
                               bagging_fraction=0.6,
                               bagging_freq= 0, 
                               feature_fraction= 0.8,
                               lambda_l1=0,
                               lambda_l2=0)
gsearch5 = GridSearchCV(estimator,param_grid = params_test5, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch5.fit(X_train,y_train)
print(gsearch5.best_params_)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容