การสุ่มตัวอย่าง 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แนะนำแนวคิดแบบเบย์
- การเขียนโมเดล Stan ใน R
- การสุ่มตัวอย่าง MCMC และการวินิจฉัย
- การตรวจสอบการทำนายภายหลัง