Байесовский анализ сложных моделей возможен с помощью алгоритмов Монте-Карло по схеме Марковской цепи (MCMC). По идее, исследователь должен не только сформулировать модель, априорное мнение о параметрах модели, но и самостоятельно сконструировать цепь сходящуюся к апостериорному распределению параметров. Однако оказалось, что конструирование цепи в большинстве ситуаций можно доверить компьютеру.
Программа STAN — это не пакет R, а отдельный язык описания байесовских моделей. Исследователь описывает модель и априорное распределение параметров, а STAN генерирует код C++, в котором запрограммирована требуемая марковская цепь. Среди альтернатив программе STAN можно назвать JAGS, R + пакет NIMBLE, python + пакет PyMC, Julia + змея Mamba и Julia + Klara.
Для работы требуется установить пакет rstan
, который содержит и свежую версию программы STAN. В силу того, что здесь взаимодействует много программ (R, STAN, компилятор C++), установку следует выполнять аккуратно, строго по инструкции на сайте STAN.
library("rstan") # врубим на полную мощь Байеса!
library("shinystan") # и на полную громкость интерактивный анализ полученной цепи
Пара опций: определяем число ядер процессора, чтобы при симуляциях использовались все ядра и просим STAN сохранить скомпилированную модель, чтобы не перекомпилировать её для каждой цепи.
rstan_options(auto_write = TRUE)
options(mc.cores = parallel::detectCores())
Модель 1: Байесовский МНК
model_bayesian_ls <- "
data {
int n;
int k;
vector[n] y;
matrix[n, k] X;
}
parameters {
vector[k] beta;
real<lower=0> sigma;
}
model {
y ~ normal(X * beta, sigma);
}
"
Блок data
описывает, какие данные нужно передать STAN. Блок model
описывает, хм, неужели модель?
\[ y|\beta, \sigma, X \sim \mathcal{N}(X\beta, \sigma^2 \cdot I) \]
Блок parameters
описывает априорное распределение. Если не указывать явно, то по умолчанию предполагаются равномерные распределения на допустимом множестве. Для вектора бет это означает: \[
\beta_j \sim U(-\infty, \infty)
\] Для константы \(\sigma\) мы подразумеваем: \[
\sigma \sim U(0, \infty)
\]
Конечно, настоящего равномерного распределения на неограниченном интервале не бывает, это несобственное распределение. Однако в данном случае апостериорное распределение оказывается собственным.
Можно явно указать любое другое априорное распределение.
Формируем данные:
n <- nrow(cars)
k <- 2
y <- cars$dist
X <- cbind(rep(1, n), cars$speed)
cars_data <- list(n = n, k = k, y = y, X = X)
Запускаем 4 цепи:
fit <- stan(model_code = model_bayesian_ls, data = cars_data,
iter = 1000, chains = 4)
Апостериорное распределение параметров:
fit
## Inference for Stan model: dd48765ea01c4aabdbe455473e42eb1a.
## 4 chains, each with iter=1000; warmup=500; thin=1;
## post-warmup draws per chain=500, total post-warmup draws=2000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff
## beta[1] -17.53 0.26 6.84 -31.26 -21.94 -17.59 -13.18 -4.04 679
## beta[2] 3.93 0.02 0.42 3.07 3.67 3.94 4.20 4.77 681
## sigma 15.75 0.05 1.62 12.93 14.68 15.60 16.65 19.47 981
## lp__ -159.37 0.05 1.24 -162.68 -159.92 -159.00 -158.49 -158.01 746
## Rhat
## beta[1] 1
## beta[2] 1
## sigma 1
## lp__ 1
##
## Samples were drawn using NUTS(diag_e) at Wed Sep 28 08:59:18 2016.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
Модель 2: Байесовский логит
Модель 3:
Описываем модель на языке STAN:
model_8_schools <- "
data {
int<lower=0> J; // number of schools
real y[J]; // estimated treatment effects
real<lower=0> sigma[J]; // s.e. of effect estimates
}
parameters {
real mu;
real<lower=0> tau;
real eta[J];
}
transformed parameters {
real theta[J];
for (j in 1:J)
theta[j] = mu + tau * eta[j];
}
model {
eta ~ normal(0, 1);
y ~ normal(theta, sigma);
}
"
Задаем данные:
schools_data <- list(J = 8,
y = c(28, 8, -3, 7, -1, 1, 18, 12),
sigma = c(15, 10, 16, 11, 9, 11, 10, 18))
Запускаем 4 цепи:
fit <- stan(model_code = model_8_schools, data = schools_data,
iter = 1000, chains = 4)
Апостериорное распределение параметров:
fit
## Inference for Stan model: 4cd96c47cbb67b368bab02377102f603.
## 4 chains, each with iter=1000; warmup=500; thin=1;
## post-warmup draws per chain=500, total post-warmup draws=2000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
## mu 8.08 0.15 4.74 -1.08 5.05 7.86 11.10 17.97 948 1.00
## tau 6.33 0.22 5.16 0.24 2.31 4.99 9.15 18.70 529 1.01
## eta[1] 0.35 0.03 0.93 -1.49 -0.26 0.38 1.02 2.08 1391 1.00
## eta[2] -0.03 0.02 0.84 -1.64 -0.59 -0.03 0.50 1.65 1529 1.00
## eta[3] -0.17 0.03 0.90 -1.93 -0.77 -0.19 0.41 1.68 1262 1.00
## eta[4] -0.04 0.02 0.90 -1.85 -0.62 -0.04 0.54 1.74 1535 1.00
## eta[5] -0.35 0.02 0.82 -1.92 -0.92 -0.37 0.18 1.31 1366 1.00
## eta[6] -0.24 0.02 0.88 -1.95 -0.83 -0.25 0.35 1.48 1406 1.00
## eta[7] 0.30 0.03 0.88 -1.45 -0.28 0.32 0.89 2.06 1173 1.00
## eta[8] 0.02 0.03 0.89 -1.75 -0.56 0.02 0.63 1.75 1024 1.00
## theta[1] 11.53 0.30 8.47 -1.10 6.03 9.82 15.60 33.39 800 1.00
## theta[2] 7.80 0.14 5.94 -3.87 4.17 7.88 11.43 19.81 1793 1.00
## theta[3] 6.33 0.20 7.35 -11.38 2.72 6.93 10.82 19.96 1311 1.00
## theta[4] 7.65 0.15 6.30 -4.69 3.75 7.49 11.62 20.56 1781 1.00
## theta[5] 5.31 0.14 6.04 -7.94 1.58 5.62 9.22 16.75 1808 1.00
## theta[6] 5.99 0.17 6.67 -9.28 2.42 6.43 10.19 18.19 1545 1.00
## theta[7] 10.62 0.20 7.04 -1.73 6.02 9.87 14.62 27.32 1228 1.00
## theta[8] 8.37 0.23 7.70 -6.49 3.67 8.04 12.50 25.17 1148 1.00
## lp__ -4.68 0.10 2.54 -9.79 -6.24 -4.44 -2.87 -0.30 594 1.00
##
## Samples were drawn using NUTS(diag_e) at Wed Sep 28 09:00:06 2016.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
Графики:
….
Тесты на сходимость цепей:
….
Документация STAN содержит кучу встроенных примеров:
stan_demo()
Визуализировать полученную цепь КРАЙНЕ удобно интерактивно с помощью команды
shiny_stan_object <- launch_shinystan(fit)
Почиташки: