如何保存和加载xgboost模型?

88
XGBoost指南中得知:

After training, the model can be saved.

bst.save_model('0001.model')

The model and its feature map can also be dumped to a text file.

# dump model
bst.dump_model('dump.raw.txt')
# dump model with feature map
bst.dump_model('dump.raw.txt', 'featmap.txt')

A saved model can be loaded as follows:

bst = xgb.Booster({'nthread': 4})  # init model
bst.load_model('model.bin')  # load data

以下是我的问题。

  1. save_modeldump_model有什么区别?
  2. 保存'0001.model''dump.raw.txt','featmap.txt'有什么区别?
  3. 加载model.bin的模型名称与要保存的0001.model的名称不同,为什么?
  4. 假设我训练了两个模型:model_Amodel_B。我想保存这两个模型以供将来使用。我应该使用哪个saveload函数?能否帮助解释清楚操作步骤?

1
你问了很多问题,但如果你感兴趣的话,可以在这里查看 save_modeldump_modelload_model 的代码:https://github.com/dmlc/xgboost/blob/master/python-package/xgboost/core.py - Max Power
如果您的XGBoost模型是使用sklearn包装器训练的,您仍然可以使用"bst.save_model()"保存模型,并使用"bst = xgb.Booster().load_model()"加载模型。当您使用'bst.predict(input)'时,您需要将输入转换为DMatrix。 - Jundong
我更多地使用 joblibs。有关讨论,请参见pickle vs joblibssklearn指南以保存模型 - Travis
5个回答

50

以下是我解决问题的方法:

import pickle
file_name = "xgb_reg.pkl"

# save
pickle.dump(xgb_model, open(file_name, "wb"))

# load
xgb_model_loaded = pickle.load(open(file_name, "rb"))

# test
ind = 1
test = X_val[ind]
xgb_model_loaded.predict(test)[0] == xgb_model.predict(test)[0]

Out[1]: True

29
如果你的模型被保存在pickle中,当你升级xgboost版本时可能会失去支持。 - Fontaine007
7
这是一个合理的使用案例 - 例如,选取是保存sklearn管道的官方建议。这意味着,如果有一个包含XGBoost模型的sklearn管道,必须最终选择XGBoost。 如果担心将来XGBoost的更新可能会破坏选取的行为,那么版本固定(和单元测试)就存在的原因。 - AmphotericLewisAcid
1
@AmphotericLewisAcid 版本固定可以显示问题所在,但并不能解决它。 - Qbik
4
不要使用pickle或joblib,因为这可能会引入对xgboost版本的依赖。保存和恢复模型的规范方法是使用load_model和save_model。 - Qbik
我不同意。如果您想序列化包含实现sklearn API的sklearn对象的sklearn管道,sklearn文档中的官方建议是使用pickle对对象进行序列化。我的评论特别针对您正在使用XGBoost的sklearn兼容对象的情况。无论XGBoost认为什么是“规范”的在这里都是无关紧要的 - 它们要么符合规范,要么不符合规范。而对于它们的不兼容性的解决方法是版本固定,以确保pickled对象正常工作。 - AmphotericLewisAcid
2
我必须警告你,仅仅是 sklearn API 的变化就可能破坏生产模型... 如果使用 pickle,你需要固定每个东西... 另一个反对 pickle 模型的论据是:Triton 推理服务器(由 NVIDIA 维护,在每个主要公共云中都可用)将无法导入 pickled 基于树的模型(仅接受纯 Boosters 保存为 txt 或 json,没有特定于版本的 python 对象标头)。 - mirekphd

44

两个函数save_modeldump_model都可以保存模型,区别在于在dump_model中您可以保存特征名称并以文本格式保存树。

load_model将使用save_model保存的模型。从dump_model保存的模型可以与xgbfi一起使用。

在加载模型时,您需要指定模型保存的路径。例如,bst.load_model("model.bin")示例从名为model.bin的文件加载模型。祝好运!

编辑:从Xgboost文档(版本1.3.3)中可以看出,dump_model()应该用于保存模型以供进一步解释。对于保存和加载模型,应该使用save_model()load_model()。请查看文档获取更多详细信息。

Xgboost的Learning APIScikit-Learn API之间也有区别。后者保存了在早期停止训练期间设置的best_ntree_limit变量。您可以在我的文章《如何在Python中保存和加载Xgboost?》中阅读详细信息。

save_model()方法识别文件名的格式,如果指定了*.json,则将以JSON格式保存模型,否则将保存为文本文件。


23
不要使用pickle或joblib,因为它们可能会引入对xgboost版本的依赖。保存和恢复模型的规范方式是通过load_modelsave_model
如果您想将模型存储或归档以进行长期存储,请使用save_model(Python)和xgb.save(R)。
是最新版本XGBoost的相关文档。它还解释了dump_modelsave_model之间的区别。
请注意,您可以通过在使用bst.save_model时指定json扩展名将模型序列化/反序列化为json。如果您不关心保存和恢复模型的速度,这非常方便,因为它允许您对模型进行适当的版本控制,因为它是一个简单的文本文件。

22

使用joblib库是保存和加载xgboost模型的简单方法。

import joblib
#save model
joblib.dump(xgb, filename) 

#load saved model
xgb = joblib.load(filename)

18
如果您想在不同的编程语言中加载和保存模型,这并不是一个好的选择。例如,您可能想在Python中训练模型,但要在Java中进行预测。 - oshribr
5
这是 XGBoost 开发者建议的方法,当你使用 xgboost 的 sklearn API 时,应该通过 pickle 格式来保存 XGBClassifier 和 XGBRegressor。 - Abhilash Awasthi
3
它说在Python3.8中,joblib已经被弃用。 - Yi Lin Liu
2
当您在不同版本的Xgboost上保存和加载pickle时,可能会出现不兼容性。 - dhanush-ai1990

13

如果您正在使用sklearn api,您可以使用以下方法:


xgb_model_latest = xgboost.XGBClassifier() # or which ever sklearn booster you're are using

xgb_model_latest.load_model("model.json") # or model.bin if you are using binary format and not the json

如果您使用了上述的加载提升方法,您将在Python API内获取xgboost提升器而不是sklearn API中的sklearn提升器。

所以,如果您正在使用sklearn API,则这似乎是加载保存的xgboost模型数据的最符合Python风格的方式。


1
我已经使用了这种方法,但是在使用xgb_model_latest.get_params()时无法获取先前保存的模型参数。 - Galo Castillo
我有同样的问题。 - Ravi
没有遇到这个问题。默认值的处理方式不是我喜欢的方式。但是我确实得到了我输入的参数。我正在使用1.2.1版本。欢迎发布您的代码以尝试解决这个问题。 - Robert Beatty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接