使用GridSearchCV与Scikit-learn Pipeline后无法保存模型求助
为何无法用XGBoost的save_model保存GridSearchCV+Pipeline中的最优模型?
复现问题的代码
import numpy as np import xgboost as xgb from sklearn.datasets import make_regression from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV X, y = make_regression(n_samples=30, n_features=5, noise=0.2) reg = xgb.XGBRegressor(tree_method='hist', eval_metric='mae', n_jobs= 4) steps = list() steps.append(('reg', reg)) pipeline = Pipeline(steps=steps) param_grid = {'reg__max_depth': [2, 4, 6],} cv = 3 model = GridSearchCV(pipeline, param_grid, cv=cv, scoring='neg_mean_absolute_error') best_model = model.fit(X = X, y = y)
失败的保存尝试
- 直接调用GridSearchCV对象的
save_model:
model.save_model('test_1.json')
AttributeError: 'GridSearchCV' object has no attribute 'save_model'
- 调用拟合后的GridSearchCV对象的
save_model:
best_model.save_model('test2.json')
AttributeError: 'GridSearchCV' object has no attribute 'save_model'
- 调用最优Pipeline的
save_model:
best_model.best_estimator_.save_model('test3.json')
AttributeError: 'Pipeline' object has no attribute 'save_model'
- 调用模型的最优Pipeline的
save_model:
model.best_estimator_.save_model('test4.json')
AttributeError: 'Pipeline' object has no attribute 'save_model'
成功的保存方法
使用joblib序列化整个Pipeline:
import joblib joblib.dump(model.best_estimator_, 'naive_model.joblib') joblib.dump(best_model.best_estimator_, 'naive_best_model.joblib')
问题
请问是否是我构建Pipeline的方式错误,导致无法使用save_model方法保存最优模型?
解答
你的Pipeline构建完全没问题,无法调用save_model的原因很明确:
GridSearchCV和Pipeline都不属于XGBoost的模型类,它们没有save_model这个方法——该方法是XGBoost原生模型(如XGBRegressor)独有的。- 你需要从Pipeline中提取出内部的XGBoost模型实例,才能调用它的
save_model方法。
正确的操作方式是通过Pipeline的named_steps属性获取到XGBoost模型:
# 从GridSearchCV中获取最优Pipeline,再提取其中的XGBoost模型 best_xgb = model.best_estimator_.named_steps['reg'] best_xgb.save_model('best_xgb_model.json') # 由于model.fit返回的是自身,best_model和model是同一个对象,所以也可以这么写 best_xgb = best_model.best_estimator_.named_steps['reg'] best_xgb.save_model('best_xgb_model.json')
这样就能用XGBoost原生的save_model方法保存模型了。而用joblib保存整个Pipeline是另一种有效方案,因为joblib可以完整序列化scikit-learn的Pipeline对象,包括其中的XGBoost模型。
内容的提问来源于stack exchange,提问作者Li-Pin Juan
相关产品推荐
相关产品推荐

