Powody korzystania z funkcji set.seed

185

Wiele razy widziałem tę set.seedfunkcję w języku R przed uruchomieniem programu. Wiem, że jest zasadniczo używany do generowania liczb losowych. Czy jest jakaś konkretna potrzeba, aby to ustawić?

Vignesh
źródło
2
Odpowiemy na
duffymo

Odpowiedzi:

264

Potrzebna jest możliwa chęć uzyskania powtarzalnych wyników, które mogą na przykład wynikać z próby debugowania programu lub oczywiście z ponownej próby wykonania tego, co robi:

Te dwa wyniki „nigdy” nie odtworzymy, ponieważ właśnie poprosiłem o coś „losowego”:

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

Te dwa są jednak identyczne, ponieważ ustawiłem ziarno :

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> 

Na ten temat jest ogromna literatura; Wikipedia to dobry początek. W gruncie rzeczy te RNG są nazywane generatorami liczb pseudolosowych, ponieważ w rzeczywistości są w pełni algorytmiczne : biorąc pod uwagę to samo ziarno, otrzymujesz tę samą sekwencję. I to jest funkcja, a nie błąd.

Dirk Eddelbuettel
źródło
5
Dzięki Dirk, za taki miły przykład. Wyczyściłem go z 99%, ale wciąż pytam. 1. W swojej odpowiedzi użyłeś set.seed z argumentem 42 jako argument .. czy istnieje jakiś powód, aby wybrać tę wartość?
Vignesh,
43
Dla normalnego RNG o przyzwoitej jakości wartość nie ma znaczenia. „42” odnosi się do znanej książki; inni używają swoich urodzin lub „123” lub po prostu „1”.
Dirk Eddelbuettel
7
char2seedFunkcja w pakiecie TeachingDemos pozwala ustawić ziarno (lub wybierz ziarno przechodzi w set.seed) na podstawie ciągu znaków. Na przykład możesz mieć uczniów, którzy używają ich nazw jako nasion, wtedy każdy uczeń ma unikalny zestaw danych, ale instruktor może również utworzyć te same zestawy danych do oceny.
Greg Snow,
8
Możliwe jest ponowne uruchomienie tego samego kodu z różnymi nasionami, aż do uzyskania „najlepszego” wyniku (zrobiłem to dla przykładów). Aby uchronić się przed oskarżeniami o zrobienie tego, najlepiej wybrać ziarno, które ma jakieś oczywiste znaczenie, albo zawsze to samo ziarno, albo datę, albo używam char2seedi nazwisko głównego badacza projektu.
Greg Snow,
5
@ Wartość początkowa @DirkEddelbuettel może mieć znaczenie z przyczyn innych niż obliczeniowe, mój przyjaciel miał problemy z opublikowaniem wyników opartych na symulacji, ponieważ kod zaczął się od, set.seed(666)a recenzentom nie podobało się ziarno diabła w kodzie ...
Tim
33

Musisz ustawić ziarno za każdym razem, gdy chcesz uzyskać powtarzalny losowy wynik.

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
Zawieszony na szyję
źródło
17

Właśnie dodając kilka dodatkowych aspektów. Potrzeba ustawienia nasion: W świecie akademickim, jeśli ktoś twierdzi, że jego algorytm osiąga, powiedzmy 98,05% wydajności w jednej symulacji, inni muszą być w stanie go odtworzyć.

?set.seed

Przeglądając plik pomocy tej funkcji, oto kilka interesujących faktów:

(1) set.seed () zwraca NULL, niewidoczny

(2) „Początkowo nie ma nasion; nowy jest tworzony na podstawie bieżącej godziny i identyfikatora procesu, gdy jest wymagany. Stąd różne sesje będą domyślnie dawały różne wyniki symulacji. Jednak ziarno może zostać przywrócone z poprzednia sesja, jeśli poprzednio zapisany obszar roboczy zostanie przywrócony. ”, dlatego chciałbyś wywołać set.seed () z tymi samymi wartościami całkowitymi, kiedy następnym razem będziesz chciał mieć taką samą sekwencję losowej sekwencji.

Ridingstar
źródło
7

Naprawienie zarodka jest niezbędne, gdy próbujemy zoptymalizować funkcję, która obejmuje losowo generowane liczby (np. W estymacji opartej na symulacji). Mówiąc luźniej, jeśli nie naprawimy zarodka, zmiana spowodowana rysowaniem różnych liczb losowych prawdopodobnie spowoduje awarię algorytmu optymalizacji.

Załóżmy, że z jakiegoś powodu chcesz oszacować odchylenie standardowe (sd) rozkładu normalnego średniego zera metodą symulacji, biorąc pod uwagę próbkę. Można to osiągnąć, przeprowadzając optymalizację numeryczną wokół kroków

  1. (Ustawianie nasion)
  2. Podając wartość sd, generuj normalnie rozproszone dane
  3. Oceń prawdopodobieństwo swoich danych, biorąc pod uwagę symulowane rozkłady

Następujące funkcje to robią, raz bez kroku 1., raz włączając to:

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

Możemy sprawdzić względną wydajność dwóch funkcji w odkryciu prawdziwej wartości parametru za pomocą krótkiego badania Monte Carlo:

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)

Wynikowe rozkłady oszacowań parametrów są następujące:

Histogram szacunków parametrów bez ustalania nasion Histogram szacunków parametrów ustalających ziarno

Kiedy naprawimy ziarno, wyszukiwanie numeryczne kończy się znacznie bliżej prawdziwej wartości parametru 2.

Matthias Schmidtblaicher
źródło
6

w zasadzie funkcja set.seed () pomoże ponownie wykorzystać ten sam zestaw zmiennych losowych, które mogą być potrzebne w przyszłości, aby ponownie ocenić dane zadanie ponownie z tymi samymi losowymi zmiennymi

musimy tylko to zadeklarować przed użyciem jakiejkolwiek funkcji generowania liczb losowych.

użytkownik4388407
źródło
opracuj odpowiedź
Spry Techies