R Academy · Урок

set.seed() и воспроизводимость

Обеспечьте воспроизводимую генерацию случайных чисел при каждом запуске с помощью set.seed()

Урок 1 из 413 шагов

«set.seed() и воспроизводимость» — бесплатный урок R Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Почему важна воспроизводимость

Генерация случайных чисел является псевдослучайной: это детерминированный алгоритм, инициализируемый начальным значением. Установка seed делает моделирование воспроизводимым — один и тот же код всегда даёт одинаковые результаты, что важно для отладки, публикации и обучения.

# Without set.seed: different every run
runif(3)  # e.g., 0.21, 0.57, 0.89 (changes each run)
runif(3)  # different again!

# With set.seed: always identical
set.seed(42)
runif(3)  # always: 0.9148060 0.9370754 0.2861395

set.seed(42)  # reset seed
runif(3)  # exactly the same three numbers again

cat('set.seed() is your reproducibility guarantee')

Механика set.seed()

set.seed(n) инициализирует состояние генератора случайных чисел (RNG). Подходит любое положительное целое число. seed определяет всю последующую последовательность случайных чисел, пока seed не будет установлен заново. Для воспроизводимости используйте фиксированное число.

# Different seeds give different sequences
set.seed(1)
seq1 <- rnorm(5)

set.seed(99)
seq2 <- rnorm(5)

print(seq1)
print(seq2)
identical(seq1, seq2)  # FALSE

# Same seed always gives same sequence
set.seed(1)
seq1_again <- rnorm(5)
identical(seq1, seq1_again)  # TRUE

# Common seed choices
set.seed(123)   # popular convention
set.seed(2024)  # use year for temporal clarity

RNGkind(): алгоритм RNG

RNGkind() показывает или устанавливает алгоритм RNG. По умолчанию R использует вихрь Мерсенна с методом нормального распределения инверсии. Алгоритм влияет на последовательность, поэтому для полной воспроизводимости документируйте и seed, и RNGkind.

# Check current RNG settings
RNGkind()
# [1] 'Mersenne-Twister' 'Inversion' 'Rejection'
# [1] kind, normal.kind, sample.kind

# Set explicitly for maximum reproducibility
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
set.seed(42)
runif(3)

# Alternative RNG algorithms (rarely needed)
# RNGkind('L'Ecuyer-CMRG') # for parallel RNG
# RNGkind('Super-Duper')   # older algorithm

cat('Default Mersenne-Twister has period 2^19937 - 1')

Изучение .Random.seed

.Random.seed — это глобальный целочисленный вектор, хранящий полное состояние RNG. Он автоматически обновляется после каждой генерации случайного числа. Его можно сохранить и восстановить, чтобы воспроизвести последовательность с любой точки.

set.seed(42)
# .Random.seed is created in .GlobalEnv after first use
length(.Random.seed)  # 626 integers for Mersenne-Twister
.Random.seed[1]       # encodes RNG type

# Generate one number (state advances)
x1 <- runif(1)
state_after <- .Random.seed

# Generate another
x2 <- runif(1)

# Restore state to after x1
.Random.seed <<- state_after
x2_replay <- runif(1)

identical(x2, x2_replay)  # TRUE - we replayed the state
cat('x2:', x2, 'x2_replay:', x2_replay)

Сохранение и восстановление состояния RNG

Сохраните состояние RNG перед блоком кода, а затем восстановите его позже, чтобы точно воспроизвести выполнение этого блока. Это гибче, чем set.seed(), когда нужно продолжить последовательность с середины.

set.seed(100)
# Generate some random numbers first
runif(10)

# Save current state
saved_state <- .Random.seed

# Generate block of interest
block1 <- rnorm(5)
print(block1)

# ... later, restore and replay
.Random.seed <<- saved_state
block1_replay <- rnorm(5)

identical(block1, block1_replay)  # TRUE!
cat('RNG state saved and restored successfully')

Параллельный RNG с L'Ecuyer-CMRG

При использовании параллельных вычислений каждому процессу нужен независимый поток RNG. Генератор L'Ecuyer-CMRG предоставляет длинные непересекающиеся потоки для параллельных рабочих процессов, обеспечивая независимость результатов на разных ядрах.

# Set up L'Ecuyer-CMRG for parallel use
RNGkind('L\'Ecuyer-CMRG')
set.seed(42)

# Each parallel worker gets its own stream
# (parallel package handles this automatically)
# library(parallel)
# cl <- makeCluster(4)
# clusterSetRNGStream(cl, iseed = 42)

# Generate numbers with this generator
samples <- rnorm(5)
print(samples)

# Reset to default Mersenne-Twister
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
cat('L\'Ecuyer-CMRG: safe for parallel simulation')

Начальное значение в вызовах функций

Установка начального значения внутри функции не влияет на состояние RNG вызывающего кода после возврата из функции, поскольку вызов установки начального значения изменяет глобальное значение .Random.seed. В повторно используемых функциях явно управляйте начальными значениями.

# Function that optionally accepts a seed
simulate_data <- function(n, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)
  list(
    x = rnorm(n),
    y = rnorm(n)
  )
}

# Reproducible call
result1 <- simulate_data(5, seed = 42)
result2 <- simulate_data(5, seed = 42)
identical(result1$x, result2$x)  # TRUE

# Without seed: different each time
result3 <- simulate_data(5)
result4 <- simulate_data(5)
identical(result3$x, result4$x)  # FALSE

Воспроизводимая выборка

Аргумент sample.kind функции RNGkind() влияет именно на sample(). Начиная с R 3.6.0 значением по умолчанию стал 'Rejection' для повышения равномерности — используйте его в воспроизводимых рабочих процессах.

# R 3.6+ default sample kind
RNGkind(sample.kind = 'Rejection')  # default
set.seed(42)
sample(1:10, 5)
# [1] 1 5 10 8 2  (with Rejection)

# Old behavior (R < 3.6) for legacy code
RNGkind(sample.kind = 'Rounding')
set.seed(42)
sample(1:10, 5)
# Different result!

# Best practice: reset to modern defaults
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
set.seed(42)
sample(1:10, 5)

Документирование случайности

Хорошая практика для воспроизводимых исследований: документируйте версию R, значение начального числа и RNGkind. Используйте sessionInfo() для полной фиксации среды. Записывайте начальные значения в комментариях скрипта или в файле конфигурации.

# Reproducibility header for analysis scripts:
# R version: R.version$version.string
# Seed: 42
# RNGkind: Mersenne-Twister / Inversion / Rejection

# Capture R version
R.version$version.string

# Capture full session info
# sessionInfo()  # shows all packages and versions

# In RMarkdown, set seed in setup chunk:
# ```{r setup}
# knitr::opts_chunk$set(echo = TRUE)
# set.seed(42)
# ```

# This ensures all chunks share the same RNG state
set.seed(42)
cat('R version:', R.version$version.string, '\n')
cat('Seed: 42, RNGkind: Mersenne-Twister')

Начальные значения в исследованиях методом Монте-Карло

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

# Generate per-replicate seeds from a master seed
set.seed(2024)
n_replicates <- 5
replicate_seeds <- sample.int(1e6, n_replicates)
print(replicate_seeds)

# Each replicate uses its own seed
run_replicate <- function(rep_id) {
  set.seed(replicate_seeds[rep_id])
  mean(rnorm(1000))  # estimate with this seed
}

results <- sapply(seq_len(n_replicates), run_replicate)
print(round(results, 4))

# Any single replicate can be re-run independently:
set.seed(replicate_seeds[3])
mean(rnorm(1000))  # exactly matches results[3]

Тестирование случайности с помощью withr

Пакет withr предоставляет with_seed(seed, expr): он временно устанавливает начальное значение, вычисляет выражение, а затем восстанавливает исходное состояние RNG — идеально для тестов без изменения глобального состояния.

# withr::with_seed - restore RNG state automatically
# library(withr)
# result <- with_seed(42, rnorm(5))

# Simulation without withr (manual state save)
old_seed <- if (exists('.Random.seed')) .Random.seed
old_kind <- RNGkind()

set.seed(42)
result <- rnorm(5)

# Restore
if (!is.null(old_seed)) .Random.seed <<- old_seed
cat('Result:', result, '\n')
cat('Caller\'s RNG state preserved')

# set.seed in tests ensures deterministic assertions:
set.seed(1)
stopifnot(round(rnorm(1), 6) == round(-0.6264538, 6))

Быстрая проверка

Проверьте своё понимание воспроизводимости RNG в R.

Итоги: начальные значения и воспроизводимость

Главные выводы: set.seed(n) делает код со случайностью воспроизводимым. RNGkind() показывает или устанавливает алгоритм — документируйте и начальное значение, и алгоритм. В .Random.seed хранится полное состояние RNG; его можно сохранить и восстановить. Для параллельных вычислений используйте L'Ecuyer-CMRG. В функциях принимайте параметр seed. В крупных имитациях используйте начальные значения отдельных повторений, сгенерированные из основного начального значения.

# Reproducibility checklist:
# 1. Set seed at script top
set.seed(42)

# 2. Document RNGkind
RNGkind()  # Mersenne-Twister / Inversion / Rejection

# 3. Save RNG state if needed
saved <- .Random.seed

# 4. For functions, accept seed argument
my_sim <- function(n, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)
  rnorm(n)
}

# 5. For parallel: use L'Ecuyer-CMRG
# RNGkind('L\'Ecuyer-CMRG'); set.seed(42)

cat('Reproducibility = trust in your results')
Можно начать бесплатно

Изучай R с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
43
Уроки
159

Часто задаваемые вопросы

Урок «set.seed() и воспроизводимость» бесплатный?

Да — полный текст урока «set.seed() и воспроизводимость» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «set.seed() и воспроизводимость»?

Обеспечьте воспроизводимую генерацию случайных чисел при каждом запуске с помощью set.seed() Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «set.seed() и воспроизводимость»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. set.seed() и воспроизводимость
  2. Генерация случайных распределений
  3. Основы метода Монте-Карло
  4. Бутстреп-ресэмплинг в R
← Назад к R Academy