readBin来自内存,而不是磁盘

时间:2015-02-02 00:03:06

标签: r binaryfiles rcpp

我最近一直在使用xgboost模型:

library(xgboost)
set.seed(23)
data(agaricus.train, package='xgboost')
data(agaricus.test, package='xgboost')
train <- agaricus.train
test <- agaricus.test
bst <- xgboost(
  data = train$data, label = train$label, max.depth = 2,
  eta = 1, nround = 2,objective = "binary:logistic")
pred <- predict(bst, test$data)

不幸的是,如果您尝试使用saveload以及xgboost型号,结果就是段错误:

f <- tempfile()
saveRDS(bst, f)
bst_new = readRDS(f)
unlink(f)
print(bst_new) #NULL pointer
pred2 <- predict(bst_new, test$data) #This line segfaults

这是因为xgboost模型实际上只是指向内存中C ++对象的指针:R包实际上只是一些C ++代码的薄包装:

> print(bst)
<pointer: 0x10a5ae750>
attr(,"class")
[1] "xgb.Booster"

包作者已经意识到了这一点,并编写了2个自定义函数(xgb.savexgb.load)来保存和加载xgboost模型,但是它们没有能力使用它们那么有用来自基地R的saveload。我想出了一个用于保存模型作为R会话的一部分的黑客攻击,但它不是很漂亮:

#Hack to save an xgboost model
f1 <- tempfile()
f2 <- tempfile()
xgb.save(bst, f1)
model_raw_bytes <- readBin(f1, what='raw', file.info(f)[1, "size"])
unlink(f1)
print(head(model_raw_bytes))
saveRDS(model_raw_bytes, f2)

#Hack to load an xgboost
f3 <- tempfile()
model_raw_bytes <- readRDS(f2)
writeBin(model_raw_bytes, f3)
model_2 <- xgb.load(f3)
pred_2 <- predict(model_2, test$data)
all.equal(pred_2, pred)
unlink(f2)
unlink(f3)

有没有办法直接从内存中的某个位置readBin,而不是从磁盘? (这样可以省去编写临时文件以保存和加载模型)。

更好的是,是否有一种可以在C对象中包装R对象的方法,我可以指导包作者?他们非常愿意接受我对github的评论,如果我能提交公关来使这项工作,我认为他们会接受它。

0 个答案:

没有答案