并行处理 - R 在使用 RNG 时不会重置种子"L'Ecuyer-CMRG"?



我在R中进行了一些并行模拟,我注意到种子当使用"L'Ecuyer-CMRG"rng时不会发生变化。我在读书书"平行R",以及选项mc.set.seed=TRUE应该给出每次调用mclapply((时,每个工作者都有一个新的种子。

这是我的代码:

library(parallel)
RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(n) rnorm(n), mc.set.seed = TRUE)
[[1]]
[1] -0.7125037
[[2]]
[1] -0.9013552  0.3445190
mclapply(1:2, function(n) rnorm(n), mc.set.seed = TRUE)
[[1]]
[1] -0.7125037
[[2]]
[1] -0.9013552  0.3445190

编辑:同样的事情发生在我的台式机和笔记本电脑上(都是Ubuntu 12.04 LTS(。

在我看来,如果你想保证在R会话中对mclapply的后续调用得到不同的随机数,你需要用不同的值调用set.seed,删除全局变量".random.seed",或者在再次调用mclapply之前,在该R会话中至少生成一个随机数。

这种行为的原因是mclapply(例如与mcparallel不同(在内部调用mc.reset.stream。这会将存储在"并行"包中的种子重置为值"Random.seed",因此,如果再次调用mclapply时"Random.seeed"没有更改,则由mclapply启动的工作程序将获得与以前相同的随机数。

请注意,clusterApply和parLapply等函数的情况并非如此,因为它们使用持久工作者,因此会继续从其RNG流中提取随机数。但每次mclapply被呼叫时,新员工都会被分流,这可能会让这种行为变得更加困难。

下面是一个使用mclapply将种子设置为不同值以获得不同随机数的示例:

RNGkind("L'Ecuyer-CMRG")
set.seed(100)
mclapply(1:2, function(i) rnorm(2))
set.seed(101)
mclapply(1:2, function(i) rnorm(2))

这里有一个删除"随机种子"的例子:

RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rm(.Random.seed)
mclapply(1:2, function(i) rnorm(2))

这里有一个在主机上生成随机数的例子:

RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rnorm(1)
mclapply(1:2, function(i) rnorm(2))

我不确定哪种方法是最好的,但这可能取决于你想做什么

尽管看起来简单地多次调用mclapply而不更改".Random.seed"会产生可重复的结果,但我不知道这是否能保证。为了保证可重复的结果,我认为你需要调用set.seed:

RNGkind("L'Ecuyer-CMRG")
set.seed(1234)
mclapply(1:2, function(i) rnorm(2))
set.seed(1234)
mclapply(1:2, function(i) rnorm(2))

您是否考虑过使用clusterApply而不是mclapply?我认为使用这个框架更容易保证可复制的示例。我附上一个例子。

library(parallel)
#---- creating local cluster ----
clust <- makeCluster(detectCores())
#---- seed ----
RNGkind(kind = "L'Ecuyer-CMRG")
set.seed(1234)
s <- .Random.seed
clusterSetRNGStream(cl = clust, iseed = s)
#---- generating random numbers ----
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -0.0514128  0.7344781
#> 
#> [[2]]
#> [1]  0.3946233 -0.6649782
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -1.57875323 -0.07533176
#> 
#> [[2]]
#> [1] -0.3698359 -0.1564795
#---- repeating the process ----
set.seed(1234)
s <- .Random.seed
clusterSetRNGStream(cl = clust, iseed = s)
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -0.0514128  0.7344781
#> 
#> [[2]]
#> [1]  0.3946233 -0.6649782
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -1.57875323 -0.07533176
#> 
#> [[2]]
#> [1] -0.3698359 -0.1564795
# same result

创建于2019-03-04由reprex包(v0.2.1(

devtools::session_info()
#> Session info -------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.5.1 (2018-07-02)
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  tz       America/Sao_Paulo           
#>  date     2019-03-04
#> Packages -----------------------------------------------------------------
#>  package   * version date       source         
#>  backports   1.1.2   2017-12-13 CRAN (R 3.5.0) 
#>  base      * 3.5.1   2018-07-03 local          
#>  compiler    3.5.1   2018-07-03 local          
#>  datasets  * 3.5.1   2018-07-03 local          
#>  devtools    1.13.6  2018-06-27 CRAN (R 3.5.0) 
#>  digest      0.6.17  2018-09-12 cran (@0.6.17) 
#>  evaluate    0.11    2018-07-17 cran (@0.11)   
#>  graphics  * 3.5.1   2018-07-03 local          
#>  grDevices * 3.5.1   2018-07-03 local          
#>  htmltools   0.3.6   2017-04-28 CRAN (R 3.5.0) 
#>  knitr       1.20    2018-02-20 CRAN (R 3.5.0) 
#>  magrittr    1.5     2014-11-22 cran (@1.5)    
#>  memoise     1.1.0   2017-04-21 CRAN (R 3.5.0) 
#>  methods   * 3.5.1   2018-07-03 local          
#>  parallel  * 3.5.1   2018-07-03 local          
#>  Rcpp        0.12.18 2018-07-23 cran (@0.12.18)
#>  rmarkdown   1.10    2018-06-11 CRAN (R 3.5.1) 
#>  rprojroot   1.3-2   2018-01-03 CRAN (R 3.5.0) 
#>  stats     * 3.5.1   2018-07-03 local          
#>  stringi     1.2.4   2018-07-20 cran (@1.2.4)  
#>  stringr     1.3.1   2018-05-10 CRAN (R 3.5.0) 
#>  tools       3.5.1   2018-07-03 local          
#>  utils     * 3.5.1   2018-07-03 local          
#>  withr       2.1.2   2018-03-15 CRAN (R 3.5.0) 
#>  yaml        2.2.0   2018-07-25 cran (@2.2.0)

最新更新