【问题标题】:How can I parallelize a double for loop in R?如何在 R 中并行化双 for 循环?
【发布时间】:2015-09-04 19:40:42
【问题描述】:

我一直在尝试并行化我的代码,因为目前我正在使用双 for 循环来记录结果。我一直在尝试了解如何使用 R 中的 SNOW 和 doParallel 包来执行此操作。

如果您想要一个可复制的示例,只需使用

residual_anomalies <- matrix(sample(c('ANOMALY','NO SIGNAL'),300,replace=T),nrow=100)

而不是使用这三行

inputfile <- paste0("simulation_",i,"_",metrics[k],"_US.csv")
data <- residuals(inputfile)

residual_anomalies <- conceptdrift(data,length=10,threshold=.05)

在嵌套的for循环中。整个代码如下。

source("GetMetrics.R")
source("slowdrift_resampling_vectorized.R")

metrics <- unique(metrics)
num_metrics <- length(metrics)

f1_scores_table_raw = data.frame(matrix(ncol=10,nrow=46))
f1_scores_table_pred = data.frame(matrix(ncol=10,nrow=46))

rownames(f1_scores_table_raw) <- metrics
colnames(f1_scores_table_raw) <- paste0("Sim",1:10)

rownames(f1_scores_table_pred) <- metrics
colnames(f1_scores_table_pred) <- paste0("Sim",1:10)


for(k in 1:num_metrics){

  for(i in 1:10){
    #inputfile <- paste0("simulation_",i,"_",metrics[k],"_US.csv")
    #data <- residuals(inputfile)

    #residual_anomalies <- conceptdrift(data,length=10,threshold=.05)

    #the above is how I get the data frame but I'll create another one for reproducibility.
    residual_anomalies <- as.data.frame(matrix(sample(c('ANOMALY','NO SIGNAL'),300,replace=T),nrow=100))
    names(residual_anomalies) <- c("Raw_Anomaly","Prediction_Anomaly","True_Anomaly")

    #calculate precision and recall for an F1 score

    #first for raw data

    counts <- ifelse(rowSums(residual_anomalies[c("Raw_Anomaly","True_Anomaly")]=='ANOMALY')==2,1,0)
    correct_detections <- sum(counts)

    total_predicted = sum(residual_anomalies$Raw_Anomaly =='ANOMALY')
    total_actual = sum(residual_anomalies$True_Anomaly =='ANOMALY')

    raw_precision = correct_detections / total_predicted
    raw_recall = correct_detections / total_actual

    f1_raw = 2*raw_precision*raw_recall / (raw_precision+raw_recall)

    #then for prediction (DLM,ESP,MLR) data

    counts <- ifelse(rowSums(residual_anomalies[c("Prediction_Anomaly","True_Anomaly")]=='ANOMALY')==2,1,0)
    correct_detections <- sum(counts)

    total_predicted = sum(residual_anomalies$Prediction_Anomaly =='ANOMALY')
    total_actual = sum(residual_anomalies$True_Anomaly =='ANOMALY')

    pred_precision = correct_detections / total_predicted
    pred_recall = correct_detections / total_actual

    f1_pred = 2*pred_precision*pred_recall / (pred_precision+pred_recall)

    f1_scores_table_raw[[k,i]] <- f1_raw
    f1_scores_table_pred[[k,i]] <- f1_pred
  }

}

以前,我在外部循环上使用 foreach 并带有 %dopar%,但我遇到的问题是我一直收到未找到问题 '%dopar%' 的问题。我应该并行化两个循环还是只并行一个?

我也知道 foreach 创建了一个列表并将其存储到一个变量中,但是我仍然可以让其他变量在我的 foreach 循环中存储数据吗?例如,我仍然想将数据记录到我的 f1_scores_table_raw 和 f1_scores_table_pred 数组中。

谢谢!

【问题讨论】:

  • 我只能告诉你你想要什么(困惑可能是我的问题,而不是你的问题),但你正在寻找的大部分功能都在 ROCR 包中(精确召回曲线等)。我会考虑从那里开始。此外,也许添加您认为需要并行处理的瓶颈(即指标向量真的很大吗?您的文件是否比嵌套 for 循环中的硬编码 10 多得多?)。这可以通过一些矢量化而不是并行化来解决。
  • 我有 46 个指标和每个指标的 10 个模拟。不过,我将如何对其进行矢量化?
  • 由于在所有模拟中都计算了相同的指标,是否适合lapply(或者如果您觉得并行路线是理想的,clusterApplyLB)?我认为更好的问题是“瓶颈在哪里?”。对于上述看似非计算密集型的计算,嵌套并行语句似乎有点矫枉过正。或者我可能不知道。另外,您的问题不是关于方法的适当性,而只是对方法的帮助,很抱歉在没有真正帮助的情况下进行批评。
  • 在 for 循环中计算量很大。尤其是概念漂移函数,即使使用矢量化也需要很长时间。
  • 我明白你所说的 lapply 是什么意思。我将尝试这些而不是嵌套的 for 循环。

标签: r foreach parallel-processing


【解决方案1】:

如果您在循环级别之间使用%:% 运算符,Foreach 将自动处理此问题(请参阅“嵌套”小插图):

require(foreach)
# Register parallel backend

foreach (k = 1:num_metrics) %:% # nesting operator
  foreach (i = 1:10) %dopar% {
    # code to parallelise
}

【讨论】:

  • 在哪里提到嵌套循环中代码使用的包?每个都有外层还是内层?
猜你喜欢
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2013-12-12
  • 1970-01-01
  • 2017-07-01
  • 1970-01-01
相关资源
最近更新 更多