OOF的问题

在Bayesian Optimization或者Grid Search调参时,通常会结合交叉验证OOF来找到最优的参数。

OOF会利用K-Fold训练K个模型,最后计算每个模型在验证集上的metrics。

lgb在做OOF的时候,每个模型都有自己的early stopping,会有一定的过拟合。如果后面还要做Stacking,会影响最终模型的精度。

什么是lgb.cv

lightgbm.cv() 会同时在每个round训练K个模型,并记录每个round中最优的模型的metric。这样指定的early stopping通常会更早停止,这样避免过拟合,而且训练速度会更快一些。

除了lightgbm,也有xgboost.cv catboost.cv等等。

lgb.cv例子

需要提取准备的包括:

  • kf: K Fold,可以是sklearn.model_selection.KFold或者sklearn.model_selection.StratifiedKFold
  • num_boost_round:因为有early stopping,可以设置的比较大
  • early_stopping_rounds
  • data_train:lgb的训练集
  • params参数
from sklearn.model_selection import KFold
import lightgbm as lgb

# K Fold
kf = KFold(5, shuffle=True, random_state=0)

# 有early stopping, num_boost_round一般会设置比较大
num_boost_round = 100000
early_stopping_rounds = 100

# 训练集
data_train = lgb.Dataset(x_train, label=y_train)

# params
params =  {
    'boosting_type': 'gbdt',
    "objective" : "xxx",
    'max_depth' : xxx,
    ...
}

通过lgb.cv找到最优的round。lgb.cv的返回值history的类别是dict。它的key是metric的名字,value是每个round的最优模型的metric记录值。

history = lgb.cv(params, data_train, 
                 num_boost_round=num_boost_round, 
                 folds=kf, metrics=xxx,
                 early_stopping_rounds=early_stopping_rounds, 
                 verbose_eval=xxx, 
                 show_stdv=True,  # 显示metric的标准差
                 seed=0)

# 最佳round,具体名字和metric有关
best_round = np.argmax(history['xxx-mean'])

# 避免最坏情况
if best_round == 0:
    best_round = 1

最终训练的模型固定最大的round,不设置early stopping

bst = lgb.train(param, data_train, num_boost_round=best_round, 
                    verbose_eval=None,
                    early_stopping_rounds=None, 
                   )
最后修改:2021 年 09 月 22 日 01 : 26 PM
如果觉得我的文章对你有用,请随意赞赏