9

R でいくつかの並列シミュレーションを行っていましたが、"L'Ecuyer-CMRG" rng を使用するとシードが変更されないことに気付きました。私は本「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の両方)で同じことが起こります。

4

2 に答える 2

5

Rセッションでのmclapplyへの後続の呼び出しが異なる乱数を取得することを保証したい場合は、異なる値でset.seedを呼び出すか、グローバル変数「.Random.seed」を削除するか、生成する必要があるようですmclapply を再度呼び出す前に、その R セッションで少なくとも 1 つの乱数。

この動作の理由は、mclapply が (たとえば mcparallel とは異なり) mc.reset.stream を内部的に呼び出すためです。これにより、「parallel」パッケージに格納されているシードが「.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))

どちらが最善のアプローチかはわかりませんが、それはあなたが何をしようとしているのかに依存するかもしれません.

「.Random.seed」を変更せずに mclapply を複数回呼び出すだけで再現可能な結果が得られるように見えますが、それが保証されているかどうかはわかりません。再現可能な結果を​​保証するには、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))
于 2013-02-27T20:32:25.513 に答える