我正在尝试在列表中保存多个GLM对象。一个GLM对象在大型数据集上进行训练,但通过在GLM对象中设置NULL所有不必要的数据来减小对象的大小。问题是我遇到了RAM问题,因为R保留了比GLM对象大得多的RAM。有人知道为什么会出现这个问题以及如何解决这个问题?在此保存后面,对象会产生比对象大小更大的文件。
示例:
> glm_full <- glm(formula = formule , data = dataset, family = binomial(), model = F, y = F)
> glm_full$data <- glm_full$model <- glm_full$residuals <- glm_full$fitted.values <- glm_full$effects <- glm_full$qr$qr <- glm_full$linear.predictors <- glm_full$weights <- glm_full$prior.weights <- glm_full$y <- NULL
> rm(list= ls()[!(ls() %in% c('glm_full'))])
> object.size(glm_full)
172040 bytes
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 944802 50.5 3677981 196.5 3862545 206.3
Vcells 83600126 637.9 503881514 3844.4 629722059 4804.4
> rm(glm_full)
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 944208 50.5 2942384 157.2 3862545 206.3
Vcells 4474439 34.2 403105211 3075.5 629722059 4804.4
在这里你可以看到R为GLM对象保留RAM,在环境中保存多个GLM对象会导致RAM问题。
答案 0 :(得分:1)
对此的一个粗略解释是glm
隐藏了指向glm
对象内部(以及许多地方)内部环境和环境的指针。
您需要使用glm
做什么?即使你已经淘汰了模型的很多“胖”,你的对象大小仍会随着你的数据大小呈线性增长,当你通过存储多个glm
对象来复合它时,会遇到RAM限制是一个明显的问题。
这是一个允许你切掉几乎所有非必要的函数的函数,最好的部分是glm
对象大小将保持不变,无论你的数据有多大。
stripGlmLR = function(cm) {
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$family$variance = c()
cm$family$dev.resids = c()
cm$family$aic = c()
cm$family$validmu = c()
cm$family$simulate = c()
attr(cm$terms,".Environment") = c()
attr(cm$formula,".Environment") = c()
cm
}
一些注意事项:
您可以完全忽略model$family
,predict
函数仍将返回其默认值(因此,predict(model, newdata = data))
将起作用)。但是,predict(model, newdata=data, type = 'response')
将失败。您可以通过反向链接函数传递链接值来恢复response
:在逻辑回归的情况下,这是sigmoid函数sigmoid(x) = 1/(1 + exp(-x))
。 (不确定type = 'terms'
)
最重要的是,除了predict
之外,您可能希望对glm
模型执行的任何其他操作都会在精简版本上失败(所以summary()
,{{1 }}和anova()
都是禁忌的。因此,您最好从step()
对象中提取所有这些信息,然后运行glm
函数。
CREDIT:Nina Zumel对stripGlmLR
对象内存分配进行了精彩的分析