R Academy · 강의

사후예측검사

시뮬레이션 데이터와 관측 데이터의 분포를 비교해 모델 적합도를 검증합니다.

레슨 4/413개 단계

사후예측검사은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

사후 예측 검사가 무엇인가요?

베이지안 모델을 적합한 후에는 다음을 물어야 합니다. 이 모델이 관측한 데이터와 비슷한 데이터를 생성하는가? 사후 예측 검사(PPC)는 사후분포에서 복제 데이터셋 yrep을 시뮬레이션하고 이를 관측값 y와 그래프로 비교하여 이 질문에 답합니다.

사후분포 표본 추출하기

extract(fit, pars='mu')는 이름이 지정된 목록을 반환하며, $mu는 해당 매개변수의 워밍업 후 표본 전체를 숫자 벡터로 반환합니다. 4개 연쇄에서 워밍업 후 반복이 각각 1000회라면 표본은 4000개가 됩니다.

# library(rstan)
# mu_samples    <- extract(fit, pars = 'mu')$mu
# sigma_samples <- extract(fit, pars = 'sigma')$sigma
#
# cat('Samples drawn:', length(mu_samples), '
')
# cat('Posterior mean of mu:', mean(mu_samples), '
')
# cat('90% CI:', quantile(mu_samples, c(0.05, 0.95)), '
')

사후분포 표본에서 yrep 생성하기

각 사후분포 추출값 (mu_s, sigma_s)에 대해 원래 데이터와 같은 크기의 복제 데이터셋을 시뮬레이션합니다. 이를 행마다 하나의 시뮬레이션 데이터셋이 들어가는 행렬 yrep에 저장합니다.

# y <- c(2.1, 1.8, 2.4, 1.9, 2.3, 2.0, 1.7, 2.2)
# n_obs <- length(y)
# S     <- length(mu_samples)  # 4000 posterior draws
#
# yrep <- matrix(NA, nrow = S, ncol = n_obs)
# for (s in seq_len(S)) {
#   yrep[s, ] <- rnorm(n_obs, mean = mu_samples[s], sd = sigma_samples[s])
# }
# dim(yrep)  # [4000, 8]

ppc_dens_overlay() — 밀도 비교

bayesplot::ppc_dens_overlay(y, yrep[1:50,])는 관측 데이터의 커널 밀도(짙은 선) 위에 무작위로 선택한 시뮬레이션 데이터셋 50개의 밀도(옅은 선)를 겹쳐 표시합니다. 모델 적합이 좋다면 짙은 선이 옅은 선들이 모인 영역 안에 놓입니다.

# library(bayesplot)
#
# ppc_dens_overlay(y, yrep[1:50, ])
#
# Interpretation:
# - Dark line (y_obs) surrounded by light lines (yrep): good fit
# - Dark line systematically outside the cloud: model misfit
# - Light lines much wider than dark: overdispersed model
# - Light lines much narrower than dark: underdispersed model

ppc_stat() — 검정 통계량 확인

ppc_stat(y, yrep, stat = 'mean')은 각 시뮬레이션 데이터셋에서 계산한 검정 통계량(예: 평균)의 히스토그램을 표시하고, 관측된 통계량에는 세로선을 표시합니다. 관측값이 히스토그램의 중심부에 있으면 모델이 데이터의 해당 특성을 포착한 것입니다.

# library(bayesplot)
#
# ppc_stat(y, yrep, stat = 'mean')   # does model capture the mean?
# ppc_stat(y, yrep, stat = 'sd')     # does model capture spread?
# ppc_stat(y, yrep, stat = 'max')    # does model capture extremes?
#
# If observed stat is in the tail of the histogram,
# the model fails to reproduce that statistic.

베이지안 p-값

베이지안 p-값(사후 예측 p-값)은 검정 통계량이 관측값보다 더 극단적인 시뮬레이션 데이터셋의 비율입니다. 0.5에 가까운 값은 보정이 양호함을, 0이나 1에 가까운 값은 해당 통계량에서 모델이 데이터에 맞지 않음을 나타냅니다.

# Bayesian p-value for the mean:
# obs_mean <- mean(y)
# rep_means <- apply(yrep, 1, mean)
# pval <- mean(rep_means >= obs_mean)
# cat('Bayesian p-value (mean):', round(pval, 3), '
')
# # 0.5 is perfect; < 0.05 or > 0.95 suggests misfit

추가 bayesplot PPC 함수

bayesplot은 밀도 겹치기 외에도 다양한 PPC 시각화를 제공합니다.

  • ppc_hist(y, yrep[1:8,]) — 히스토그램 격자
  • ppc_scatter_avg(y, yrep) — 관측값과 yrep 평균의 산점도
  • ppc_intervals(y, yrep) — 각 관측값 주변의 불확실성 구간
  • ppc_rootogram(y, yrep) — 개수형 데이터에 사용
# library(bayesplot)
#
# # Grid of 8 simulated histograms vs the observed
# ppc_hist(y, yrep[1:8, ])
#
# # Scatter: y_obs (x) vs mean of yrep (y) — should hug diagonal
# ppc_scatter_avg(y, yrep)
#
# # 50% and 90% posterior predictive intervals around each y_i
# ppc_intervals(y, yrep)

PPC 도표 해석 — 모델 부적합

일반적인 부적합 패턴과 원인:

  • yrep가 너무 넓음 — 사전분포가 너무 넓거나 모델의 과산포가 큼
  • yrep가 이동함 — 잘못된 가능도 분포(예: 왜도가 있는 데이터에 정규분포 사용)
  • yrep가 다봉성을 포착하지 못함 — 혼합 모델이 필요함
  • yrep가 극단값에 맞지 않음 — 꼬리가 두꺼운 분포가 필요함
# Example: if data has a long right tail but yrep does not,
# consider switching:
# y ~ normal(mu, sigma)  =>  y ~ student_t(nu, mu, sigma)
#
# Or for count data:
# y ~ poisson(lambda)  =>  y ~ neg_binomial_2(mu, phi)  (overdispersion)
cat('PPCs guide model improvement by revealing specific failure modes
')

Stan 모델 블록에서 PPC 사용하기

generated quantities 블록을 사용하면 Stan에서 직접 yrep을 생성할 수 있습니다. 이렇게 하면 R에서 매개변수를 다시 추출할 필요가 없으며 계산 결과는 동일합니다.

# Stan model with generated quantities:
# '
# generated quantities {
#   array[N] real y_rep;
#   for (n in 1:N) {
#     y_rep[n] = normal_rng(mu, sigma);
#   }
# }
# '
# Then extract in R:
# yrep <- extract(fit, pars = 'y_rep')$y_rep  # [S, N] matrix

일부 제외 교차 검증

PPC 외에도 loo::loo(fit)은 경쟁 모델을 비교하기 위한 일부 제외 교차 검증을 계산합니다. ELPD(기대 로그 예측 밀도)가 더 높은 모델을 선택합니다. loo::loo_compare(loo1, loo2)를 사용하면 모델 순위를 매길 수 있습니다.

# library(loo)
# loo1 <- loo(fit1)  # normal model
# loo2 <- loo(fit2)  # student-t model
#
# comparison <- loo_compare(loo1, loo2)
# print(comparison)
#
# Model with elpd_diff > 0 is preferred
# se_diff > |elpd_diff| means difference is not reliable

PPC 모범 사례

엄밀한 사후 예측 검사를 위해 다음 방법을 따르세요.

  • 항상 전반적인 타당성 점검으로 ppc_dens_overlay()부터 시작합니다
  • 분석 목표와 관련된 영역별 통계량(ppc_stat())으로 추가 확인을 진행합니다
  • 시각적 확인에는 yrep 추출값을 최소 50개 사용하고, 베이지안 p-값에는 4000개를 모두 사용합니다
  • PPC 실패 결과는 모델 개선의 방향을 제시합니다 — 실패가 아니라 진단 정보입니다
# Workflow:
# 1. Fit model -> extract() -> generate yrep matrix
# 2. ppc_dens_overlay(y, yrep[1:50,])  -- visual global check
# 3. ppc_stat(y, yrep, stat='mean')    -- check mean
# 4. ppc_stat(y, yrep, stat='sd')      -- check spread
# 5. ppc_stat(y, yrep, stat='max')     -- check tails
# 6. If misfit found -> revise model -> refit -> re-check

빠른 확인: 베이지안 p-값 해석

최댓값 통계량에 대한 베이지안 p-값이 0.03이라면 모델에 대해 무엇을 의미하나요?

사후 예측 검사 복습

RStan과 bayesplot을 사용한 PPC 작업 흐름:

  • 표본 추출: extract(fit, pars='mu')$mu
  • yrep 생성: 사후분포 추출값을 순회하며 rnorm(n, mu_s, sigma_s) 호출
  • 전반적 확인: ppc_dens_overlay(y, yrep[1:50,])
  • 통계량 확인: ppc_stat(y, yrep, stat='mean')
  • 베이지안 p-값: mean(apply(yrep,1,stat) >= stat(y)) — 0.5에 가까우면 양호함
  • 모델 비교에는 loo::loo_compare()를 사용합니다
무료로 시작

AI 튜터와 함께 R을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
43
레슨
159

자주 묻는 질문

“사후예측검사” 강의는 무료인가요?

네 — “사후예측검사” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“사후예측검사”에서 뭘 배우나요?

시뮬레이션 데이터와 관측 데이터의 분포를 비교해 모델 적합도를 검증합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

R Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“사후예측검사” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 베이지안 사고 입문
  2. R에서 Stan 모델 작성하기
  3. MCMC 표본추출과 진단
  4. 사후예측검사
← R Academy(으)로 돌아가기