R中使用lapply调用predFit出现预测文件过大内存报错如何解决
R中predFit计算NLS置信区间内存溢出解决方案
报错根因
内存溢出和lapply的使用无关,问题出在investr::predFit对nls模型计算置信区间的内部逻辑:
- predFit默认采用蒙特卡洛模拟/Bootstrap法计算nls的置信区间,会根据传入的newdata行数和默认模拟次数生成超大的中间计算矩阵,这部分内存开销远大于最终输出的预测结果大小
- 你传入122735行预测数据,默认模拟次数为10000次时,单次预测就会生成
122735 * 10000的数值矩阵,单矩阵内存开销约9GB,多模型计算时很容易突破内存上限触发报错
解决方案
可根据精度需求选择以下任意方案:
方案1:改用Delta方法近似计算置信区间
Delta方法是解析近似方法,不需要生成大型模拟矩阵,内存占用极低,大部分场景下精度足够使用:
library(dplyr) # 预测逻辑修改,指定method = "delta" results <- lapply(seq_along(model), function(i) { pred_res <- predFit(model[[i]], newdata = predictions, interval = "confidence", level = 0.9, method = "delta") # 追加标识列方便后续合并 as_tibble(pred_res) %>% mutate(temp = predictions$temp, id = names(model)[i]) }) # 合并所有模型结果为一个数据框 final_result <- bind_rows(results)
方案2:降低模拟次数
如果必须使用模拟法计算区间,可以通过nsim参数减少模拟次数,降低内存开销:
results <- lapply(seq_along(model), function(i) { pred_res <- predFit(model[[i]], newdata = predictions, interval = "confidence", level = 0.9, nsim = 1000) # 从默认10000改为1000,内存降至原来的1/10 as_tibble(pred_res) %>% mutate(temp = predictions$temp, id = names(model)[i]) })
方案3:分批预测
如果既需要高模拟次数又不想改计算方法,可以把12万行预测数据拆分为多批,分批跑完再合并结果,避免单次生成超大矩阵。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

