---
title: "Post-hoc MCMC with glmmTMB"
author: "Ben Bolker"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Post-hoc MCMC with glmmTMB}
%\VignetteEngine{knitr::rmarkdown}
\usepackage[utf8]{inputenc}
---
One commonly requested feature is to be able to run a *post hoc* Markov chain Monte Carlo analysis based on the results of a frequentist fit. This is often a reasonable shortcut for computing confidence intervals and p-values that allow for finite-sized samples rather than relying on asymptotic sampling distributions. This vignette shows an example of such an analysis. Some caveats:
- when using such a "pseudo-Bayesian" approach, be aware that using a scaled likelihood (implicit, improper priors) can often cause problems, especially when the model is poorly constrained by the data
- in particular, models with poorly constrained random effects (singular or nearly singular) are likely to give bad results
- as shown below, even models that are well-behaved for frequentist fitting may need stronger priors to give well-behaved MCMC results
- as with all MCMC analysis, it is the *user's responsibility to check for proper mixing and convergence of the chains* before drawing conclusions
- the first MCMC sampler illustrated below is simple (Metropolis with a multivariate normal candidate distribution). Users who want to do MCMC sampling on a regular basis should consider the [tmbstan package](https://CRAN.R-project.org/package=tmbstan), which does much more efficient hybrid/Hamiltonian Monte Carlo sampling.
```{r knitr_setup, include=FALSE, message=FALSE}
library(knitr)
opts_chunk$set(echo = TRUE,
eval = identical(Sys.getenv("NOT_CRAN"), "true"))
rc <- knitr::read_chunk
rc(system.file("vignette_data","mcmc.R",package="glmmTMB"))
```
Load packages:
```{r libs,message=FALSE}
library(glmmTMB)
library(coda) ## MCMC utilities
library(reshape2) ## for melt()
## graphics
library(lattice)
library(ggplot2); theme_set(theme_bw())
```
Fit basic model:
```{r fit1}
```
Set up for MCMC: define scaled log-posterior function (in this case the log-likelihood function); extract coefficients and variance-covariance matrices as starting points.
```{r setup}
```
This is a basic block Metropolis sampler, based on Florian Hartig's code [here](https://theoreticalecology.wordpress.com/2010/09/17/metropolis-hastings-mcmc-in-r/).
```{r run_MCMC}
```
Run the chain:
```{r do_run_MCMC,eval=FALSE}
```
```{r load_MCMC, echo=FALSE, eval=TRUE}
L <- load(system.file("vignette_data", "mcmc.rda", package="glmmTMB"))
```
(running this chain takes `r round(t1["elapsed"],1)` seconds)
Add more informative names and transform correlation parameter (see vignette on covariance structures and parameters):
```{r add_names}
colnames(m1) <- c(names(fixef(fm1)[[1]]),
"log(sigma)",
c("log(sd_Intercept)","log(sd_Days)","cor"))
m1[,"cor"] <- sapply(m1[,"cor"], get_cor)
```
```{r traceplot,fig.width=7}
xyplot(m1,layout=c(2,3),asp="fill")
```
The trace plots are poor, especially for the correlation; the effective sample size backs this up, as would any other diagnostics we did.
```{r effsize}
print(effectiveSize(m1),digits=3)
```
**In a real analysis we would stop and fix the mixing/convergence problems before proceeding**; for this simple sampler, some of our choices would be (1) simply run the chain for longer; (2) tune the candidate distribution (e.g. by using `tune` to scale some parameters, or perhaps by switching to a multivariate Student t distribution [see the `mvtnorm` package]); (3) add regularizing priors.
Ignoring the problems and proceeding, we can compute column-wise quantiles or highest posterior density intervals (`coda::HPDinterval`) to get confidence intervals.
Plotting posterior distributions, omitting
the intercept because it's on a very different scale.
```{r violins,echo=FALSE}
ggplot(reshape2::melt(as.matrix(m1[,-1])),aes(x=Var2,y=value))+
geom_violin(fill="gray")+coord_flip()+labs(x="")
```
## tmbstan
The `tmbstan` package allows direct, simple access to a hybrid/Hamiltonian Monte Carlo algorithm for sampling from a TMB object; the `$obj` component of a `glmmTMB` fit is such an object. (To run this example you'll need to install the `tmbstan` package and its dependencies.)
```{r do_tmbstan,eval=FALSE}
```
(running this command, which creates 4 chains, takes `r round(t2["elapsed"],1)` seconds)
However, there are many indications (warning messages; trace plots) that the correlation parameter needs to be given a more informative prior. (In the plot below, the correlation parameter is shown on its unconstrained scale; the actual correlation would be $\theta_3/\sqrt{1+\theta_3^2}$.)
```{r show_traceplot,echo=FALSE,fig.width=8,fig.height=5}
library(png)
library(grid)
img <- readPNG(system.file("vignette_data","tmbstan_traceplot.png",package="glmmTMB"))
grid.raster(img)
```
## To do
- solve mixing for cor parameter
- more complex example - e.g. `Owls`