web-dev-qa-db-ja.com

set.seed関数を使用する理由

プログラムを起動する前に、Rでset.seed関数を見たことがあります。私はそれが基本的に乱数生成に使われているのを知っています。これを設定するための特別な必要性はありますか?

168
Vignesh

再現性のある結果が望まれる可能性があります。それは、たとえばプログラムをデバッグしようとしていること、またはもちろんそれをやり直すことから来ている可能性があることです。

これら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は、実際には完全にアルゴリズム:であるため、擬似乱数生成器と呼ばれます。同じシードを与えると、同じシーケンスになります。そしてそれは機能ですでバグではありません。

242

再現性のあるランダムな結果を得たい場合は毎回シードを設定する必要があります。

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
30
Chia-hung

追加の側面をいくつか追加するだけです。種を設定する必要性:学界で、彼のアルゴリズムが1つのシミュレーションで98.05%のパフォーマンスを達成したと主張する場合、他の人がそれを再現できる必要があります。

?set.seed

この関数のヘルプファイルを見てみると、これらは興味深い事実です。

(1)set.seed()がNULLを返し、見えない

(2) "最初はシードがありません。現在の時刻と必要に応じてプロセスIDから新しいものが作成されます。したがって、デフォルトではセッションが異なるとシミュレーション結果も異なります。前回保存したワークスペースを復元する場合は前回のセッションを参照してください。 "これが、次に同じ乱数シーケンスを使用するときに同じ整数値でset.seed()を呼び出す必要がある理由です。

16
Ridingstar

ランダムに生成された数を含む関数を最適化しようとするとき(例えば、シミュレーションベースの推定において)、シードを修正することは不可欠です。大まかに言えば、シードを修正しないと、異なる乱数を描画することによる変動によって最適化アルゴリズムが失敗する可能性があります。

何らかの理由で、サンプルを与えて、シミュレーションによって平均ゼロ正規分布の標準偏差(sd)を推定したいとします。これは、ステップの周りで数値最適化を実行することによって達成できます。

  1. (種を設定する)
  2. Sdの値が与えられると、正規分布データを生成します
  3. シミュレートされた分布が与えられたときにあなたのデータの尤度を評価する

次の関数は、ステップ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()関数は、同じランダム変数のセットを再利用するのに役立ちます。将来、同じランダム変数で再び特定のタスクを評価するために必要になるかもしれません。

乱数生成関数を使う前に宣言するだけです。

6
user4388407