【问题标题】:Problems with using glm in foreach在 foreach 中使用 glm 的问题
【发布时间】:2017-03-08 17:11:32
【问题描述】:

我正在尝试使用 foreach 循环来玩多个 glms。我遇到的问题是,当我尝试指定权重时,它表示找不到对象。下面是重现我遇到的问题的代码。

library(foreach)
library(doParallel)

registerDoParallel(cores=4)  
getDoParWorkers()



train_samples<-vector(mode="list", length=4)
for(i in 1:4){
  train_samples[[i]]<-sample(nrow(mtcars),nrow(mtcars)*.8,replace=FALSE)
}

train_samples
d_data<-mtcars
#Add a weights column to illustrate the issue. The actual weights would vary.
d_data$weights = 1 

#This results in an error: object 'd_data' not found
foreach(k=1:4) %dopar%{
  model.fit<-glm(formula='hp~cyl+disp+mpg',
                 family=poisson,
                 data=d_data[train_samples[[k]],],
                 weights=d_data[train_samples[[k]],12])
}

#Removing the weights condition makes it run fine.
foreach(k=1:4) %dopar%{
  model.fit<-glm(formula='hp~cyl+disp+mpg',
                 family=poisson,
                 data=d_data[train_samples[[k]],])
}

我已经在网上寻找解决方案,但找不到任何东西。我想知道为什么这是一个问题以及如何解决它。提前致谢!

编辑 1:我在下面添加了一个附加示例。

w1<-numeric(25)+1

#This has the same problem with object w1 not being found.
#Setting .export="w1" doesn't help either
foreach(k=1:4, .export="w1") %dopar%{
  model.fit<-glm(formula='hp~cyl+disp+mpg',
                 family=poisson,
                 data=d_data[train_samples[[k]],],
                 weights=w1)
}

#However, manually defining a numeric vector for weights works
foreach(k=1:4) %dopar%{
  model.fit<-glm(formula='hp~cyl+disp+mpg',
                 family=poisson,
                 data=d_data[train_samples[[k]],],
                 weights=numeric(25)+1)
}

编辑 2:版本信息。

Windows 10
RStudio 版本:1.0.136
R 版本:3.3.1
foreach 版本:1.4.3
doParallel 版本:1.0.10

【问题讨论】:

  • 您可能需要将权重/数据传递给处理它的核心。 gforge.se/2015/02/how-to-go-parallel-in-r-basics-tips你试过.export吗?
  • 我无法复制您的错误。我得到一个不同的错误,“任务 1 失败 - “找不到对象 'k'”。
  • @MJH,我尝试过使用 .export="d_data" 并得到相同的错误,警告 d_data 已经被导出。我在下面添加了一个附加示例。
  • @msubbaiah,我不确定您为什么会收到该错误。如果错误是由“权重”参数引起的,我添加了一个额外的示例,它可能对您有用。
  • @Kyle 感谢您的编辑。导出功能应该可以工作。我仍然无法复制您的错误。两个 foreach 循环都为我运行。

标签: r foreach glm


【解决方案1】:

我能够复制您的错误。我不确定它为什么会出现,但我想出了一个可行的解决方案。

如果您将 glm 函数从循环中取出并创建一个单独的函数,然后在循环中使用它,它就可以工作。

model <- function(k, input_data, samples){

  samples <- samples[[k]]
  input_data <- input_data[samples,]
  weights <- input_data[samples, 12]
  print(weights)

  model.fit <- glm(formula = 'hp ~ cyl + disp + mpg',
                 family = poisson,
                 data = input_data,
                 weights = weights)

  return(model.fit)
}


trial.data <- foreach(k = 1:4, 
                      .errorhandling = 'pass') %dopar% {
                        model(k, d_data, train_samples)
                      }

print(trial.data)

此外,如果您使用 .errorhandling,它会为您提供更多信息,这些信息有时会很有用(在这种情况下并非如此,仅供参考)。

希望这对你有用。

【讨论】:

  • 感谢您的帮助!不幸的是,这对我来说不太合适。它会运行良好,但包含 .errorhandling = 'pass' 会导致 trial.data 变量被错误消息填充。运行代码时是否存储错误消息或结果?
  • @Kyle 为延迟道歉。我调整了模型功能。这现在适用于并行和非并行处理。此外,您可能希望在通过多个循环实现此之前调查您的抽样或权重。如果你从 %dopar% 切换到 %do%,你会得到 NA 值,并通过 print weights 语句报告
  • 太棒了,这对我有用!我不确定为什么需要以特定方式指定权重。我发现如果你使用 speedglm 包,你不会遇到定义权重的问题。我认为打印权重语句报告的 NA 值是由于在对 input_data 采样后定义权重而产生的。切换 input_data
【解决方案2】:

这个聚会迟到了,但问题是glm() 首先在数据环境中寻找权重,然后是公式。当您使用%dopar% 并行运行时,您提供的权重向量不会出现在这些环境中。引用全局环境可以让代码正确运行:

foreach(k=1:4) %dopar% {
  #Create a weight vector, saves on globalenv() references later
  w=d_data[train_samples[[k]],12]
  model.fit<-glm(formula='hp~cyl+disp+mpg',
                 family=poisson,
                 data=d_data[train_samples[[k]],],
                 #Instruct glm() to look in the global environment for weights
                 weights=globalenv()$w)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2020-09-25
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    相关资源
    最近更新 更多