การเขียนโมเดล Stan ใน R
กำหนดบล็อกข้อมูล พารามิเตอร์ และบล็อกโมเดลด้วยไวยากรณ์ของ Stan
การเขียนโมเดล Stan ใน R เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
Stan คืออะไร
Stan เป็นภาษาโปรแกรมเชิงความน่าจะเป็นสำหรับการสร้างแบบจำลองทางสถิติแบบเบย์ RStan คือส่วนเชื่อมต่อจาก R ไปยัง Stan คุณเขียนแบบจำลองด้วยภาษาของ Stan (คล้าย C++) จากนั้น Stan จะคอมไพล์เป็นโค้ด C++ ที่มีประสิทธิภาพและเรียกใช้การสุ่มตัวอย่างแบบมอนติคาร์โลแฮมิลโทเนียน (HMC) เพื่อประมาณการแจกแจงภายหลัง
# Stan installation check
library(rstan)
# Check version
cat('RStan version:', as.character(packageVersion('rstan')), '\n')
# Enable parallel chains
options(mc.cores = parallel::detectCores())
# Reuse compiled models across sessions
rstan_options(auto_write = TRUE)
cat('Stan ready. Cores:', parallel::detectCores(), '\n')โครงสร้างแบบจำลองของ Stan
แบบจำลอง Stan มีบล็อกที่ตั้งชื่อได้สูงสุดหกบล็อก ได้แก่ data, transformed data, parameters, transformed parameters, model และ generated quantities บล็อกสำคัญสามบล็อกคือ data, parameters และ model
library(rstan)
# Stan model as a character string in R
stan_code <- '
data {
int<lower=0> N; // number of observations
vector[N] x; // predictor
vector[N] y; // response
}
parameters {
real alpha; // intercept
real beta; // slope
real<lower=0> sigma; // noise (must be positive)
}
model {
// Priors
alpha ~ normal(0, 10);
beta ~ normal(0, 10);
sigma ~ exponential(1);
// Likelihood
y ~ normal(alpha + beta * x, sigma);
}
'
cat('Stan model defined as a string in R\n')
cat('Blocks: data, parameters, model\n')data{}: การประกาศข้อมูลนำเข้า
บล็อก data ประกาศข้อมูลภายนอกทั้งหมดที่แบบจำลองรับมาจาก R ชนิดข้อมูล ได้แก่ int, real, vector[N], matrix[M,N] และ array ข้อจำกัดอย่าง <lower=0> จะได้รับการตรวจสอบขณะทำงาน
library(rstan)
# Comprehensive data block examples
data_block_examples <- '
data {
// Scalars
int<lower=1> N; // at least 1 observation
int<lower=2> K; // at least 2 groups
// Constrained scalars
real<lower=0, upper=1> rate; // probability
// Vectors
vector[N] y; // continuous response
array[N] int<lower=0, upper=1> z; // binary outcomes
// Matrix
matrix[N, K] X; // design matrix
// Integer array
array[N] int group; // group membership 1..K
}
'
cat(data_block_examples)บล็อก parameters{}: ประเภทพารามิเตอร์
บล็อก parameters ใช้ประกาศค่าที่ไม่ทราบซึ่ง Stan จะสุ่มตัวอย่าง ข้อจำกัดในบล็อกนี้จะกำหนดปริภูมิพารามิเตอร์ เช่น <lower=0> สำหรับปริมาณที่เป็นบวก และ <lower=0, upper=1> สำหรับความน่าจะเป็น Stan จะใช้การแก้ไขจาโคเบียนของความน่าจะเป็นลอการิทึมกับพารามิเตอร์ที่มีข้อจำกัดโดยอัตโนมัติ
library(rstan)
# Common parameter declarations
param_examples <- '
parameters {
// Unconstrained
real mu; // mean
vector[K] beta; // regression coefficients
// Positive (sigma, lambda, variance)
real<lower=0> sigma;
real<lower=0> lambda;
// Probability
real<lower=0, upper=1> theta;
// Simplex (sums to 1, for mixture weights)
simplex[K] pi;
// Correlation matrix
corr_matrix[K] Omega;
// Cholesky factor of covariance
cholesky_factor_cov[K] L_Sigma;
}
'
cat(param_examples)บล็อก model{}: การแจกแจงก่อนและฟังก์ชันภาวะน่าจะเป็น
บล็อก model จะสะสมค่าลอการิทึมของการแจกแจงภายหลังด้วยไวยากรณ์ ~ (ตัวหนอน) นิพจน์ y ~ normal(mu, sigma) เป็นรูปย่อของการบวกค่าลอการิทึมของ PDF แบบปกติเข้าใน target คุณสามารถเขียนการเพิ่มค่าความน่าจะเป็นลอการิทึมอย่างชัดเจนได้ด้วย target += normal_lpdf(y | mu, sigma)
library(rstan)
model_block_example <- '
model {
// --- Priors ---
mu ~ normal(0, 10); // weakly informative
sigma ~ cauchy(0, 2.5); // half-Cauchy for scale
beta ~ normal(0, 1); // standardised coefficients
// --- Likelihood ---
// Tilde notation (most common)
y ~ normal(mu + X * beta, sigma);
// Equivalent explicit notation:
// target += normal_lpdf(y | mu + X * beta, sigma);
// For loop (less common but valid)
// for (i in 1:N)
// target += normal_lpdf(y[i] | mu, sigma);
}
'
cat(model_block_example)การปรับแบบจำลองปกติอย่างง่าย
นี่คือลำดับการทำงานของ Stan แบบสมบูรณ์และกระชับ: กำหนดสตริงแบบจำลอง เตรียมรายการข้อมูล เรียกใช้ stan() และตรวจสอบผลลัพธ์ด้วย print() Stan จะคอมไพล์แบบจำลองในการเรียกใช้ครั้งแรกและเก็บไว้ในแคชสำหรับการเรียกใช้ครั้งถัดไป
library(rstan)
# Stan model: estimate mean and SD of a normal distribution
normal_model <- '
data {
int<lower=0> N;
vector[N] y;
}
parameters {
real mu;
real<lower=0> sigma;
}
model {
mu ~ normal(0, 10);
sigma ~ exponential(0.1);
y ~ normal(mu, sigma);
}
'
# Simulate data
set.seed(42)
y_data <- rnorm(50, mean = 5, sd = 2)
# Fit the model
fit <- stan(
model_code = normal_model,
data = list(N = length(y_data), y = y_data),
chains = 2,
iter = 1000,
warmup = 500,
refresh = 0 # suppress iteration output
)
print(fit, pars = c('mu', 'sigma'))การถดถอยเชิงเส้นใน Stan
Stan ทำให้การถดถอยเชิงเส้นแบบเบย์ทำได้อย่างตรงไปตรงมา โดยกำหนดการแจกแจงก่อนแบบปกติให้กับสัมประสิทธิ์ และกำหนดการแจกแจงก่อนแบบเอ็กซ์โพเนนเชียลหรือฮาล์ฟ-Cauchy ให้กับ sigma การแจกแจงภายหลังจะแสดงการกระจายของความไม่แน่นอนทั้งหมดสำหรับสัมประสิทธิ์แต่ละตัว ไม่ใช่เพียงค่าประมาณจุดเดียว
library(rstan)
lin_reg_model <- '
data {
int<lower=0> N;
vector[N] x;
vector[N] y;
}
parameters {
real alpha;
real beta;
real<lower=0> sigma;
}
model {
alpha ~ normal(0, 10);
beta ~ normal(0, 10);
sigma ~ exponential(1);
y ~ normal(alpha + beta * x, sigma);
}
generated quantities {
vector[N] y_rep; // posterior predictive
for (i in 1:N)
y_rep[i] = normal_rng(alpha + beta * x[i], sigma);
}
'
set.seed(7)
n <- 80
x <- rnorm(n); y <- 2 + 3 * x + rnorm(n, 0, 1)
fit <- stan(model_code = lin_reg_model,
data = list(N = n, x = x, y = y),
chains = 2, iter = 1000, refresh = 0)
print(fit, pars = c('alpha', 'beta', 'sigma'))บล็อกพารามิเตอร์ที่แปลงแล้ว{}
บล็อก transformed parameters ใช้คำนวณปริมาณที่ได้จากพารามิเตอร์ที่สุ่มตัวอย่าง ปริมาณเหล่านี้มีประโยชน์สำหรับการกำหนดพารามิเตอร์ของแบบจำลองให้มีเสถียรภาพทางตัวเลข เช่น การแยกแบบโชลสกีและการแปลงลอการิทึม โดยยังคงทำให้พารามิเตอร์หลักตีความได้ง่าย
library(rstan)
# Model with transformed parameters
trans_param_example <- '
data {
int<lower=0> N;
array[N] int<lower=0> y; // counts
}
parameters {
real log_lambda; // work in log space for stability
}
transformed parameters {
real<lower=0> lambda;
lambda = exp(log_lambda); // transform back to original scale
}
model {
log_lambda ~ normal(1, 2); // prior on log scale
y ~ poisson(lambda);
}
'
set.seed(42)
y_counts <- rpois(30, lambda = 5)
fit_poisson <- stan(
model_code = trans_param_example,
data = list(N = length(y_counts), y = y_counts),
chains = 2, iter = 1000, refresh = 0
)
print(fit_poisson, pars = c('log_lambda', 'lambda'))บล็อกปริมาณที่สร้างขึ้น{}
บล็อก generated quantities จะทำงานหลังการสุ่มตัวอย่างเพื่อคำนวณปริมาณเพิ่มเติม เช่น ตัวอย่างการพยากรณ์จากการแจกแจงภายหลัง (y_rep) ค่าลอการิทึมของฟังก์ชันภาวะน่าจะเป็นสำหรับ LOO-CV หรือพารามิเตอร์ที่แปลงแล้วสำหรับสรุปผล ค่าที่อยู่ในบล็อกนี้จะถูกสุ่มจากการแจกแจงการพยากรณ์ภายหลัง
library(rstan)
# Use generated quantities for posterior predictive checks
model_with_gq <- '
data {
int<lower=0> N;
vector[N] y;
}
parameters {
real mu;
real<lower=0> sigma;
}
model {
mu ~ normal(0, 10);
sigma ~ exponential(0.5);
y ~ normal(mu, sigma);
}
generated quantities {
vector[N] y_rep; // replicated datasets
real mean_y_rep; // mean of replicated data
for (i in 1:N)
y_rep[i] = normal_rng(mu, sigma);
mean_y_rep = mean(y_rep);
}
'
set.seed(1)
y_obs <- rnorm(40, 3, 1.5)
fit <- stan(model_code = model_with_gq,
data = list(N = length(y_obs), y = y_obs),
chains = 2, iter = 1000, refresh = 0)
print(fit, pars = c('mu', 'sigma', 'mean_y_rep'))การส่งข้อมูลจาก R ไปยัง Stan
อาร์กิวเมนต์ data ของ stan() คือรายการ R ที่มีชื่อกำกับ ชื่อต่าง ๆ ต้องตรงกับชื่อตัวแปรที่ประกาศไว้ในบล็อก data{} ของ Stan ทุกประการ เวกเตอร์จะกลายเป็น vector[N] ใน Stan จำนวนเต็มจะกลายเป็น int และเมทริกซ์ R จะกลายเป็น matrix[M,N] ใน Stan
library(rstan)
# Data preparation: names must match Stan data block exactly
set.seed(42)
n <- 60
x1 <- rnorm(n)
x2 <- rnorm(n)
y <- 1.5 + 2 * x1 - 0.8 * x2 + rnorm(n, 0, 0.5)
# Build the design matrix
X <- cbind(x1, x2) # 60 x 2 matrix
# Named list passed to stan(data = ...)
stan_data <- list(
N = n, # int
K = ncol(X), # int
X = X, # matrix[N, K]
y = y # vector[N]
)
cat('Stan data list elements:\n')
for (nm in names(stan_data)) {
cat(' ', nm, ': class =', class(stan_data[[nm]]),
'dim =', paste(dim(stan_data[[nm]]), collapse = 'x'),
'\n')
}การดูแบบจำลองที่คอมไพล์แล้ว
หลังจากปรับแบบจำลองแล้ว ให้ใช้ print(fit) เพื่อดูสรุปการแจกแจงภายหลัง (ค่าเฉลี่ย se_mean sd ควอนไทล์ Rhat และ n_eff) ของพารามิเตอร์ทั้งหมด ใช้ stan_plot(fit) เพื่อสร้างกราฟช่วงค่า และใช้ traceplot(fit) เพื่อประเมินการผสมกันของสายโซ่
library(rstan)
# Reuse the simple normal model from scene 6
normal_model <- '
data { int<lower=0> N; vector[N] y; }
parameters { real mu; real<lower=0> sigma; }
model {
mu ~ normal(0, 10);
sigma ~ exponential(0.1);
y ~ normal(mu, sigma);
}
'
set.seed(5)
fit <- stan(model_code = normal_model,
data = list(N = 50, y = rnorm(50, 7, 3)),
chains = 2, iter = 1000, refresh = 0)
# Detailed summary table
print(fit)
# Extract as data frame
posterior_df <- as.data.frame(fit)
cat('\nPosterior samples shape:', nrow(posterior_df),
'rows x', ncol(posterior_df), 'cols\n')ตรวจสอบอย่างรวดเร็ว
ในแบบจำลอง Stan หากต้องการกำหนดให้พารามิเตอร์มีค่าเป็นบวกอย่างเคร่งครัด เช่น ส่วนเบี่ยงเบนมาตรฐาน ควรประกาศแบบใด
ทบทวน: การเขียนแบบจำลอง Stan
ประเด็นสำคัญ:
- แบบจำลอง Stan มีสามบล็อกหลัก ได้แก่
data{},parameters{}และmodel{} - ข้อจำกัด:
<lower=0>,<upper=1>และ<lower=0, upper=1>สำหรับความน่าจะเป็น - ชนิดข้อมูล:
int,real,vector[N],matrix[M,N]และsimplex[K] - บล็อกแบบจำลอง: ใช้ไวยากรณ์ตัวหนอน
y ~ normal(mu, sigma)สำหรับการแจกแจงก่อนและฟังก์ชันภาวะน่าจะเป็น - ใช้
transformed parameters{}สำหรับปริมาณที่ได้จากการคำนวณ และgenerated quantities{}สำหรับการคำนวณหลังการสุ่มตัวอย่าง - ส่งข้อมูลเป็นรายการ R ที่มีชื่อกำกับ โดยชื่อต้องตรงกับชื่อบล็อกของ Stan ทุกประการ
rstan_options(auto_write = TRUE)ใช้เก็บแบบจำลองที่คอมไพล์แล้วไว้ในแคช
library(rstan)
# Stan model skeleton
model_skeleton <- '
data { int N; vector[N] y; }
parameters { real mu; real<lower=0> sigma; }
model { mu ~ normal(0,10); sigma ~ exponential(1); y ~ normal(mu, sigma); }
'
cat(model_skeleton)
cat('\nFit with: stan(model_code = model_skeleton, data = list(N=..., y=...), chains=4)\n')เรียนรู้ R ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 43
- บทเรียน
- 159
คำถามที่พบบ่อย
บทเรียน “การเขียนโมเดล Stan ใน R” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเขียนโมเดล Stan ใน R” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเขียนโมเดล Stan ใน R”
กำหนดบล็อกข้อมูล พารามิเตอร์ และบล็อกโมเดลด้วยไวยากรณ์ของ Stan คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การเขียนโมเดล Stan ใน R” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แนะนำแนวคิดแบบเบย์
- การเขียนโมเดล Stan ใน R
- การสุ่มตัวอย่าง MCMC และการวินิจฉัย
- การตรวจสอบการทำนายภายหลัง