`lm`是否因为`predict`以外的原因返回`model`

时间:2017-06-23 22:41:26

标签: r memory lm

默认情况下,

lm设置model = TRUE,这意味着将使用拟合对象复制并返回用于学习的整个数据集。这由predict使用,但会产生内存开销(例如下面的例子)。

我想知道,复制的数据集是否用于predict以外的任何其他原因?

回答不是必不可少的,但我也想知道出于predict以外的原因存储数据的模型。

实施例

object.size(lm(mpg ~ ., mtcars))
#> 45768 bytes
object.size(lm(mpg ~ ., mtcars, model = FALSE))
#> 28152 bytes

更大的数据集=更大的开销。

动机

为了分享我的动机,twidlr包强制用户在使用predict时提供数据。如果这使得在学习不必要时复制数据集,则通过默认为model = FALSE来节省内存似乎是合理的。我已经打开了相关问题here

次要动机 - 您可以轻松地将lm等许多模型与pipelearner相匹配,但每次复制数据会产生巨大的开销。因此,找到减少内存需求的方法会非常方便!

1 个答案:

答案 0 :(得分:4)

我认为返回模型框架是为了防止非标准评估。

让我们看一个小例子。

dat <- data.frame(x = runif(10), y = rnorm(10))
FIT <- lm(y ~ x, data = dat)
fit <- FIT; fit$model <- NULL

之间有什么区别
model.frame(FIT)
model.frame(fit)

??检查methods(model.frame)stats:::model.frame.lm表示在第一种情况下,模型框架是从FIT$model有效提取的;而在第二种情况下,它将从fit$callmodel.frame.default重建。这种差异也导致了

之间的差异
# depends on `model.frame`
model.matrix(FIT)
model.matrix(fit)

因为模型矩阵是从模型框架构建的。如果我们进一步挖掘,我们会发现它们也是不同的,

# depends on `model.matrix`
predict(FIT)
predict(fit)

# depends on `predict.lm`
plot(FIT)
plot(fit)

请注意,这可能是问题所在。如果我们故意删除dat,我们无法重建模型框架,那么所有这些都将失败:

rm(dat)
model.frame(fit)
model.matrix(fit)
predict(fit)
plot(fit)
使用FIT

将起作用。

这还不够糟糕。以下非标准评估的例子非常糟糕!

fitting <- function (myformula, mydata, keep.mf = FALSE) {
  b <- lm(formula = myformula, data = mydata, model = keep.mf)
  par(mfrow = c(2,2))
  plot(b)
  predict(b)
  }

现在让我们再次创建一个数据框(我们之前已经删除了它)

dat <- data.frame(x = runif(10), y = rnorm(10))

你能看到吗

fitting(y ~ x, dat, keep.mf = TRUE)

有效但

fitting(y ~ x, dat, keep.mf = FALSE)

失败?

以下是我在一年前回答/调查过的一个问题:R - model.frame() and non-standard evaluation有人要求survival包裹。这个例子非常极端:即使我们提供newdata,我们仍然会收到错误。保留模型框架是唯一的方法!

最后关于你对内存成本的观察。事实上,$model并不主要负责潜在的大lm个对象。 $qr是,因为它与模型矩阵具有相同的维度。考虑具有许多因素的模型,或bsnspoly等非线性项,模型框架与模型矩阵相比要小得多。因此,省略模型框架返回无助于减少lm对象大小。这实际上是biglm开发的一个动机。

由于我不可避免地提到biglm,我再次强调这种方法只能帮助减少最终的模型对象大小,而不是模型拟合期间的RAM使用。