当使用“L'Ecuyer-CMRG”RNG时,R不会重置种子?

时间:2013-02-25 15:25:18

标签: r parallel-processing prng

我在R中做了一些并行模拟,我发现了种子 使用“L'Ecuyer-CMRG”时不会更改。我正在读书 书“Parallel 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)。

2 个答案:

答案 0 :(得分:3)

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

此行为的原因是mclapply(例如,与mcparallel不同)在内部调用mc.reset.stream。这会将“并行”包中存储的种子重置为“.Random.seed”的值,因此如果再次调用mclapply时“.Random.seed”没有改变,那么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))

以下是删除“.Random.seed”的示例:

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))

答案 1 :(得分:0)

您是否考虑过使用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

reprex package(v0.2.1)于2019-03-04创建

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)