在序列化XGBoost模型时,可以使用R序列化器,如save()或saveRDS()来序列化XGBoost模型对象。但XGBoost也提供了自己的序列化器,具有更好的兼容性保证,允许在XGBoost的其他语言绑定中加载这些模型。
请注意,一个xgb.Booster对象(由xgb.train()生成,有关xgboost()生成的对象,请参阅文档其余部分),除了其核心组件外,还可能包含
- 附加模型配置(可通过 - xgb.config()访问),其中包括模型拟合参数,如- max_depth和运行时参数,如- nthread。这些对于预测/重要性/绘图不一定有用。
- 附加的R特定属性——例如,回调的结果,如评估日志,它们以 - data.table对象的形式保存,如果存在,可通过- attributes(model)$evaluation_log访问。
第一个(配置)不具有与模型本身相同的兼容性保证,包括通过xgb.attributes()设置和访问的属性——也就是说,无论使用哪种序列化器,在不同XGBoost版本中加载助推器后,此类配置可能会丢失。使用saveRDS()时会保存这些配置,但如果加载到不兼容的XGBoost版本中,它们将被丢弃。使用XGBoost公共接口的序列化器,包括xgb.save()和xgb.save.raw()时,这些配置不会被保存。
第二个(R属性)不属于标准XGBoost模型结构,因此在使用XGBoost自己的序列化器时不会被保存。这些属性仅用于信息目的,例如跟踪模型拟合时的评估指标,或保存生成模型的R调用,但除此之外不用于预测/重要性/绘图等。这些R属性仅在使用R的序列化器时保留。
除了由xgb.train()生成的常规xgb.Booster对象之外,函数xgboost()生成具有不同子类xgboost(继承自xgb.Booster)的对象,该对象将其他附加元数据作为R属性保存,例如分类问题中的类名,并且具有使用不同默认值和接受不同参数名称的专用predict方法。XGBoost自己的序列化器可以处理此xgboost类,但由于它们不保留R属性,因此反序列化后生成的对象会被下转为常规xgb.Booster类(即它会丢失元数据,生成的对象将使用predict.xgb.Booster()而不是predict.xgboost())——对于这些xgboost对象,如果需要额外的功能,saveRDS可能是一个更好的选择。
请注意,从版本2.1.0及更高版本开始的R中的XGBoost模型,以及版本2.1.0之前的XGBoost模型;具有非常不同的R对象结构,并且彼此不兼容。因此,在使用saveRDS()或save()等R序列化器在版本2.1.0之前保存的模型将无法与后续的xgboost版本一起使用,反之亦然。请注意,R模型对象的结构理论上将来可能会再次改变,因此XGBoost的序列化器应优先用于长期存储。
此外,请注意,XGBoost的模型对象可能无法与第三方R包(如qs或qs2)序列化。
详细信息
使用xgb.save()将XGBoost模型保存为独立文件。您可以通过指定JSON扩展名来选择JSON格式。要读回模型,请使用xgb.load()。
使用xgb.save.raw()以未来兼容的方式将XGBoost模型保存为原始字节序列(向量)。XGBoost的未来版本将能够读取原始字节并重建相应的模型。要读回模型,请使用xgb.load.raw()。如果您希望将XGBoost模型作为另一个R对象的一部分进行持久化,则xgb.save.raw()函数很有用。
如果您需要助推器可能具有的R特定属性,例如评估日志或模型类xgboost而不是xgb.Booster,请使用saveRDS(),但请注意,此类对象的未来兼容性超出了XGBoost的控制范围,因为它依赖于R的序列化格式(参见基础R中serialize和save()的详细信息部分)。
有关模型持久化和存档的更多详细信息和解释,请查阅页面https://docs.xgboost.com.cn/en/stable/tutorials/saving_model.html。
示例
data(agaricus.train, package = "xgboost")
bst <- xgb.train(
  data = xgb.DMatrix(agaricus.train$data, label = agaricus.train$label, nthread = 1),
  nrounds = 2,
  params = xgb.params(
    max_depth = 2,
    nthread = 2,
    objective = "binary:logistic"
  )
)
# Save as a stand-alone file; load it with xgb.load()
fname <- file.path(tempdir(), "xgb_model.ubj")
xgb.save(bst, fname)
bst2 <- xgb.load(fname)
# Save as a stand-alone file (JSON); load it with xgb.load()
fname <- file.path(tempdir(), "xgb_model.json")
xgb.save(bst, fname)
bst2 <- xgb.load(fname)
# Save as a raw byte vector; load it with xgb.load.raw()
xgb_bytes <- xgb.save.raw(bst)
bst2 <- xgb.load.raw(xgb_bytes)
# Persist XGBoost model as part of another R object
obj <- list(xgb_model_bytes = xgb.save.raw(bst), description = "My first XGBoost model")
# Persist the R object. Here, saveRDS() is okay, since it doesn't persist
# xgb.Booster directly. What's being persisted is the future-proof byte representation
# as given by xgb.save.raw().
fname <- file.path(tempdir(), "my_object.Rds")
saveRDS(obj, fname)
# Read back the R object
obj2 <- readRDS(fname)
# Re-construct xgb.Booster object from the bytes
bst2 <- xgb.load.raw(obj2$xgb_model_bytes)