【问题标题】:Run ovun.sample in R doParallel foreach loop在 R doParallel foreach 循环中运行 ovun.sample
【发布时间】:2016-05-09 01:54:39
【问题描述】:

我只是无法在并行 foreach 中使用 ovun.sample。

下面是最小的工作示例。

library(doParallel)
library(ROSE) # ovun.sample

if(!getDoParRegistered()){
  registerDoParallel(cores=detectCores())
}

foreach(i=1:2,.combine=rbind, .packages=c("ROSE")) %dopar% {
  my_data = iris[iris$Species != "setosa",]
  under_data <- ovun.sample(Species ~ ., data=my_data, N=40, seed = 1)$data
}
print(r)

我得到错误:

Error in { : task 1 failed - "object 'my_data' not found"

任何想法我错过了什么。或者可能是另一个类似于 ROSE 的过/过采样包,可与 doParallel 一起使用?在 Windows 上运行。

【问题讨论】:

    标签: r doparallel


    【解决方案1】:

    ovun.sample 的问题在于,不幸的是,它似乎在假设变量位于全局范围内的情况下尝试执行代码: https://github.com/cran/ROSE/blob/master/R/data_balancing_funcs.R#L26

    以下代码有助于直观地了解ovun.sample 不起作用的原因:

    my.ovun.sample <- function(dataset) {
      my_data <- dataset
      ovun.sample(cls ~ ., data = my_data, method="both", N=200, seed=1)$data
    }
    
    my.ovun.sample(dataset=hacide.train)
    

    它将产生:

    adj.formula(公式,数据)中的错误:找不到对象“my_data”

    所以,如果我们调试问题,当它在ovun.sample source code 中执行第 24 行时:

    sys.nframe()
    # [1] 2
    

    这意味着 R 当前位于 environment #2 中。

    然后我们继续调试当前范围内可用的变量:

    ls(sys.frame(2))
    # [1] "Call"      "Call1"     "data"      "formula"   "m"         "method"    "N"         "na.action" "p"         "seed"     
    # [11] "subset"   
    

    然后我们继续调试父作用域内的内容(即my.ovun.sample 函数):

    ls(sys.frame(1))
    # [1] "dataset" "my_data"
    

    最后在全局范围内:

    ls(sys.frame(0))
    # [1] "hacide.test"    "hacide.train"   "my.ovun.sample"
    

    现在,当执行以下行时:

    res <- eval(Call1)
    

    代码将引发错误,因为 my_data 在该环境中不可用。如果我们将代码更改为:

    my.ovun.sample <- function(dataset) {
      my_data <- dataset
      ovun.sample(cls ~ ., data = get("my_data", sys.frame(1)), method="both", N=200, seed=1)$data
    }
    

    现在,当使用foreach 时,data=get("my_data", sys.frame(1)) 的问题是并行环境并不总是 1。要解决这个问题,我们需要使用更通用的方式来发送当前帧。这是一个似乎有效的代码:

    library(doParallel)
    library(ROSE) # ovun.sample
    data(hacide)
    
    if (!getDoParRegistered()) {
      registerDoParallel(cores=detectCores())
    }
    
    my_results = foreach(i=1:2, .combine=rbind, .packages=c("ROSE")) %dopar% {
      my_data <- hacide.train
      my_data$i <- i
    
      # this sends the current_frame to global environment
      curr_frame <<- sys.nframe()
    
      ovun.sample(cls ~ ., data = get("my_data", sys.frame(curr_frame)), method="both", N=200, seed=1)$data
    }
    
    registerDoSEQ()
    
    print(head(my_results))
    #  cls          x1         x2 i
    # 1   0  0.56444509 -0.7198744 1
    # 2   0  0.73493507  0.4791222 1
    # 3   0 -0.39307673  0.8098423 1
    # 4   0 -0.39934508 -0.2746103 1
    # 5   0 -0.06157228 -1.2983649 1
    # 6   0  0.20251246 -0.6173485 1
    
    print(tail(my_results))
    #    cls        x1        x2 i
    # 395   1 -2.789707 -1.497824 2
    # 396   1 -2.149788 -1.708764 2
    # 397   1 -0.741708 -1.973571 2
    # 398   1 -2.149788 -1.708764 2
    # 399   1 -1.427158 -1.415405 2
    # 400   1 -2.037152 -1.127303 2
    
    print(table(my_results$cls))
    #   0   1 
    # 196 204
    
    print(table(my_results$i))
    #  1   2 
    # 200 200
    

    【讨论】:

    • 是的,这需要 var global。谢谢!
    【解决方案2】:

    foreach 循环在寻找my_data 的位置具有不同的环境上下文。尝试将data=my_data 替换为data=get("my_data", sys.frame(1))

    另一种方法是在foreach之前设置数据变量,并在foreach调用中使用.export=my_data选项确保数据在执行前推送到每个内核。

    【讨论】:

    • 感谢您的建议,但data=get("my_data", sys.frame(1)) 也不起作用。我也试过 .export=c("my_data"),也没有用。但这有效:result &lt;- foreach(i=1:2,.combine=rbind, .packages=c("SDR", "ROSE") ) %dopar% { my_data = iris[iris$Species != "setosa",] sum(iris$Species == "virginica") } print(result) 我只是不知道为什么不适用于函数 ovun.sample。
    • 要使.export=my_data 工作,必须在主代码中的foreach 循环之前定义my_data。这真的应该工作。它必须与执行环境有关。 ?ovun.sampledata 选项描述为If not specified, the variables are taken from “environment(formula).。这向我表明,这可能是公式中的.my_data 之间的冲突。如果您完全放弃 data=my_data 选项会发生什么?
    【解决方案3】:

    在 foreach 循环中设置my_data 时,尝试使用my_data &lt;&lt;- ...

    这会将赋值的结果放到全局环境中

    【讨论】:

      猜你喜欢
      • 2020-06-07
      • 2017-10-19
      • 2020-07-13
      • 2021-09-16
      • 1970-01-01
      • 2015-03-17
      • 2016-10-08
      • 2016-03-11
      • 1970-01-01
      相关资源
      最近更新 更多