LightGBM启用Early Stopping时未保留最佳模型问题咨询
问题原因分析
我帮你排查了代码,发现几个导致LightGBM没有保留最佳模型的核心问题:
- 变量名错误,保存了不存在的模型:你在结果字典
Results里写的是'lg_boost_model' : bst,但整个代码里根本没定义过bst这个变量——实际训练好的模型是model。这会导致要么直接抛出NameError,要么保存了一个无效的变量,完全不是你训练出来的模型。 - 预测时未指定使用最佳迭代次数:虽然你设置了
early_stopping_rounds=20,但LightGBM的scikit-learn接口默认会使用所有n_estimators次迭代的最终模型,而不是early stopping选中的最佳迭代点的模型。你必须明确告诉模型使用最佳迭代次数来做预测。 - 旧版本默认行为限制:考虑到你用的是Python3.7,对应的LightGBM版本可能相对较早,部分旧版本的scikit-learn接口不会自动将模型切换到最佳迭代状态,必须手动干预。
解决建议
针对这些问题,给你几个具体的修复步骤:
1. 修正变量名错误
把结果字典里的bst改成model,确保保存的是训练好的模型:
Results = { 'params' : params, 'data' : data, 'lg_boost_model' : model, # 这里把bst改成model 'y_pred_train' : y_pred_train, 'y_pred_dev' : y_pred_dev, 'y_pred_test' : y_pred_test, 'auc_train' : auc_train, 'auc_dev' : auc_dev, 'precision_dev': precision, 'recall_dev' : recall, 'fscore_dev' : fscore, 'support_dev' : support }
2. 预测时指定使用最佳迭代次数
在调用predict_proba的时候,加上num_iteration=model.best_iteration_参数,让模型用early stopping找到的最佳迭代点来预测:
# 训练后先确认best_iteration_是否存在(正常触发early stopping的话会有这个属性) print(f"Best iteration found: {model.best_iteration_}") # 用最佳迭代次数预测 y_pred_train = model.predict_proba(X_train, num_iteration=model.best_iteration_)[:, 1].ravel() y_pred_dev = model.predict_proba(X_dev, num_iteration=model.best_iteration_)[:, 1].ravel() y_pred_test = model.predict_proba(X_test, num_iteration=model.best_iteration_)[:, 1].ravel()
3. 可选:直接修改模型的n_estimators为最佳迭代次数
如果你不想每次预测都加参数,可以在训练后直接把模型的n_estimators改成最佳迭代次数,这样后续的预测会默认使用这个次数:
model.n_estimators = model.best_iteration_
4. 添加verbose参数确认early stopping触发
建议在fit方法里加上verbose=True,这样可以在训练过程中看到early stopping的日志,确认是否真的触发了早停,以及找到的最佳迭代次数是多少:
model.fit(X_train, y_train, eval_set = [(X_dev, y_dev)], eval_metric = 'auc', early_stopping_rounds = 20, categorical_feature = categorical_feature, feature_name = feature_name, verbose=True) # 添加这个参数
这样修改后,你的模型就会正确保留并使用early stopping找到的最佳模型了。
内容的提问来源于stack exchange,提问作者user8270077
相关产品推荐
相关产品推荐

