R Academy · บทเรียน

set.seed() และการทำซ้ำผลลัพธ์ได้

ทำให้การสร้างเลขสุ่มให้ผลลัพธ์เหมือนเดิมในแต่ละรอบการทำงานด้วย set.seed()

บทเรียน 1 จาก 413 ขั้นตอน

set.seed() และการทำซ้ำผลลัพธ์ได้ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดการทำซ้ำผลลัพธ์จึงสำคัญ

การสร้างเลขสุ่มเป็นแบบสุ่มเทียม: ใช้ขั้นตอนวิธีที่กำหนดแน่นอนและเริ่มต้นด้วยค่า seed การกำหนด 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 คือ Mersenne-Twister และใช้วิธีแจกแจงปกติแบบ Inversion ขั้นตอนวิธีมีผลต่อลำดับเลขสุ่ม ดังนั้นควรบันทึกทั้ง 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 ค่าของ seed และ RNGkind ใช้ sessionInfo() เพื่อบันทึกสภาพแวดล้อมทั้งหมด และบันทึกค่า seed ไว้ในความคิดเห็นของสคริปต์หรือไฟล์การกำหนดค่า

# 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) ซึ่งกำหนดค่า seed ชั่วคราว ประเมินนิพจน์ แล้วคืนค่าสถานะ 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() แสดงหรือตั้งค่าอัลกอริทึม จึงควรบันทึกทั้ง seed และชนิดของอัลกอริทึม .Random.seed เก็บสถานะ RNG ทั้งหมดและสามารถบันทึกหรือกู้คืนได้ สำหรับการประมวลผลแบบขนาน ให้ใช้ L'Ecuyer-CMRG ในฟังก์ชัน ให้รับพารามิเตอร์ seed และในการจำลองขนาดใหญ่ ให้ใช้ค่า seed สำหรับแต่ละการทำซ้ำที่สร้างจาก 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 ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
43
บทเรียน
159

คำถามที่พบบ่อย

บทเรียน “set.seed() และการทำซ้ำผลลัพธ์ได้” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “set.seed() และการทำซ้ำผลลัพธ์ได้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “set.seed() และการทำซ้ำผลลัพธ์ได้”

ทำให้การสร้างเลขสุ่มให้ผลลัพธ์เหมือนเดิมในแต่ละรอบการทำงานด้วย set.seed() คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 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