0Pricing
R Academy · レッスン

set.seed() と再現性

set.seed() を使い、実行するたびに乱数生成の結果を再現できるようにします。

「set.seed() と再現性」はCoddyKit上の無料R Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応の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 clarity

RNGkind():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')

Monte Carlo研究でのシード

大規模なシミュレーション研究では、単一のマスターシードから反復ごとのシードを生成してください。これにより、各反復を個別に再現可能にしながら、全体の設計を決定論的に保てます。

# 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時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。

「set.seed() と再現性」で何を学びますか?

set.seed() を使い、実行するたびに乱数生成の結果を再現できるようにします。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

R Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「set.seed() と再現性」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このR Academyレッスンでコードを書いて実行できますか?

はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. set.seed() と再現性
  2. 確率分布からの乱数生成
  3. モンテカルロシミュレーションの基礎
  4. R でのブートストラップ再標本化
← R Academyに戻る