You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过并行化加速tidymodels的Bootstrapping过程

解决rsample Bootstrap并行化及兼容int_pctl的方案

问题背景

我使用rsample包执行Bootstrapping并计算置信区间时,原代码运行速度极慢。尝试用parallel包的mcmapply实现并行化失败,需要找到能兼容int_pctl()函数的并行加速方案。

原代码

library(resample)
library(broom)
library(dplyr)
library(purrr)
library(tibble)

lm_est <- function(split, ...) {
  lm(mpg ~ disp + hp, data = analysis(split)) %>%
    tidy()
}

set.seed(52156)
car_rs <- 
  bootstraps(mtcars, 500, apparent = TRUE) %>%
  mutate(results = map(splits, lm_est))

int_pctl(car_rs, results) # 关键步骤

原代码运行结果

> int_pctl(car_rs, results)
# A tibble: 3 × 6
  term         .lower .estimate   .upper .alpha .method   
  <chr>         <dbl>     <dbl>    <dbl>  <dbl> <chr>     
1 (Intercept) 27.7      31.0    34.1       0.05 percentile
2 disp        -0.0431   -0.0295 -0.0123    0.05 percentile
3 hp          -0.0643   -0.0281 -0.00930   0.05 percentile

失败的并行尝试代码

library(parallel)
# 设置并行核心数
cores <- detectCores() - 1
cl <- makeCluster(cores)

# 用mcmapply并行处理
car_rs$results <- mcmapply(lm_est, car_rs$splits, mc.cores = cores, mc.preschedule = TRUE)

stopCluster(cl)

可行解决方案

方案1:用furrr实现并行(推荐,适配tidyverse/rsample生态)

furrr是purrr的并行扩展,完美兼容rsample的结果结构,直接替换map为future_map即可,无需额外调整就能让int_pctl()正常工作。

library(furrr)
library(rsample)
library(broom)
library(dplyr)
library(tibble)

# 初始化并行环境,保留1个核心给系统
plan(multisession, workers = detectCores() - 1)

lm_est <- function(split, ...) {
  lm(mpg ~ disp + hp, data = analysis(split)) %>%
    tidy()
}

set.seed(52156)
car_rs <- 
  bootstraps(mtcars, 500, apparent = TRUE) %>%
  mutate(results = future_map(splits, lm_est)) # 替换map为future_map

# 正常调用int_pctl,结果和原代码一致
int_pctl(car_rs, results)

# 结束并行环境(可选,R会话关闭时会自动清理)
plan(sequential)

方案2:修复parallel包的使用方式

之前的mcmapply失败有两个原因:一是默认简化结果结构,破坏了int_pctl()需要的列表格式;二是并行节点未加载必要的包。修复后可正常运行:

library(parallel)
library(rsample)
library(broom)
library(dplyr)
library(tibble)

cores <- detectCores() - 1
cl <- makeCluster(cores)

# 在所有并行节点加载所需包
clusterEvalQ(cl, {
  library(rsample)
  library(broom)
  library(dplyr)
})

# 把自定义函数传给并行节点
clusterExport(cl, "lm_est")

lm_est <- function(split, ...) {
  lm(mpg ~ disp + hp, data = analysis(split)) %>%
    tidy()
}

set.seed(52156)
car_rs <- bootstraps(mtcars, 500, apparent = TRUE)

# 使用parLapply保持列表结构,或mcmapply加SIMPLIFY=FALSE
car_rs$results <- parLapply(cl, car_rs$splits, lm_est)
# 也可以用:car_rs$results <- mcmapply(lm_est, car_rs$splits, mc.cores = cores, SIMPLIFY = FALSE)

stopCluster(cl)

# 正常调用int_pctl
int_pctl(car_rs, results)

失败原因说明

  1. 结构不兼容:mcmapply默认SIMPLIFY=TRUE,会把多个tidy返回的数据框自动转为数组,破坏了int_pctl()需要的列表结构;
  2. 环境缺失:并行节点未加载rsample、broom等包,无法识别analysis()、tidy()这类函数。

内容的提问来源于stack exchange,提问作者littleworth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:20:32