Причины использования функции set.seed

185

Много раз я видел set.seedфункцию в R, прежде чем запустить программу. Я знаю, что это в основном используется для генерации случайных чисел. Есть ли какая-то конкретная необходимость установить это?

Вигнеш
источник
2
Это ответит на это: stattrek.com/statistics/random-number-generator.aspx
duffymo

Ответы:

264

Необходимость заключается в возможном желании получить воспроизводимые результаты, которые могут, например, возникнуть при попытке отладки вашей программы или, конечно, при попытке повторить то, что она делает:

Эти два результата мы «никогда» не воспроизведем, поскольку я просто попросил что-то «случайное»:

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

Эти два, однако, идентичны, потому что я установил семя :

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
Спасибо Дирк, за такой хороший пример .. Я очистил его с 99%, но все еще вопрос. 1. В своем ответе вы использовали set.seed с 42 в качестве аргумента. Есть ли какая-то связанная причина для выбора этого значения?
Vignesh
43
Для нормального RNG приличного качества значение не имеет значения. «42» - это ссылка на известную книгу; другие люди используют свой день рождения или «123» или просто «1».
Дирк Эддельбюттель
7
char2seedФункция в пакете TeachingDemos позволяет установить начальное число (или выбрать семена переходят в set.seed) на основе строки символов. Например, вы можете попросить учеников использовать свое имя в качестве начального числа, тогда у каждого ученика есть уникальный набор данных, но преподаватель также может создать те же наборы данных для оценки.
Грег Сноу,
8
Можно перезапустить один и тот же код с разными начальными значениями, пока вы не получите «лучший» результат (я сделал это для примеров). Чтобы избежать обвинений в этом, лучше выбрать семя, которое имеет какое-то очевидное значение, либо всегда одно и то же семя, либо дату, либо я использую char2seedфамилию главного исследователя проекта.
Грег Сноу,
5
Значение @DirkEddelbuettel может иметь значение по некомпьютерным причинам, у моего друга были проблемы с публикацией результатов, основанных на моделировании, потому что код начинался с того, set.seed(666)что рецензентам не нравилось семя Дьяволов в коде ...
Тим
33

Вы должны устанавливать seed каждый раз, когда хотите получить воспроизводимый случайный результат.

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
Chia-хун
источник
17

Просто добавив некоторые дополнительные аспекты. Необходимость установки начального числа: если в академическом мире утверждают, что его алгоритм достигает, скажем, 98,05% производительности в одной имитации, другие должны иметь возможность воспроизводить его.

?set.seed

Просматривая файл справки этой функции, вот некоторые интересные факты:

(1) set.seed () возвращает NULL, невидимый

(2) «Первоначально, нет начального числа; новое создается из текущего времени и идентификатора процесса, когда оно требуется. Следовательно, разные сеансы будут давать разные результаты моделирования по умолчанию. Однако начальное число может быть восстановлено из предыдущий сеанс, если восстановлено ранее сохраненное рабочее пространство. ", поэтому вы захотите вызвать set.seed () с такими же целочисленными значениями в следующий раз, когда вы захотите такую ​​же последовательность случайной последовательности.

Ridingstar
источник
7

Фиксация начального числа важна, когда мы пытаемся оптимизировать функцию, которая включает случайно сгенерированные числа (например, при оценке на основе моделирования). Грубо говоря, если мы не исправим начальное число, изменение из-за рисования различных случайных чисел, скорее всего, приведет к сбою алгоритма оптимизации.

Предположим, что по какой-то причине вы хотите оценить стандартное отклонение (sd) среднего-нулевого нормального распределения путем моделирования с учетом выборки. Это может быть достигнуто путем выполнения числовой оптимизации по шагам

  1. (Урегулирование семян)
  2. Учитывая значение для SD, генерировать нормально распределенные данные
  3. Оцените вероятность ваших данных с помощью смоделированных распределений

Следующие функции делают это, один раз без шага 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)))
}

Мы можем проверить относительную производительность двух функций при обнаружении истинного значения параметра с помощью короткого исследования Монте-Карло:

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 () поможет повторно использовать тот же набор случайных переменных, который нам может понадобиться в будущем для повторной оценки конкретной задачи с теми же случайными переменными

нам просто нужно объявить это перед использованием любой функции генерации случайных чисел.

user4388407
источник
подробный ответ
Spry Techies