set.seed()와 재현성
set.seed()를 사용해 실행할 때마다 난수 생성을 재현할 수 있도록 합니다.
set.seed()와 재현성은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
재현성이 중요한 이유
난수 생성은 의사난수 방식입니다. 시작값으로 초기화된 결정적 알고리즘을 사용합니다. 시드를 설정하면 시뮬레이션을 재현할 수 있습니다. 즉, 같은 코드는 항상 같은 결과를 내므로 디버깅, 출판 및 교육에 필수적입니다.
# 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)의 상태를 초기화합니다. 양의 정수라면 무엇이든 사용할 수 있습니다. 시드는 재설정할 때까지 이어지는 난수 전체의 순서를 결정합니다. 재현성을 위해 고정된 값을 사용하세요.
# 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 clarityRNGkind(): RNG 알고리즘
RNGkind()은 RNG 알고리즘을 표시하거나 설정합니다. R의 기본값은 정규분포 방법 Inversion을 사용하는 Mersenne-Twister입니다. 알고리즘은 난수 순서에 영향을 주므로, 완전한 재현성을 위해 시드와 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')L'Ecuyer-CMRG를 사용한 병렬 RNG
병렬 컴퓨팅을 사용할 때는 각 프로세스에 독립적인 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재현 가능한 표본 추출
RNGkind()의 sample.kind 인수는 특히 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 패키지는 시드를 일시적으로 설정하고, 표현식을 평가한 다음 원래 RNG 상태를 복원하는 with_seed(seed, expr)를 제공합니다. 전역 상태를 오염시키지 않고 테스트할 때 매우 유용합니다.
# 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))빠른 확인
R에서 RNG 재현성에 대한 이해도를 확인해 보십시오.
복습: 시드와 재현성
핵심 내용: 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')자주 묻는 질문
“set.seed()와 재현성” 강의는 무료인가요?
네 — “set.seed()와 재현성” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“set.seed()와 재현성”에서 뭘 배우나요?
set.seed()를 사용해 실행할 때마다 난수 생성을 재현할 수 있도록 합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
R Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“set.seed()와 재현성” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- set.seed()와 재현성
- 확률분포에서 난수 생성
- 몬테카를로 시뮬레이션 기초
- R에서 부트스트랩 재표본추출