As interfaces amigáveis do Stan
A principal ferramenta para computação Bayesiana é a linguagem probabilística Stan
(Carpenter et al., 2017). O problema do Stan
é que ele é uma linguagem de programação e, portanto, possui um acesso dificultado a não-programadores. Abaixo um código que mostra como é um programa escrito em Stan
1:
data {
int<lower=0> N;
vector<lower=0, upper=200>[N] kid_score;
vector<lower=0, upper=200>[N] mom_iq;
}
parameters {
real alpha;
real beta;
real<lower=0> sigma;
}
model {
sigma ~ cauchy(0, 2.5);
kid_score ~ normal(alpha + beta * mom_iq, sigma);
}
Para remediar essa barreira de acesso ao Stan
, temos interfaces abstratas que interpretam a intenção do usuário e lidam com a parte mais obral de codificação. As principais são rstanarm
(Goodrich, Gabry, Ali, & Brilleman, 2020) e brms
(Bürkner, 2017). Ambos usa a mesma síntaxe e as mesmas famílias de funções de verossimilhança, mas com algumas diferenças:
rstanarm
todos os modelos são pré-compilados e brms
não possui os modelos pré-compilados então os modelos devem ser todos compilados antes de serem rodados. A diferença prática é que você irá esperar alguns instantes antes do R começar a amostrar do modelo.brms
compila os modelos conforme a especificação do usuário (não possui modelos pré-compilados) ele pode criar modelos um pouco mais eficientes que o rstanarm
. Caso o tempo de compilação dos modelos brms
seja menor que ganho de velocidade em amostragem do modelo, é vantajoso especificar seu modelo com brms
.brms
dá maior poder e flexibilidade ao usuário na especificação de funções de verossimilhança e também permite modelos mais complexos que o rstanarm
(um exemplo notório é que rstanarm
não permite usarmos distribuição \(t\) de Student como função de verossimilhança enquanto que isso é possível no brms
. Portanto a Aula 9 - Regressão Robusta usará exclusivamente o brms
).Todos os modelos especificados pelo rstanarm
e brms
usam uma fórmula com a seguinte síntaxe:
dependente ~ independente_1 + independente_2 + ...
Para quem conhece R
essa síntaxe é a mesma utilizada em regressões lineares frequentista com o lm()
ou em modelos lineares generalizados frequentistas com glm()
.
family
Todo modelo especificado pelo rstanarm
e brms
devem especificar qual família da função de verossimilhança (family
) respectivamente com a função de ligação (‘link’) que fará o mapeamento dos parâmetros condicionados nos dados para a variável dependente. Caso o usuário não designe nenhum valor para esses dois parâmetros, rstanarm
e brms
usarão a verossimilhança Gaussiana (family = gaussian
) e a função de identidade como função de ligação (link = "identity"
).
Estes argumentos family
e link
são conhecidos para quem usa R para estatística frequentista pois são os mesmos da função glm()
de R para modelos lineares generalizados frequentistas. Algumas das principais famílias com suas funções de ligação padrões são:
family = gaussian
– link = "identity"
family = lognormal
– link = "log"
family = binomial
– link = "logit"
family = poisson
– link = "log"
family = negbinomial
– link = "log"
family = student
– link = "identity"
family = exponential
– link = "log"
rstanarm
O rstanarm
é a porta de entrada para estatística Bayesiana com Stan
. O nome rstanarm
é:
r
: pacote para R
stan
: usa a linguagem probabilística Stan
arm
: acrônimo para Applied Regression ModelingEle possui as seguintes funções para especificação de modelos Bayesianos:
stan_glm()
– modelos lineares generalizados (generalized linear model)stan_lm()
– modelos lineares regularizados (linear model)stan_aov()
– modelo ANOVA (analysis of variance)stan_glmer()
– modelos linares generalizados multiníveisstan_lmer()
– modelos linares regularizados multiníveisstan_jm()
– modelos longitudinais e de sobrevivênciastan_nlmer()
– modelos não-lineares multiníveis (non-linear model)stan_polr()
– modelos ordinaisstan_gamm4()
– modelos aditivos linares multiníveisNeste curso usaremos apenas stan_glm
e stan_glmer
, mas saiba que você possui uma vasta categoria de modelos bayesianos à disposição.
mtcars
Vamos estimar modelos Bayesianos usando o dataset já conhecido mtcars
da Aula 1 - Comandos Básicos de R. A idéia é usarmos como variável dependente a autonomia do carro (milhas por galão – mpg
) e como independentes o peso do carro (wt
) e se o carro é automático ou manual (am
). A fórmula então fica:
mpg ~ wt + am
Note que também devemos especificar a localização dos nossos dados com o argumento data
. Para garantir que toda a funcionalidade do rstanarm
esteja disponível para seu modelo, recomendo que especifique sempre o valor de data
como um objeto data.frame
ou tibble
.
Podemos ver o sumário do modelo estimado2 com a função print()
ou summary()
:
print(rstanarm_fit)
stan_glm
family: gaussian [identity]
formula: mpg ~ wt + am
observations: 32
predictors: 3
------
Median MAD_SD
(Intercept) 37.3 3.2
wt -5.3 0.8
am 0.0 1.5
Auxiliary parameter(s):
Median MAD_SD
sigma 3.2 0.4
------
* For help interpreting the printed output see ?print.stanreg
* For info on the priors used see ?prior_summary.stanreg
summary(rstanarm_fit)
Model Info:
function: stan_glm
family: gaussian [identity]
formula: mpg ~ wt + am
algorithm: sampling
sample: 4000 (posterior sample size)
priors: see help('prior_summary')
observations: 32
predictors: 3
Estimates:
mean sd 10% 50% 90%
(Intercept) 37.2 3.2 33.2 37.3 41.1
wt -5.3 0.8 -6.3 -5.3 -4.3
am 0.0 1.6 -2.0 0.0 2.1
sigma 3.2 0.4 2.7 3.2 3.8
Fit Diagnostics:
mean sd 10% 50% 90%
mean_PPD 20.1 0.8 19.1 20.1 21.1
The mean_ppd is the sample average posterior predictive distribution of the outcome variable (for details see help('summary.stanreg')).
MCMC diagnostics
mcse Rhat n_eff
(Intercept) 0.1 1.0 1945
wt 0.0 1.0 2085
am 0.0 1.0 1949
sigma 0.0 1.0 2793
mean_PPD 0.0 1.0 3434
log-posterior 0.0 1.0 1394
For each parameter, mcse is Monte Carlo standard error, 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).
A interpretação e significado da saída dos modelos rstanarm
serão explicadas nas aulas seguintes. A função print()
é mais concisa que a função summary()
. Para quem já rodou modelos de regressão, o output da função print()
mostra a mediana (Median
) dos coeficientes e erro (sigma
) do modelo junto com o desvio absoluto médio (mean absolute deviation – MAD_SD
). No output da função summary()
, a tabela Estimates
é a tabela que mostra a média (mean
) dos coeficientes e erro (sigma
) do modelo junto com o desvio padrão (sd
) e os percentis 10%, 50% (mediana) e 90% baseados na mediana e desvio absoluto médio.
Podemos também especificar os percentis desejados no summary()
:
Model Info:
function: stan_glm
family: gaussian [identity]
formula: mpg ~ wt + am
algorithm: sampling
sample: 4000 (posterior sample size)
priors: see help('prior_summary')
observations: 32
predictors: 3
Estimates:
mean sd 2.5% 97.5%
(Intercept) 37.2 3.2 30.9 43.4
wt -5.3 0.8 -6.9 -3.7
am 0.0 1.6 -3.1 3.3
sigma 3.2 0.4 2.5 4.2
Fit Diagnostics:
mean sd 2.5% 97.5%
mean_PPD 20.1 0.8 18.5 21.6
The mean_ppd is the sample average posterior predictive distribution of the outcome variable (for details see help('summary.stanreg')).
MCMC diagnostics
mcse Rhat n_eff
(Intercept) 0.1 1.0 1945
wt 0.0 1.0 2085
am 0.0 1.0 1949
sigma 0.0 1.0 2793
mean_PPD 0.0 1.0 3434
log-posterior 0.0 1.0 1394
For each parameter, mcse is Monte Carlo standard error, 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).
brms
O brms
alia toda a comodidade do rstanarm
com o poder e flexibilidade do Stan
. O nome brms
quer dizer:
b
: Bayesianr
: regressionm
: modelss
: usando Stan
Ao invés de possuir diversas funções para diferentes tipos de modelo, brms
tem apenas uma única função para especificar modelos: brm()
– acrônimo para Bayesian Regression Model. O usuário consegue especificar qualquer modelo que quiser a partir da função brm()
apenas mudando seus parâmetros internos. Os parâmetros da função brm()
mais importantes são (como mencionado acima):
family
– especifica a família da função de verossimilhança do modelo (padrão gaussian
)link
– especifica a função de ligação que fará o mapeamento dos parâmetros condicionados nos dados para a variável dependente do modelo (padrão varia conforme o family
, mas para family = gaussian
, a função identidade é a função de ligação padrão link = "identity"
)Vamos usar o mesmo modelo que usamos para o rstanarm
acima. Note que a fórmula não muda e usaremos a mesma:
mpg ~ wt + am
Note que também devemos especificar a localização dos nossos dados com o argumento data
. Para garantir que toda a funcionalidade do brms
esteja disponível para seu modelo, recomendo que especifique sempre o valor de data
como um objeto data.frame
ou tibble
.
Podemos ver o sumário do modelo estimado3 com a função print()
ou summary()
. No caso do brms
não há diferença entre elas e elas literalmente produzem o mesmo output:
print(brms_fit)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: mpg ~ wt + am
Data: mtcars (Number of observations: 32)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept 37.27 3.21 30.88 43.79 1.00 2340 2513
wt -5.34 0.83 -6.98 -3.68 1.00 2355 2334
am -0.01 1.63 -3.18 3.15 1.00 2474 2639
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 3.21 0.44 2.50 4.18 1.00 2760 2835
Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
summary(brms_fit)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: mpg ~ wt + am
Data: mtcars (Number of observations: 32)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept 37.27 3.21 30.88 43.79 1.00 2340 2513
wt -5.34 0.83 -6.98 -3.68 1.00 2355 2334
am -0.01 1.63 -3.18 3.15 1.00 2474 2639
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 3.21 0.44 2.50 4.18 1.00 2760 2835
Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Note que temos quase que o mesmo output, sendo que brms
por padrão mostra a média (Estimate
) dos coeficientes e erro (sigma
) do modelo junto com o desvio padrão (Est.Error
) e os percentis 5% (l-95%
) e 95% (u-95%
) baseados na média e desvio padrão. Caso queira mediana e desvio absoluto médio, forneça o argumento robust = TRUE
para a função print()
:
summary(brms_fit, robust = TRUE)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: mpg ~ wt + am
Data: mtcars (Number of observations: 32)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept 37.34 3.18 30.88 43.79 1.00 2340 2513
wt -5.36 0.82 -6.98 -3.68 1.00 2355 2334
am -0.04 1.62 -3.18 3.15 1.00 2474 2639
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 3.17 0.42 2.50 4.18 1.00 2760 2835
Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Note que agora temos valores diferentes para o output de summary()
com robust = TRUE
, mas as colunas são as mesmas. Não se engane, agora temos a mediana (Estimate
) dos coeficientes e erro (sigma
) do modelo junto com o desvio absoluto médio (Est.Error
) e os percentis 5% (l-95%
) e 95% (u-95%
) baseados na mediana e desvio absoluto médio.
Podemos também especificar os percentis desejados no summary()
. Aqui a síntaxe é um pouco diferente da síntaxe do rstanarm
:
summary(brms_fit, prob = 0.9)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: mpg ~ wt + am
Data: mtcars (Number of observations: 32)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-90% CI u-90% CI Rhat Bulk_ESS Tail_ESS
Intercept 37.27 3.21 31.94 42.42 1.00 2340 2513
wt -5.34 0.83 -6.69 -3.98 1.00 2355 2334
am -0.01 1.63 -2.70 2.69 1.00 2474 2639
Family Specific Parameters:
Estimate Est.Error l-90% CI u-90% CI Rhat Bulk_ESS Tail_ESS
sigma 3.21 0.44 2.59 4.02 1.00 2760 2835
Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
R version 4.1.0 (2021-05-18)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 10.16
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods
[7] base
other attached packages:
[1] brms_2.15.0 rstanarm_2.21.1 Rcpp_1.0.6 skimr_2.1.3
[5] readr_1.4.0 readxl_1.3.1 tibble_3.1.2 ggplot2_3.3.3
[9] patchwork_1.1.1 cowplot_1.1.1
loaded via a namespace (and not attached):
[1] backports_1.2.1 systemfonts_1.0.2 plyr_1.8.6
[4] igraph_1.2.6 repr_1.1.3 splines_4.1.0
[7] crosstalk_1.1.1 rstantools_2.1.1 inline_0.3.19
[10] digest_0.6.27 htmltools_0.5.1.1 magick_2.7.2
[13] rsconnect_0.8.18 fansi_0.5.0 magrittr_2.0.1
[16] RcppParallel_5.1.4 matrixStats_0.59.0 xts_0.12.1
[19] prettyunits_1.1.1 colorspace_2.0-1 textshaping_0.3.4
[22] xfun_0.23 dplyr_1.0.6 callr_3.7.0
[25] crayon_1.4.1 jsonlite_1.7.2 lme4_1.1-27
[28] survival_3.2-11 zoo_1.8-9 glue_1.4.2
[31] gtable_0.3.0 V8_3.4.2 pkgbuild_1.2.0
[34] rstan_2.21.2 abind_1.4-5 scales_1.1.1
[37] mvtnorm_1.1-1 DBI_1.1.1 miniUI_0.1.1.1
[40] xtable_1.8-4 stats4_4.1.0 StanHeaders_2.21.0-7
[43] DT_0.18 htmlwidgets_1.5.3 threejs_0.3.3
[46] RColorBrewer_1.1-2 ellipsis_0.3.2 pkgconfig_2.0.3
[49] loo_2.4.1 farver_2.1.0 sass_0.4.0
[52] utf8_1.2.1 tidyselect_1.1.1 labeling_0.4.2
[55] rlang_0.4.11 reshape2_1.4.4 later_1.2.0
[58] munsell_0.5.0 cellranger_1.1.0 tools_4.1.0
[61] cli_2.5.0 generics_0.1.0 ggridges_0.5.3
[64] evaluate_0.14 stringr_1.4.0 fastmap_1.1.0
[67] yaml_2.2.1 ragg_1.1.2 processx_3.5.2
[70] knitr_1.33 purrr_0.3.4 nlme_3.1-152
[73] mime_0.10 projpred_2.0.2 xml2_1.3.2
[76] compiler_4.1.0 bayesplot_1.8.0 shinythemes_1.2.0
[79] rstudioapi_0.13 curl_4.3.1 gamm4_0.2-6
[82] png_0.1-7 bslib_0.2.5.1 stringi_1.6.2
[85] highr_0.9 ps_1.6.0 Brobdingnag_1.2-6
[88] lattice_0.20-44 Matrix_1.3-3 nloptr_1.2.2.2
[91] markdown_1.1 shinyjs_2.0.0 vctrs_0.3.8
[94] pillar_1.6.1 lifecycle_1.0.0 jquerylib_0.1.4
[97] bridgesampling_1.1-2 httpuv_1.6.1 R6_2.5.0
[100] bookdown_0.22 promises_1.2.0.1 gridExtra_2.3
[103] codetools_0.2-18 distill_1.2 boot_1.3-28
[106] colourpicker_1.1.0 MASS_7.3-54 gtools_3.8.2
[109] assertthat_0.2.1 rprojroot_2.0.2 withr_2.4.2
[112] shinystan_2.5.0 mgcv_1.8-35 parallel_4.1.0
[115] hms_1.1.0 grid_4.1.0 tidyr_1.1.3
[118] coda_0.19-4 minqa_1.2.4 rmarkdown_2.8
[121] downlit_0.2.1 shiny_1.6.0 lubridate_1.7.10
[124] base64enc_0.1-3 dygraphs_1.1.1.6
notem que a síntaxe é bem similar à C++ com uma diferença notória que pontos flutuantes double
são real
e o ~
designa uma distribuição probabilística a uma variável↩︎
geralmente chamamos objetos stanreg
que são oriundos das funções de modelos Bayesianos do rstanarm
como fit
.↩︎
geralmente chamamos objetos brmsfit
que são oriundos das funções de modelos Bayesianos do brms
como fit
.↩︎
If you see mistakes or want to suggest changes, please create an issue on the source repository.
Text and figures are licensed under Creative Commons Attribution CC BY-SA 4.0. Source code is available at https://github.com/storopoli/Estatistica-Bayesiana, unless otherwise noted. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".
For attribution, please cite this work as
Storopoli (2021, Aug. 1). Estatística Bayesiana com R e Stan: rstanarm e brms. Retrieved from https://storopoli.github.io/Estatistica-Bayesiana/3-rstanarm.html
BibTeX citation
@misc{storopoli2021priorbayesR, author = {Storopoli, Jose}, title = {Estatística Bayesiana com R e Stan: rstanarm e brms}, url = {https://storopoli.github.io/Estatistica-Bayesiana/3-rstanarm.html}, year = {2021} }