You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨系统使用mlr3prob的xgboost.cox模型预测时遇DMatrix初始化错误求助

解决mlr3中保存/加载xgboost.cox模型后预测报错的问题

问题现象

使用mlr3prob和mlr3extralearners训练surv.xgboost.cox模型,保存为RDS文件迁移到其他系统后,调用predict()或predict_newdata()时触发报错:

src/c_api/c_api.cc:675: DMatrix/Booster has not been initialized or has already been disposed.

即使手动替换加载的xgb.Booster对象,报错依然存在。

环境版本

  • R版本:4.2.3
  • 核心包版本:
    • dplyr_1.1.4
    • xgboost_1.7.7.1
    • mlr3proba_0.6.9
    • mlr3verse_0.3.0
    • mlr3tuning_1.0.0
    • paradox_1.0.1
    • survival_3.7-0
    • mlr3extralearners_1.0.0
    • mlr3_0.22.1

复现代码

library(mlr3)
library(mlr3proba)
library(mlr3verse)
library(mlr3extralearners)
library(xgboost)
library(dplyr)

# 训练阶段
lung_filter = lung |> select(-sex,-ph.ecog)
task = TaskSurv$new(id="lung",backend = lung_filter,time = "time",event = "status")
learner = lrn("surv.xgboost.cox")$train(task)
saveRDS(task,"task.rds")
saveRDS(learner,"learner.rds")
xgb.save(learner$model$model, "xgb.model")

# 训练后本地预测正常
learner$predict_newdata(lung_filter,task)
learner$predict(task)

# 加载阶段(新环境/清空环境后)
rm(list=ls())
lung_filter = lung |> select(-sex,-ph.ecog)
task2 = readRDS("task.rds")
learner2 = readRDS("learner.rds")

# 查看加载后的模型状态,提示Handle无效
learner2$model$model

# 手动加载xgb模型并替换
model = xgb.load("xgb.model")
learner2$model$model = model

# 尝试预测,触发报错
learner2$predict_newdata(lung_filter,task2)
learner2$predict(task2)

解决方案

核心原因

xgboost的Booster对象依赖C后端的资源句柄,RDS序列化仅能保存对象表层信息,无法持久化底层C资源,导致加载后句柄无效。同时mlr3的surv.xgboost.cox learner会缓存训练时的dtrain(DMatrix对象),加载后该缓存已失效,预测时优先调用无效缓存触发报错。


方案1:正确的模型保存/加载流程

不要直接保存整个learner对象,而是拆分保存配置参数与训练好的Booster,在新环境重新初始化learner:

训练时保存内容

# 训练模型
learner = lrn("surv.xgboost.cox")$train(task)

# 保存learner参数配置
saveRDS(learner$param_set$values, "xgb_cox_params.rds")
# 保存xgb.Booster模型
xgb.save(learner$model$model, "xgb_cox_model.model")
# 保存训练特征列名(确保新数据列一致)
saveRDS(task$feature_names, "feature_names.rds")

新环境加载并预测

library(mlr3)
library(mlr3proba)
library(mlr3extralearners)
library(xgboost)
library(dplyr)

# 加载配置与模型
params = readRDS("xgb_cox_params.rds")
feature_names = readRDS("feature_names.rds")
xgb_model = xgb.load("xgb_cox_model.model")

# 初始化learner并设置参数
learner = lrn("surv.xgboost.cox", .params = params)
# 构建mlr3要求的model结构
learner$model = list(
  model = xgb_model,
  task_feature_names = feature_names,
  target_names = c("time", "status")
)

# 准备匹配格式的新数据
lung_filter = lung |> select(all_of(feature_names), time, status)
task2 = TaskSurv$new(id="lung_pred", backend=lung_filter, time="time", event="status")

# 执行预测
pred = learner$predict(task2)
pred_newdata = learner$predict_newdata(lung_filter, task2)

方案2:临时修复已保存的learner

如果已保存了完整learner对象,可通过清空无效缓存解决:

learner2 = readRDS("learner.rds")
xgb_model = xgb.load("xgb.model")

# 清空缓存的无效DMatrix
learner2$model$dtrain = NULL
# 替换为有效Booster
learner2$model$model = xgb_model

# 执行预测
pred = learner2$predict(task2)

内容的提问来源于stack exchange,提问作者gen linlin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:34:59