r - `lm` 是否由于 `model` 以外的原因返回 `predict`

标签 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 .

次要动机 - 您可以使用 pipelearner 轻松拟合许多模型,例如 lm ,但每次复制数据都会产生巨大的开销。所以找到减少内存需求的方法会非常方便!

最佳答案

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

我们来看一个小例子。

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使用量。

关于r - `lm` 是否由于 `model` 以外的原因返回 `predict`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44730860/

相关文章:

c++ - C++ 中未对齐访问的正确性

r - geom_smooth 自定义线性模型

r - summary.lm 输出自定义

r - ggplot2 - 向分组条形图添加差异

r - 如何在 R 包 JuliaConnectoR 中传递 Julia 类型

r - 两个结构体的猫 : not the same fields

R Predict() 要求排除在 lm() 回归模型中的变量

r - 使用另一个逻辑矩阵在矩阵中设置NA

CS50 PSET4 无法释放拼写器中的内存

C : uninitialized char pointer and print out the address