0Pricing
R Academy · บทเรียน

การสุ่มตัวอย่าง MCMC และการวินิจฉัย

เรียกใช้การสุ่มตัวอย่าง ตรวจสอบสายโซ่ และตีความการวินิจฉัย Rhat กับ ESS

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

MCMC คืออะไร

มอนติคาร์โลแบบสายโซ่มาร์คอฟ (MCMC) คือกลุ่มขั้นตอนวิธีสำหรับสุ่มตัวอย่างจากการแจกแจงความน่าจะเป็นเมื่อไม่สามารถสุ่มโดยตรงได้ ในสถิติแบบเบย์ MCMC จะสุ่มตัวอย่างจาก การแจกแจงภายหลัง P(parameters | data)

RStan ใช้ตัวสุ่มตัวอย่างแบบไม่วกกลับ (NUTS) ซึ่งเป็นขั้นตอนวิธี MCMC ที่ทันสมัย

แบบจำลอง Stan อย่างง่าย

แบบจำลอง Stan คือบล็อกข้อความที่กำหนดชนิดข้อมูล พารามิเตอร์ และค่าลอการิทึมของการแจกแจงภายหลัง แบบจำลองที่ง่ายที่สุดจะประมาณค่าเฉลี่ยของการแจกแจงปกติที่ทราบความแปรปรวน

# library(rstan)
#
# stan_code <- '
# data {
#   int<lower=0> N;
#   vector[N] y;
# }
# parameters {
#   real mu;
#   real<lower=0> sigma;
# }
# model {
#   mu    ~ normal(0, 10);   // prior
#   sigma ~ exponential(1);   // prior
#   y     ~ normal(mu, sigma); // likelihood
# }
# '

การเรียกใช้ stan() เพื่อสุ่มตัวอย่าง

stan(model_code=..., data=..., chains=4, iter=2000, warmup=1000) จะคอมไพล์แบบจำลองหนึ่งครั้ง แล้วจึงสุ่มตัวอย่าง เมื่อใช้ iter=2000 และ warmup=1000 แต่ละสายโซ่จะให้ตัวอย่างหลังช่วงวอร์มอัป 1000 ตัวอย่าง รวมเป็น 4000 ตัวอย่างจาก 4 สายโซ่

# library(rstan)
# options(mc.cores = parallel::detectCores())
#
# y <- c(2.1, 1.8, 2.4, 1.9, 2.3, 2.0, 1.7, 2.2)
# stan_data <- list(N = length(y), y = y)
#
# fit <- stan(
#   model_code = stan_code,
#   data       = stan_data,
#   chains     = 4,
#   iter       = 2000,
#   warmup     = 1000,
#   seed       = 42
# )

print(fit) — ตารางสรุป

print(fit) จะแสดงตารางสรุปสำหรับพารามิเตอร์แต่ละตัว ซึ่งประกอบด้วยค่าเฉลี่ยภายหลัง ส่วนเบี่ยงเบนมาตรฐาน ควอนไทล์ Rhat และ n_eff ตัวชี้วัดสองรายการหลังนี้คือสิ่งแรกที่ควรตรวจสอบ

# print(fit)
#
# Example output:
#       mean se_mean   sd  2.5%   25%   50%   75%  97.5%  n_eff Rhat
# mu    2.05    0.00 0.15  1.76  1.95  2.05  2.15   2.34   3842    1
# sigma 0.22    0.00 0.06  0.13  0.18  0.21  0.25   0.37   3521    1
# lp__  4.38    0.02 1.01  1.60  3.91  4.71  5.18   5.50   2148    1

เกณฑ์การลู่เข้าของ Rhat

Rhat (ตัวประกอบการลดสเกลที่เป็นไปได้) เปรียบเทียบความแปรปรวนภายในสายโซ่กับความแปรปรวนระหว่างสายโซ่ ค่าที่ใกล้ 1.0 แสดงว่าสายโซ่ทั้งหมดลู่เข้าสู่การแจกแจงเดียวกันแล้ว

  • Rhat < 1.01 — ลู่เข้าแล้ว (มาตรฐานปัจจุบัน)
  • Rhat > 1.01 — สายโซ่ยังผสมกันไม่ดี ควรทำซ้ำเพิ่ม
  • Rhat > 1.1 — มีปัญหาการลู่เข้าที่รุนแรง
# Check Rhat for all parameters:
# s <- summary(fit)$summary
# rhat_vals <- s[, 'Rhat']
# cat('Max Rhat:', max(rhat_vals, na.rm = TRUE), '
')
# if (any(rhat_vals > 1.01, na.rm = TRUE)) {
#   warning('Convergence issue detected!')
# } else {
#   cat('All Rhat < 1.01 — chains converged
')
# }

n_eff — ขนาดตัวอย่างที่มีประสิทธิผล

n_eff (ขนาดตัวอย่างที่มีประสิทธิผล) คำนึงถึงสหสัมพันธ์ในตัวระหว่างตัวอย่าง MCMC ที่ต่อเนื่องกัน ตัวอย่างที่มีสหสัมพันธ์ให้ข้อมูลน้อยกว่าตัวอย่างที่เป็นอิสระต่อกัน

  • n_eff ใกล้จำนวนรอบทั้งหมด — ตัวอย่างเกือบเป็นอิสระต่อกัน ถือว่ายอดเยี่ยม
  • n_eff / total_samples > 0.1 — โดยทั่วไปยอมรับได้
  • n_eff ต่ำมาก — มีสหสัมพันธ์ในตัวสูง ควรพิจารณาปรับการกำหนดพารามิเตอร์ของแบบจำลองใหม่
# s <- summary(fit)$summary
# n_eff_vals <- s[, 'n_eff']
# total_samples <- 4 * 1000   # chains * post-warmup iter
# ratio <- n_eff_vals / total_samples
# cat('n_eff ratio (mu)   :', round(ratio['mu'], 2), '
')
# cat('n_eff ratio (sigma):', round(ratio['sigma'], 2), '
')

traceplot() สำหรับตรวจสอบการลู่เข้าด้วยภาพ

traceplot(fit, pars = 'mu') จะแสดงค่าที่สุ่มตัวอย่างของ mu ตลอดรอบการสุ่มตัวอย่างสำหรับแต่ละสายโซ่ สายโซ่ที่ลู่เข้าจะมีลักษณะคล้ายหนอนฟู ๆ โดยสายโซ่ทั้งหมดซ้อนทับกันและไม่มีแนวโน้มหรือการเคลื่อนออกจากกัน ส่วนสายโซ่ที่ไม่ลู่เข้าจะเคลื่อนที่ไปมา หรือแยกออกจากกัน

# library(rstan)
#
# traceplot(fit, pars = c('mu', 'sigma'), inc_warmup = FALSE)
#
# Good traceplot characteristics:
# - All 4 chains overlapping completely (same range)
# - No visible drift or trend
# - Rapid mixing (values jump around quickly)
# - No flat regions (stuck sampler)
cat('A healthy traceplot looks like a fuzzy caterpillar
')

pairs() สำหรับสหสัมพันธ์ของการแจกแจงภายหลัง

pairs(fit, pars = c('mu', 'sigma')) จะแสดงเมทริกซ์กราฟกระจายของตัวอย่างจากการแจกแจงภายหลัง ซึ่งช่วยเผยให้เห็นสหสัมพันธ์ระหว่างพารามิเตอร์ และเน้นการเปลี่ยนสถานะที่ไม่ลู่เข้า (แสดงเป็นสีแดง) ซึ่งบ่งชี้บริเวณที่ตัวสุ่มตัวอย่างทำงานได้ยาก

# pairs(fit, pars = c('mu', 'sigma'))
#
# What to look for:
# - Elliptical clouds: mild correlation (OK)
# - Banana / funnel shapes: reparameterization needed
# - Red dots (divergences): geometry problem in posterior
#   => increase adapt_delta: stan(..., control=list(adapt_delta=0.95))
cat('Red dots in pairs() indicate divergent transitions — investigate!
')

การดึงตัวอย่างจากการแจกแจงภายหลัง

extract(fit, pars = 'mu')$mu จะส่งคืนเวกเตอร์ตัวเลขของตัวอย่างหลังช่วงวอร์มอัปทั้งหมดสำหรับ mu คุณสามารถใช้ตัวอย่างเหล่านี้คำนวณค่าสรุปใด ๆ ของการแจกแจงภายหลังได้ เช่น ค่าเฉลี่ย ช่วงความน่าเชื่อถือ หรือความน่าจะเป็นของเงื่อนไขหนึ่ง

# mu_samples <- extract(fit, pars = 'mu')$mu
# cat('Posterior mean :', mean(mu_samples), '
')
# cat('95% CI:', quantile(mu_samples, c(0.025, 0.975)), '
')
# cat('P(mu > 2):', mean(mu_samples > 2), '
')
# hist(mu_samples, main = 'Posterior of mu', xlab = 'mu', col = 'steelblue')

การเปิดใช้ ShinyStan เพื่อตรวจวินิจฉัยแบบโต้ตอบ

shinystan::launch_shinystan(fit) จะเปิดแอป Shiny แบบโต้ตอบที่รวมกราฟเส้นร่องรอย การแจกแจงภายหลัง กราฟ pairs และตัวชี้วัดการวินิจฉัยของ NUTS ไว้ในที่เดียว นี่เป็นเครื่องมือที่ครอบคลุมที่สุดสำหรับสำรวจผลการปรับแบบจำลองด้วย RStan

# install.packages('shinystan')
# library(shinystan)
#
# shinystan::launch_shinystan(fit)
#
# ShinyStan tabs:
# - Diagnose: Rhat, n_eff, divergences, energy
# - Explore:  marginal posteriors, scatter plots
# - Model:    Stan code, data
# - NUTS:     step size, tree depth per chain

วิธีแก้ปัญหาการลู่เข้าที่พบบ่อย

เมื่อ Rhat > 1.01 หรือพบการไม่ลู่เข้า:

  • เพิ่ม iter และ warmup
  • เพิ่ม adapt_delta ให้เข้าใกล้ 1.0 เช่น 0.95 ใน control
  • ปรับการกำหนดพารามิเตอร์ใหม่ โดยใช้การกำหนดพารามิเตอร์แบบไม่จัดศูนย์สำหรับแบบจำลองลำดับชั้น
  • กำหนดการแจกแจงก่อนให้แคบลง หากการแจกแจงเดิมกระจายกว้างเกินไป
  • ตรวจสอบข้อมูล เนื่องจากค่าผิดปกติหรือสเกลที่แตกต่างกันอาจทำให้ตัวสุ่มตัวอย่างมีปัญหา
# Re-run with higher adapt_delta to reduce divergences:
# fit2 <- stan(
#   model_code = stan_code,
#   data       = stan_data,
#   chains     = 4,
#   iter       = 4000,
#   warmup     = 2000,
#   control    = list(adapt_delta = 0.95, max_treedepth = 12),
#   seed       = 42
# )

ตรวจสอบอย่างรวดเร็ว: เกณฑ์ Rhat

เกณฑ์มาตรฐานปัจจุบันของ Rhat ที่บ่งชี้ว่าแบบจำลอง Stan ลู่เข้าแล้วคือเท่าใด

ทบทวนการสุ่มตัวอย่างและการวินิจฉัย MCMC

ลำดับการทำงานหลักของ RStan MCMC:

  • stan(model_code=..., data=..., chains=4, iter=2000, warmup=1000) ใช้ปรับแบบจำลอง
  • print(fit) แสดง Rhat และ n_eff ซึ่งเป็นตัวชี้วัดหลักของการลู่เข้า
  • Rhat < 1.01 และ n_eff / total > 0.1 บ่งชี้ว่าตัวอย่างมีพฤติกรรมเหมาะสม
  • traceplot() — ตรวจสอบการผสมกันด้วยภาพ; pairs() — เผยให้เห็นปัญหาด้านเรขาคณิตของการแจกแจงภายหลัง
  • extract(fit, pars='mu')$mu — เข้าถึงตัวอย่างดิบจากการแจกแจงภายหลัง
  • shinystan::launch_shinystan(fit) — การวินิจฉัยแบบโต้ตอบอย่างครอบคลุม

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

บทเรียน “การสุ่มตัวอย่าง MCMC และการวินิจฉัย” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การสุ่มตัวอย่าง MCMC และการวินิจฉัย”

เรียกใช้การสุ่มตัวอย่าง ตรวจสอบสายโซ่ และตีความการวินิจฉัย Rhat กับ ESS คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การสุ่มตัวอย่าง MCMC และการวินิจฉัย” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม

ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนะนำแนวคิดแบบเบย์
  2. การเขียนโมเดล Stan ใน R
  3. การสุ่มตัวอย่าง MCMC และการวินิจฉัย
  4. การตรวจสอบการทำนายภายหลัง
← กลับไปที่ R Academy