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


回答:


264

必要なのは、たとえばプログラムをデバッグしようとしたり、もちろんそれをやり直したりすることによって発生する可能性のある、再現可能な結果に対する考えられる欲求です。

これらの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は実際には完全にアルゴリズム化されているため、疑似乱数ジェネレータと呼ばれます。同じシードを指定すると、同じシーケンスが得られます。そしてそれは機能であり、バグではありません。


5
このような素晴らしい例を提供してくれたDirkに感謝します。私は99%でクリアしましたが、それでも質問があります。1.回答で、42を引数としてset.seedを使用しました。この値を選択する理由はありますか?
Vignesh 2012年

43
まともな品質の通常のRNGの場合、値は重要ではありません。「42」は有名な本への言及です。他の人は自分の誕生日または「123」または単に「1」を使用します。
Dirk Eddelbuettel、

7
char2seedTeachingDemosパッケージの関数を使用するとset.seed、文字列に基づいてシードを設定(またはに渡すシードを選択)できます。たとえば、生徒に自分の名前をシードとして使用させると、生徒ごとに一意のデータセットが作成されますが、講師はグレーディング用に同じデータセットを作成することもできます。
Greg Snow

8
「最良の」結果が得られるまで、同じコードを異なるシードで再実行することができます(例ではこれを行いました)。これを行うことの非難を防ぐために、常に同じシード、または日付、または私が使用するchar2seed、およびプロジェクトの主任研究者の姓のいずれかである、明白な意味を持つシードを選択するのが最善です。
Greg Snow

5
@DirkEddelbuettelシード値計算以外の理由で問題となる可能性があります。私の友人は、コードが最初にset.seed(666)あり、レビューアがコード内のDevilsシードを好まなかったため、シミュレーションベースの結果の公開に問題がありました...
Tim

33

再現性のあるランダムな結果を取得するたびに、シードを設定する必要があります。

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)

17

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

?set.seed

この関数のヘルプファイルを確認すると、いくつかの興味深い事実があります。

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

(2)「初期状態ではシードはありません。現在の時刻とプロセスIDが必要になると、新しいシードが作成されます。したがって、デフォルトでは、セッションが異なるとシミュレーション結果も異なります。ただし、シードは以前に保存されたワークスペースが復元された場合、前のセッション。


7

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

何らかの理由で、サンプルを指定して、シミュレーションにより平均ゼロ正規分布の標準偏差(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に非常に頻繁に近づきます。


6

基本的にset.seed()関数は、同じランダム変数の同じセットを再利用するのに役立ちます。将来、同じランダム変数を使用して特定のタスクを再度評価するために必要になる可能性があります。

乱数生成関数を使用する前に宣言する必要があります。


答えを詳しく説明する
Spry Techies 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.