Gründe für die Verwendung der Funktion set.seed

184

Oft habe ich die set.seedFunktion in R gesehen, bevor ich das Programm gestartet habe. Ich weiß, dass es grundsätzlich für die Zufallszahlengenerierung verwendet wird. Gibt es eine spezielle Notwendigkeit, dies einzustellen?

Vignesh
quelle
2
Dies wird es beantworten: stattrek.com/statistics/random-number-generator.aspx
duffymo

Antworten:

264

Die Notwendigkeit ist der mögliche Wunsch nach reproduzierbaren Ergebnissen, der beispielsweise aus dem Versuch resultieren kann, Ihr Programm zu debuggen, oder natürlich aus dem Versuch, das zu wiederholen, was es tut:

Diese beiden Ergebnisse werden wir "nie" reproduzieren, da ich nur um etwas "Zufälliges" gebeten habe:

R> sample(LETTERS, 5)
[1] "K" "N" "R" "Z" "G"
R> sample(LETTERS, 5)
[1] "L" "P" "J" "E" "D"

Diese beiden sind jedoch identisch, weil ich den Samen gesetzt habe :

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> 

Es gibt eine große Literatur zu all dem; Wikipedia ist ein guter Anfang. Im Wesentlichen werden diese RNGs als Pseudo-Zufallszahlengeneratoren bezeichnet, da sie tatsächlich vollständig algorithmisch sind : Bei gleichem Startwert erhalten Sie dieselbe Sequenz. Und das ist eine Funktion und kein Fehler.

Dirk Eddelbuettel
quelle
5
Danke Dirk, für dieses schöne Beispiel. Ich habe es mit 99% geklärt, aber immer noch eine Frage. 1. In Ihrer Antwort haben Sie set.seed mit 42 als Argument verwendet. Gibt es einen verwandten Grund für die Auswahl dieses Werts?
Vignesh
43
Für ein normales RNG von anständiger Qualität spielt der Wert keine Rolle. "42" bezieht sich auf ein berühmtes Buch; andere Leute benutzen ihren Geburtstag oder "123" oder nur "1".
Dirk Eddelbuettel
7
Mit der char2seedFunktion im TeachingDemos-Paket können Sie den Startwert (oder einen Startwert, an den übergeben werden soll set.seed) basierend auf einer Zeichenfolge festlegen. Sie können beispielsweise festlegen, dass Schüler ihren Namen als Startwert verwenden, dann hat jeder Schüler einen eindeutigen Datensatz, aber der Kursleiter kann auch dieselben Datensätze für die Bewertung erstellen.
Greg Snow
8
Es ist möglich, denselben Code mit verschiedenen Seeds erneut auszuführen, bis Sie das "beste" Ergebnis erhalten (ich habe dies zum Beispiel getan). Um sich vor Anschuldigungen zu schützen, ist es am besten, einen Samen zu wählen, der eine offensichtliche Bedeutung hat, entweder immer den gleichen Samen oder das Datum, oder ich verwende char2seedund den Nachnamen des Hauptermittlers für ein Projekt.
Greg Snow
5
@DirkEddelbuettel-Startwert kann aus nicht rechnerischen Gründen von Bedeutung sein. Ein Freund von mir hatte Probleme beim Veröffentlichen seiner simulationsbasierten Ergebnisse, da der Code mit begann set.seed(666)und die Prüfer den Devils-Startwert im Code nicht mochten ...
Tim
33

Sie müssen jedes Mal einen Startwert festlegen, wenn Sie ein reproduzierbares zufälliges Ergebnis erhalten möchten.

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
Chia-hung
quelle
17

Fügen Sie einfach einige zusätzliche Aspekte hinzu. Notwendigkeit, Samen zu setzen: Wenn man in der akademischen Welt behauptet, dass sein Algorithmus beispielsweise eine Leistung von 98,05% in einer Simulation erreicht, müssen andere in der Lage sein, diese zu reproduzieren.

?set.seed

In der Hilfedatei dieser Funktion sind einige interessante Fakten aufgeführt:

(1) set.seed () gibt NULL zurück, unsichtbar

(2) "Anfangs gibt es keinen Startwert. Aus der aktuellen Zeit und der Prozess-ID wird ein neuer erstellt, wenn einer erforderlich ist. Daher führen unterschiedliche Sitzungen standardmäßig zu unterschiedlichen Simulationsergebnissen. Der Startwert kann jedoch aus a wiederhergestellt werden vorherige Sitzung, wenn ein zuvor gespeicherter Arbeitsbereich wiederhergestellt wird. "Aus diesem Grund möchten Sie set.seed () mit denselben ganzzahligen Werten aufrufen, wenn Sie das nächste Mal dieselbe Folge von Zufallsfolgen wünschen.

Reitstern
quelle
7

Das Fixieren des Startwerts ist wichtig, wenn wir versuchen, eine Funktion zu optimieren, die zufällig generierte Zahlen enthält (z. B. bei simulationsbasierten Schätzungen). Wenn wir den Startwert nicht festlegen, führt die Variation aufgrund des Zeichnens unterschiedlicher Zufallszahlen wahrscheinlich dazu, dass der Optimierungsalgorithmus fehlschlägt.

Angenommen, Sie möchten aus irgendeinem Grund die Standardabweichung (sd) einer Mittelwert-Null-Normalverteilung durch Simulation anhand einer Stichprobe schätzen. Dies kann erreicht werden, indem eine numerische Optimierung um Schritte ausgeführt wird

  1. (Samen setzen)
  2. Generieren Sie bei einem gegebenen Wert für sd normalverteilte Daten
  3. Bewerten Sie die Wahrscheinlichkeit Ihrer Daten angesichts der simulierten Verteilungen

Die folgenden Funktionen tun dies einmal ohne Schritt 1. einmal mit:

# 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)))
}

Wir können die relative Leistung der beiden Funktionen bei der Ermittlung des wahren Parameterwerts anhand einer kurzen Monte-Carlo-Studie überprüfen:

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)

Die resultierenden Verteilungen der Parameterschätzungen sind:

Histogramm der Parameterschätzungen ohne Fixierung des Seeds Histogramm der Parameterschätzungen zur Fixierung des Seeds

Wenn wir den Startwert festlegen, endet die numerische Suche weitaus häufiger nahe am wahren Parameterwert von 2.

Matthias Schmidtblaicher
quelle
6

Grundsätzlich hilft die Funktion set.seed () dabei, denselben Satz von Zufallsvariablen wiederzuverwenden, den wir möglicherweise in Zukunft benötigen, um eine bestimmte Aufgabe erneut mit denselben zufälligen Varibalen auszuwerten

Wir müssen es nur deklarieren, bevor wir eine Funktion zur Erzeugung von Zufallszahlen verwenden.

user4388407
quelle
Erarbeiten Sie die Antwort
Spry Techies