r语言 - 如何在不影响传递给 predict() 的情况下最小化类 "lm" 对象的大小



我想在一个具有 50M+ 观测值和 2 个预测变量的大型数据集上运行lm()。分析在仅具有 10GB 用于存储数据的远程服务器上运行。我已经对从数据中采样的 10K 观察结果进行了"lm()"测试,结果对象的大小为 2GB+。

我需要从 lm() ONLY 返回的类 "lm" 的对象来生成模型的汇总统计量 ( summary(lm_object) ) 并进行预测 ( predict(lm_object) )。

我已经对lm的选项model, x, y, qr做了一些实验。如果我将它们全部设置为 FALSE,则大小减少了 38%

library(MASS)
fit1=lm(medv~lstat,data=Boston)
size1 <- object.size(fit1)
print(size1, units = "Kb")
# 127.4 Kb bytes
fit2=lm(medv~lstat,data=Boston,model=F,x=F,y=F,qr=F)
size2 <- object.size(fit2)
print(size2, units = "Kb")
# 78.5 Kb Kb bytes
- ((as.integer(size1) - as.integer(size2)) / as.integer(size1)) * 100
# -38.37994

summary(fit2)
# Error in qr.lm(object) : lm object does not have a proper 'qr' component.
#  Rank zero or should not have used lm(.., qr=FALSE).
predict(fit2,data=Boston)
# Error in qr.lm(object) : lm object does not have a proper 'qr' component.
#  Rank zero or should not have used lm(.., qr=FALSE).

显然我需要保留qr=TRUE与默认对象相比,仅将对象大小减小 9%

fit3=lm(medv~lstat,data=Boston,model=F,x=F,y=F,qr=T)
size3 <- object.size(fit3)
print(size3, units = "Kb")
# 115.8 Kb
- ((as.integer(size1) - as.integer(size3)) / as.integer(size1)) * 100
# -9.142752

如何在不转储内存和存储中大量不需要的信息的情况下将"lm"对象的大小降至最低?

这里的链接提供了一个相关的答案(对于 glm 对象,它与 lm 输出对象非常相似)。

http://www.win-vector.com/blog/2014/05/trimming-the-fat-from-glm-models-in-r/

基本上,预测仅使用系数部分,这是glm输出的非常小的一部分。 下面的函数(从链接复制)修剪预测不会使用的信息。

不过,它确实有一个警告。修剪后,它不能被 summary(fit) 或其他摘要函数使用,因为这些函数需要比预测所需的更多。

cleanModel1 = function(cm) {
  # just in case we forgot to set
  # y=FALSE and model=FALSE
  cm$y = c()
  cm$model = c()
  cm$residuals = c()
  cm$fitted.values = c()
  cm$effects = c()
  cm$qr$qr = c()
  cm$linear.predictors = c()
  cm$weights = c()
  cm$prior.weights = c()
  cm$data = c()
  cm
}

xappp的答案很好,但不是全部。您还可以对一个巨大的环境变量执行一些操作(请参阅:https://blogs.oracle.com/R/entry/is_the_size_of_your)

要么将其添加到 xappp 的函数中

     e <- attr(cm$terms, ".Environment")
     parent.env(e) <- emptyenv()
     rm(list=ls(envir=e), envir=e)

或者使用这个版本,它可以减少更少的数据,但仍然允许你使用summary()

      cleanModel1 = function(cm) {
      # just in case we forgot to set
      # y=FALSE and model=FALSE
      cm$y = c()
      cm$model = c()
      e <- attr(cm$terms, ".Environment")
      parent.env(e) <- emptyenv()
      rm(list=ls(envir=e), envir=e)
      cm
      }
我也

在尝试处理同样的问题。我使用的东西对于其他事情并不完美,但适用于预测,你基本上可以在 lm 中取出 qr 插槽的 qr 插槽:

lmFull <- lm(Volume~Girth+Height,data=trees)
lmSlim <- lmFull
lmSlim$fitted.values <- lmSlim$qr$qr <- lmSlim$residuals <- lmSlim$model <- lmSlim$effects <- NULL
pred1 <- predict(lmFull,newdata=data.frame(Girth=c(1,2,3),Height=c(2,3,4)))
pred2 <- predict(lmSlim,newdata=data.frame(Girth=c(1,2,3),Height=c(2,3,4)))
identical(pred1,pred2)
[1] TRUE
as.numeric((object.size(lmFull) - object.size(lmSlim)) / object.size(lmFull))
[1] 0.6550523

最新更新