我有一个大数据框,其中包含约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在这里如何精确地处理内存,但是我400万行数据的
biglm
输出非常小(6.6 KB)。当我将其包装到sapply
中时,我不知道它如何累积到几个GB。任何有关如何优化这一点的技巧都将不胜感激。
最佳答案
内存使用率上升是因为每次对biglm()
的调用都会在内存中复制数据。由于sapply()
本质上是一个for循环,因此使用doMC
(或doParallel
)允许使用内存中数据的单个副本进行循环。这是一种可能性:
编辑:正如@moho wu指出的那样,并行拟合会有所帮助,但还不够。因素比普通字符更有效,因此也有帮助。然后ff
可以提供更多帮助,因为它将更大的数据集保留在磁盘上而不是内存中。我更新了以下代码,使其使用ff
和doMC
成为完整的玩具示例。
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
}
关于r - lm的内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49984743/