r - Foreach 和 doparallel 而不是 R 中的 for 循环

标签 r foreach parallel-processing doparallel

我需要通过多线程加速 for 循环。为此,我想使用以下库:foreachdoParallel。我以前使用过这些包,但仅用于需要一个结果表的过程。我不知道如何使用它们导出多个表(这里是结果表)。我的问题要复杂得多,需要导出许多结果集。在这里,为简单起见,我使用虹膜数据。

library(randomForest)
library(caret)

results_class <- data.frame()
results_overall <- data.frame()

for(i in 1:50){
  trainIndex <- caret::createDataPartition(iris$Species, p = 0.5, list = FALSE)
  irisTrain <- iris[ trainIndex,]
  irisTest  <- iris[-trainIndex,]

  model <- randomForest(x = irisTrain[,c(1:4)], y = irisTrain[,5], importance = TRUE,
                        replace = TRUE, mtry = 4, ntree = 500, na.action=na.omit,
                        do.trace = 100, type = "classification")

  pred_test <- predict(model, irisTest[,c(1:4)])
  con.mat_test <- confusionMatrix(pred_test, irisTest[,5], mode ="everything")

  results_class <- rbind(results_class, con.mat_test[["byClass"]])
  results_overall <- rbind(results_overall, con.mat_test[["overall"]])

}

最佳答案

据我所知,在 foreach 循环之外修改变量并不容易(甚至不可能),那么如何将多个结果存储在一个嵌套的 tibble 中呢?

library(randomForest)
library(caret)
library(foreach)
library(doParallel)

# Set up parallel computing
cl <- makeCluster(detectCores(logical = TRUE))
registerDoParallel(cl)

res <- foreach(i = 1:50, .packages = c("caret", "randomForest"), .combine = rbind) %dopar% {
    trainIndex <- caret::createDataPartition(iris$Species, p = 0.5, list = FALSE)
    irisTrain <- iris[ trainIndex,]
    irisTest  <- iris[-trainIndex,]

    model <- randomForest(x = irisTrain[,c(1:4)], y = irisTrain[,5], importance = TRUE,
                          replace = TRUE, mtry = 4, ntree = 500, na.action=na.omit,
                          do.trace = 100, type = "classification")

    pred_test <- predict(model, irisTest[,c(1:4)])
    con.mat_test <- confusionMatrix(pred_test, irisTest[,5], mode ="everything")

    # Save class into separate variable
    # Use substr to get rid of "Class: "
    class <- data.frame(con.mat_test[["byClass"]])
    overall <- data.frame(con.mat_test[["overall"]])
    class$class <- sapply(rownames(class), function(x) substr(x, 8, nchar(x)))
    overall$class <- sapply(rownames(overall), function(x) substr(x, 8, nchar(x)))

    # Save output dataframe in tibble as list column
    return(tibble::tibble(iteration = i, 
                          class = list(class), 
                          overall = list(overall)))
}

# Stop the cluster
stopCluster(cl)
registerDoSEQ()

然后输出如下:

> print(res)
# A tibble: 50 x 3
   iteration class              overall         
       <int> <list>             <list>          
 1         1 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 2         2 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 3         3 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 4         4 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 5         5 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 6         6 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 7         7 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 8         8 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
 9         9 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
10        10 <df[,12] [3 x 12]> <df[,2] [7 x 2]>
# ... with 40 more rows

关于r - Foreach 和 doparallel 而不是 R 中的 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60971747/

相关文章:

r - 在 R 中,如何用另一个向量的值替换具有特定条件的矩阵中的值?

r - 如何在 coplot 中的数据上绘制回归或 LOWESS 线

php - 在第四张专辑 PHP 之后添加新行

arrays - CUDA 减少了许多小的、大小不等的数组

python - scipy.optimize.fmin 的简单并行化

r - 根据组的第一行对组中的每一行进行变异

r - 使用 ggplot 记录计数的时间序列

c# - Foreach 在 xslt 中带有嵌套字典

java - 遍历列表以将字符添加到 Java 中的字符串列表

c - 平行结构?