我在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)。
答案 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)