【问题标题】:Nested loop: multiple model parameters嵌套循环:多个模型参数
【发布时间】:2016-06-29 17:48:57
【问题描述】:

我正在编写一个代码,该代码将计算具有多个参数的统计模型,我想在此过程中对其进行更改。然后,根据模型的性能,我会选择最好的。

我写了这么一段伪代码来说明问题:

## vectors with values of parameters

const1 <- c(300, 500)
const2 <-  c(1, 2, 3, 4, 5)
const3 <- c(30, 50, 70, 90, 110, 130)

## loop counter

i = 1

for (j in 1:length(const1)){
  for (k in 1:length(const2)){
    for (l in 1:length(const3)){

      ## i-th model

      model <- stat.model(x = train,
                          y = target,
                          param1 = const1,
                          param2 = const2,
                          param3 = const3)

      ## ... outputing model results to a data table

      ## printing the number of iteration

      cat("iteration =", i)
      i <- i+1

      ## calling garbage collector to assure free space in RAM

      gc()
    }
  }
}

如您所见,我使用嵌套的“for”循环,这可能不是 R 中最有效的编程方式。有什么方法可以缩短处理时间(并可能节省代码的易读性)?

【问题讨论】:

    标签: r performance loops for-loop time


    【解决方案1】:

    您可以使用 lapply 语句对您的操作进行矢量化处理,用于您的伪代码

    model <- function(x,y,z){x+y+z}
    
    lapply(const1,function(x){
      lapply(const2,function(y){
        lapply(const3,function(z){model(x,y,z)})})})
    

    【讨论】:

      【解决方案2】:

      for 的速度在R 中循环。

      R 中,使用嵌套for-loops 的主要问题是可读性(可能还有内存分配)。因此,如果您事先知道输出的长度,请使用vector() 创建此长度的存储对象,或者直接调用lapplyvapplyfor-loop 本身的速度在R 中并不是一个严重的问题。

      可读性

      对于您的示例,您可以通过在您的三个向量上调用 expand.grid 来简单地创建您想要使用的所有可能的组合,您正在使用三个不同的嵌套 for-loops,如下所示:

      combis <- expand.grid(const1 = const1,
                            const2 = const2,
                            const3 = const3)
      
      combis <- combis[order(combis$const1, combis$const2, combis$const3), ]
      
      lapply(seq_len(nrow(combis)), FUN = function(i) {
        model <- stat.model(x = train,
                            y = target,
                            param1 = combis[i, "const1"],
                            param2 = combis[i, "const2"],
                            param3 = combis[i, "const3"])
        model
      })
      

      并行化

      如果您有多个内核可供使用,您可以使用 parallel 包中的 mclapply 轻松地将任何 lapply“循环”转换为并行版本。然后您可以通过mc.cores 参数指定核心数。这使您可以轻松地并行化循环。

      【讨论】:

      • 非常感谢!您的代码中可能存在一个错误:我必须将 seq_along(nrow(combis) 更改为 seq(1, nrow(combis) 才能使其正常工作。
      • 你是对的。我已将 seq_along 更改为 seq_len,这与您的建议相同。
      猜你喜欢
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      相关资源
      最近更新 更多