2011-12-02 7 views
18

Potrzebuję wykonać kilka symulacji i dla celów debugowania Chcę użyć set.seed, aby uzyskać ten sam wynik. Oto przykład tego, co próbuję zrobić:Jak ustawić seed dla losowych symulacji z pakietami foreach i doMC?

library(foreach) 
library(doMC) 
registerDoMC(2) 

set.seed(123) 
a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
set.seed(123) 
b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 

Przedmioty a i b powinny być identyczne, tj sum(abs(a-b)) powinna wynosić zero, ale to nie jest przypadek. Robię coś nie tak, czy natknąłem się na jakąś funkcję?

jestem w stanie odtworzyć to na dwóch różnych systemach z R i R 2,13 2,14

Odpowiedz

17

domyślną odpowiedź kiedyś „no więc nie rób tego” (używając foreach) jako pakiet snow robi to (niezawodnie!) dla ciebie.

Ale jak @Spacedman wskazuje Renaud nowego doRNG jest to, czego szukasz, jeśli chcesz pozostać z rodziną doFoo/foreach.

Prawdziwym kluczem jest jednak wywołanie stylu klastrowego, aby uzyskać nasiona ustawione na wszystkich węzłach. I w sposób skoordynowany w różnych strumieniach. Aha, czy wspomniałem, że snow autorstwa Tierney, Rossini, Li i Sevcikova robią to dla ciebie od prawie dekady?

Edit: I choć nie pytałem o snow, dla kompletności tutaj jest przykład z wiersza poleceń:

[email protected]:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));\ 
     clusterSetupRNG(cl);\ 
     print(do.call("rbind", clusterApply(cl, 1:4, \ 
              function(x) { stats::rnorm(1) })))' 
Loading required package: utils 
Loading required package: utils 
Loading required package: rlecuyer 
      [,1] 
[1,] -1.1406340 
[2,] 0.7049582 
[3,] -0.4981589 
[4,] 0.4821092 
[email protected]:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));\ 
     clusterSetupRNG(cl);\ 
     print(do.call("rbind", clusterApply(cl, 1:4, \ 
              function(x) { stats::rnorm(1) })))' 
Loading required package: utils 
Loading required package: utils 
Loading required package: rlecuyer 
      [,1] 
[1,] -1.1406340 
[2,] 0.7049582 
[3,] -0.4981589 
[4,] 0.4821092 
[email protected]:~$ 

Edit: I pod względem kompletności, tutaj jest przykład łączyć z tym, co jest w docs dla doRNG

> library(foreach) 
R> library(doMC) 
Loading required package: multicore 

Attaching package: ‘multicore’ 

The following object(s) are masked from ‘package:parallel’: 

    mclapply, mcparallel, pvec 

R> registerDoMC(2) 
R> library(doRNG) 
R> set.seed(123) 
R> a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
R> set.seed(123) 
R> b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
R> identical(a,b) 
[1] FALSE      ## ie standard approach not reproducible 
R> 
R> seed <- doRNGseed() 
R> a <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> b <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> doRNGseed(seed) 
R> a1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> b1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) } 
R> identical(a,a1) && identical(b,b1) 
[1] TRUE      ## all is well now with doRNGseed() 
R> 
+0

Dzięki na przykład ze śniegiem. Nie jestem dobrze zaznajomiony z zawiłościami programowania równoległego w R, więc zacząłem używać 'foreach' dla jego bezbolesnego przejścia z kodu nierównoległego na równoległy. Wiedziałem, że czegoś mi brakuje. – mpiktas

+2

Cóż, dlatego wszyscy zaczęliśmy lata temu śniegiem, ponieważ przejście od standardowych funkcji * apply() do równoległych było łatwe :) –

4

Czy pakiet doRNG Jakiekolwiek użycie do ciebie? Podejrzewam, że problem wynika z dwóch nitek zarówno splatting losowy wektor nasion:

http://ftp.heanet.ie/mirrors/cran.r-project.org/web/packages/doRNG/index.html

+0

Dzięki za odpowiedź, naprawdę chciałbym zaznaczyć obie odpowiedzi jako odpowiedź, ale odpowiedź Dirka była szersza. Przegrałem jednak odpowiedź, ponieważ zawiera ona wystarczającą ilość informacji, aby rozwiązać mój problem. – mpiktas

2

dla bardziej skomplikowanych pętli, może trzeba obejmują set.seed() wewnątrz z pętli for:

library(foreach) 
library(doMC) 
registerDoMC(2) 
library(doRNG) 

set.seed(123) 
a <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(1, 2, 3) 
    rnorm(5) 
} 
set.seed(123) 
b <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(4, 5, 6) 
    rnorm(5) 
} 
identical(a, b) 
# FALSE 

kontra

a <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(1, 2, 3) 
    set.seed(123) 
    rnorm(5) 
} 
b <- foreach(i=1:2,.combine=cbind) %dopar% { 
    create_something <- c(4, 5, 6) 
    set.seed(123) 
    rnorm(5) 
} 
identical(a, b) 
# TRUE 
6

Korzystanie set.seed(123, kind = "L'Ecuyer-CMRG") robi też podstęp i nie wymaga dodatkowego pakietu:

set.seed(123, kind = "L'Ecuyer-CMRG") 
a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)} 
identical(a,b) 
# TRUE 
+0

Ta odpowiedź jest o wiele prostsza niż odpowiedź Dirka Eddulbuettela. Czy ma jakieś wady? –

Powiązane problemy