lm 的内存问题

Memory issue with lm

我有一个包含大约 400 万行和 15 个变量的大型数据框。我正在尝试实施一种模型选择算法,该算法添加了一个变量,该变量导致 lm 模型的 r 平方增幅最大。

以下代码片段是我的函数因数据量大而失败的地方。我试过 biglm 但还是不行。我这里以mtcars为例,只是为了说明。

library(biglm)
library(dplyr)
data <- mtcars
y <- "mpg"
vars.model <- "cyl"
vars.remaining <- setdiff(names(data), c("mpg", "cyl"))

new.rsq <- sapply(vars.remaining, 
                  function (x) {
                      vars.test <- paste(vars.model, x, sep="+")
                      fit.sum <- biglm(as.formula(paste(y, vars.test, sep="~")), 
                                       data) %>% summary()
                      new.rsq <- fit.sum$rsq 
                  })
new.rsq

我不确定 R 在这里如何处理内存,但是 biglm 我的 400 万行数据的输出非常小 (6.6 KB)。打包成sapply不知道怎么累积到好几GB。非常感谢有关如何优化它的任何提示。

内存使用量上升,因为每次调用 biglm() 都会在内存中复制数据。由于 sapply() 基本上是一个 for 循环,使用 doMC(或 doParallel)允许通过内存中数据的单个副本来完成循环。这是一种可能性:

编辑:正如@moho wu 指出的那样,平行拟合有帮助,但还不够。因素比普通字符更有效,所以这也有帮助。然后 ff 可以提供更多帮助,因为它将更大的数据集保存在磁盘上,而不是内存中。我更新了下面的代码,使用 ffdoMC.

使其成为一个完整的玩具示例
library(tidyverse)
library(pryr)

# toy data
df <- sample_n(mtcars, size = 1e7, replace = T)   
df$A <- as.factor(letters[1:5]) 

# get objects / save on disk
all_vars <- names(df) 
y <- "mpg"  
vars.model <- "cyl"
vars.remaining <- all_vars[-c(1:2)]
save(y, vars.model, vars.remaining, file = "all_vars.RData") 
readr::write_delim(df, path = "df.csv", delim = ";")

# close R session and start fresh

library(ff)
library(biglm)
library(doMC)
library(tidyverse)

# read flat file as "ff" ; also read variables
ff_df <- read.table.ffdf(file = "df.csv", sep = ";", header = TRUE)
load("all_vars.RData") 

# prepare the "cluster"
nc <- 2 # number of cores to use
registerDoMC(cores = nc)

# make all formula
fo <- paste0(y, "~", vars.model, "+", vars.remaining)
fo <- modify(fo, as.formula) %>%
  set_names(vars.remaining)

# fit models in parallel
all_rsq <- foreach(fo = fo) %dopar% {
  fit <- biglm(formula = fo, data = ff_df)
  new.rsq <- summary(fit)$rsq
}

我的问题的罪魁祸首是我有很多字符列。使用我的原始脚本将它们全部更改为因子后,它工作正常。

data %>%
  mutate_if(is.character, as.factor)

@meriops 的回答也不错。如果分解数据框不能解决问题,则可能需要考虑并行处理