set.seed
プログラムを開始する前に、Rで関数を何度も見てきました。基本的に乱数の生成に使用されていることは知っています。これを設定する特別な必要性はありますか?
7 に答える
必要なのは、再現性のある結果を求める可能性のあることです。これは、たとえば、プログラムのデバッグを試みたり、もちろん、プログラムの機能をやり直したりすることから生じる可能性があります。
これらの2つの結果は、「ランダム」なものを要求したため、「決して」再現されません。
R> sample(LETTERS, 5)
[1] "K" "N" "R" "Z" "G"
R> sample(LETTERS, 5)
[1] "L" "P" "J" "E" "D"
ただし、シードを設定したため、これら2つは同じです。
R> set.seed(42); sample(LETTERS, 5)
[1] "X" "Z" "G" "T" "O"
R> set.seed(42); sample(LETTERS, 5)
[1] "X" "Z" "G" "T" "O"
R>
そのすべてについて膨大な文献があります。ウィキペディアは良いスタートです。本質的に、これらのRNGは、実際には完全にアルゴリズムであるため、疑似乱数ジェネレーターと呼ばれます。同じシードが与えられると、同じシーケンスが得られます。これは機能であり、バグではありません。
再現性のあるランダムな結果を得るには、毎回シードを設定する必要があります。
set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
いくつかの追加の側面を追加するだけです。シードを設定する必要性:学術界では、彼のアルゴリズムが1つのシミュレーションで98.05%のパフォーマンスを達成すると主張する場合、他の人はそれを再現できる必要があります。
?set.seed
この関数のヘルプファイルを調べると、これらはいくつかの興味深い事実です。
(1)set.seed()はNULLを返し、非表示
(2)「最初はシードはありません。必要に応じて、現在の時刻とプロセスIDから新しいシードが作成されます。したがって、セッションが異なれば、デフォルトでシミュレーション結果も異なります。ただし、シードは、以前に保存したワークスペースが復元された場合は、前のセッション。」これが、次に同じランダムシーケンスのシーケンスが必要になったときに、同じ整数値でset.seed()を呼び出す理由です。
ランダムに生成された数値を含む関数を最適化しようとする場合(シミュレーションベースの推定など)、シードの修正は不可欠です。大まかに言えば、シードを修正しないと、異なる乱数を描画することによる変動により、最適化アルゴリズムが失敗する可能性があります。
何らかの理由で、サンプルが与えられた場合に、シミュレーションによって平均ゼロ正規分布の標準偏差(sd)を推定するとします。これは、ステップの周りで数値最適化を実行することによって達成できます
- (シードの設定)
- sdの値を指定して、正規分布データを生成します
- シミュレートされた分布を前提として、データの可能性を評価します
次の関数は、これを実行します。1回はステップ1なしで、1回はそれを含めます。
# without fixing the seed
simllh <- function(sd, y, Ns){
simdist <- density(rnorm(Ns, mean = 0, sd = sd))
llh <- sapply(y, function(x){ simdist$y[which.min((x - simdist$x)^2)] })
return(-sum(log(llh)))
}
# same function with fixed seed
simllh.fix.seed <- function(sd,y,Ns){
set.seed(48)
simdist <- density(rnorm(Ns,mean=0,sd=sd))
llh <- sapply(y,function(x){simdist$y[which.min((x-simdist$x)^2)]})
return(-sum(log(llh)))
}
短いモンテカルロ研究で、真のパラメーター値を発見する際の2つの関数の相対的なパフォーマンスを確認できます。
N <- 20; sd <- 2 # features of simulated data
est1 <- rep(NA,1000); est2 <- rep(NA,1000) # initialize the estimate stores
for (i in 1:1000) {
as.numeric(Sys.time())-> t; set.seed((t - floor(t)) * 1e8 -> seed) # set the seed to random seed
y <- rnorm(N, sd = sd) # generate the data
est1[i] <- optim(1, simllh, y = y, Ns = 1000, lower = 0.01)$par
est2[i] <- optim(1, simllh.fix.seed, y = y, Ns = 1000, lower = 0.01)$par
}
hist(est1)
hist(est2)
結果として得られるパラメーター推定値の分布は次のとおりです。
シードを修正すると、数値検索は2の真のパラメーター値にはるかに近くなることが多くなります。
基本的に、set.seed()関数は、同じ確率変数のセットを再利用するのに役立ちます。これは、将来、同じ確率変数を使用して特定のタスクを再度評価するために必要になる可能性があります。
乱数生成関数を使用する前に、それを宣言する必要があります。
set.seed
は、同じランダム値の他の関数(、、)を一緒に(必要なときに)生成できる基本関数ですrnorm
。runif
sample
set.seedを使用しない例の下
> set.seed(NULL)
> rnorm(5)
[1] 1.5982677 -2.2572974 2.3057461 0.5935456 0.1143519
> rnorm(5)
[1] 0.15135371 0.20266228 0.95084266 0.09319339 -1.11049182
> set.seed(NULL)
> runif(5)
[1] 0.05697712 0.31892399 0.92547023 0.88360393 0.90015169
> runif(5)
[1] 0.09374559 0.64406494 0.65817582 0.30179009 0.19760375
> set.seed(NULL)
> sample(5)
[1] 5 4 3 1 2
> sample(5)
[1] 2 1 5 4 3
set.seedの例の下
> set.seed(123)
> rnorm(5)
[1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774
> set.seed(123)
> rnorm(5)
[1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774
> set.seed(123)
> runif(5)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673
> set.seed(123)
> runif(5)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673
> set.seed(123)
> sample(5)
[1] 3 2 5 4 1
> set.seed(123)
> sample(5)
[1] 3 2 5 4 1
さらに追加するだけです...一貫性が必要な場合は、ランダムな処理を行うたびにシードを設定する必要があります。シードは設定されたままではありません。
set.seed(0)
rnorm(3)
set.seed(0)
rnorm(3)
[1] 1.2629543 -0.3262334 1.3297993
[1] 1.2629543 -0.3262334 1.3297993
set.seed(0)
rnorm(3)
rnorm(3)
[1] 1.2629543 -0.3262334 1.3297993
[1] 1.2724293 0.4146414 -1.5399500