我想使用optimParallel从R中的包中优化函数。到现在为止,我只优化了在环境中编写的函数,并且该函数一直有效。但是任何包中的功能都无法正常工作,并且出现错误。我使用.libPaths()检查每个节点上的路径是否相同,并使用Sys.info()检查是否有任何差异。这是一个示例(没有意义,但应该显示我的问题)
library(optimParallel)
.libPaths()
[1] "C:/Users/Name/Documents/R/win-library/3.5" "C:/Program Files/R/R-3.5.1/library"
cl <- makeCluster(2) #also tried to set "master" to my IP
clusterEvalQ(cl, .libPaths())
[[1]]
[1] "C:/Users/Name/Documents/R/win-library/3.5" "C:/Program Files/R/R-3.5.1/library"
[[2]]
[1] "C:/Users/Name/Documents/R/win-library/3.5" "C:/Program Files/R/R-3.5.1/library"
setDefaultCluster(cl)
optimParallel(par=0, dnorm, mean=1, method = "L-BFGS-B")$par
Error in checkForRemoteErrors(val) :
2 nodes produced errors; first error: object 'C_dnorm' not found
#for comparison
optim(par=0, dnorm, mean=1, method = "L-BFGS-B")$par
[1] -5.263924
我在做什么错了?
答案 0 :(得分:0)
考虑到您的错误消息表明并行进程未获得足够的信息,我查看了optimParallel
软件包文档中的示例。第一个定义了一个辅助函数,该函数将随环境一起提供,但在某些方面与您的环境类似。
library(optimParallel)
set.seed(123); x <- rnorm(n=1000, mean=1, sd=2)
negll <- function(par, x) -sum(dnorm(x=x, mean=par[1], sd=par[2], log=TRUE))
o1 <- optimParallel(par=c(0, 1), fn=negll, x=x, method="L-BFGS-B", lower=c(-Inf, 0.0001))
o1$par
#[1] 1.032256 1.982398
该示例也与您的示例不同,因为它使用数据来估计参数。我不确定您的结果意味着什么,但是我确实理解了我在此处发布的示例修改所返回的值。该特定数据的最小对数可能性(由于我忘记设置种子而不完全可重现),平均值为1.126,标准差为2.007。
有关如何创建非基本软件包的环境被带到工作人员的情况的示例,请参见以下先前的答案:parallel::clusterExport how to pass nested functions from global environment?
答案 1 :(得分:0)
该版本在CRAN上可用:https://CRAN.R-project.org/package=optimParallel
一种解决方法是将dnorm()
包装到.GlobalEnv
中定义的函数中。
library("optimParallel")
cl <- makeCluster(2)
setDefaultCluster(cl)
f <- function(x, mean) dnorm(x, mean=mean)
optimParallel(par=0, f, mean=1, method="L-BFGS-B")$par
[1] -5.263924
一个更困难的任务是解释问题发生的原因:
optimParallel()
使用parallel::parLapply()
来评估f
。parLapply()
的参数为cl
,X
,fun
。如果我们不经预处理就使用parLapply()
的{{1}}传递的参数,则...
不能有名为optimParallel()
的参数,f
,cl
,因为这会导致以下错误:
X
fun
通过从Error in lapply(X = x, FUN = f, ...) (from #2) :
formal argument "X" matched by multiple actual arguments
中删除所有参数,将其放入环境中并在该环境中评估optimParallel()
来避免此错误。 f
并链接到已编译的代码时,会发生该方法的问题。上面的问题说明了这种情况。欢迎提出更好的方法来解决此问题。我打开了一个相应的问题here。只要没有更好的解决方案,就可以使用上述解决方法。