---
title: "G-priors, Mixtures and JAGS"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r preliminary}
set.seed(8675309)    #google number and you will not be able get rid of this for the rest of the day
```

Generate some data and center
```{r data and ols}
 X = rnorm(30, 0, 1)
 Xc = X - mean(X)
 Y = Xc* 3 + rnorm(30, 0, 1)
 Yc = Y - mean(Y)
 ols = lm(Y ~ Xc)  
```
 
 
G-prior as augmented data with $Y_0 = 0$ (at mean) and $X_0 = \sqrt{SSX/g}$ to find estimates using OLS

```{r bayes}
 SSX = sum(X^2)
 g = 5

 Xo = sqrt(SSX/g)
 Xo
 Xcomp = c(Xc, Xo)
 Ycomp = c(Yc, 0)
 bols = lm(Ycomp ~ Xcomp -1)
```

Compare Bayes with OLS
```{r}
plot(Xcomp, Ycomp)
points(sqrt(SSX/g), 0, pch=15, col=2)

abline(0, ols$coef[2])
abline(0, bols$coef, lty=3, lwd=3, col=2)


legend(1, -2, legend=c("OLS", "g-prior"), lty=c(1, 3), col=c(1,2))
```

The "prior observation" is depicted in red and appears to be an outlier that is pulling down the regression line towards the point.  Of course $g = 5$ is a completely arbitrary choice!  So what should you use?

Let's fit the model using a Zellner-Siow Cauchy prior as a mixture of normals.   We'll use the package `jags` (you will need to install separately) and the library `R2Jags`

```{r libraries}
library("R2jags")

```

First we need to define a function that represents the model
```{r model}
model = function(){
  
  # sampling model for Y | beta, phi 
  for (i in 1:n) {
      Y[i] ~ dnorm(beta0 + (X[i] - Xbar)*beta, phi)
  }
  # Note that second argument for the normal
  # is a precision in JAGS
  
  # generate beta as a scale mixtures of normals
  # where lambda is the scale parameter that we are mixing over
  beta0 ~ dnorm(0, phi*0.0000001)
  beta ~ dnorm(0, phi*tau*SSX)
  tau  ~ dgamma(.5, .5*n)
  
  # prior for phi to approximate p(phi) = 1/phi
  phi ~ dgamma(.005, .005)
  sigma = pow(phi, -.5)
}
```

In the two normal distributions, the second argument is actually the precision, not the variance as in R.  JAGS does not allow improper priors, so the prior $p(\phi) \propto 1/\phi$ has to be expressed as a limiting Gamma.   The
Although our sampling model is defined with a loop, this is just a way to represent the model.  As `jags` is written in `C++` so this is very efficient.   

To run jags we need to provide the data, we will do this as a list
```{r jags}
data = list(Y=Y, X=X, n =length(Y), SSX=sum(Xc^2), Xbar=mean(X) )

ZSout = jags(data,model=model, inits=NULL,    
             parameters.to.save=c("beta0", "beta", "tau", "sigma"), 
             n.iter=10000)
```

I'm letting JAGS generate the initial values `inits=NULL` and will monitor `beta0`, `beta`, `tau` and `sigma` for posterior inference. The `n.iter` will run for 10,000 iterations, with half used for burnin by default.

Typing the name of the output, will provide a summary of parameters and diagnostics
```{r output}
ZSout
```

IF we want to obtain Credible intervals, we can use the `HPDinterval` function

```{r}
HPDinterval(as.mcmc(ZSout$BUGSoutput$sims.matrix))
```


Let's add the posterior mean to the plot from before.
```{r plots}
plot(X, Y)
points(sqrt(SSX/g), 0, pch=15, col=2)

abline(0, ols$coef[2])
abline(0, bols$coef, lty=3, lwd=3, col=2)
abline(0, ZSout$BUGSoutput$mean$beta, lty=2, lwd=3, col=3)
legend(1, -2, 
       legend=c("OLS", "G-prior", "ZS-prior"), 
       lty=c(1, 3, 2), 
       col=c(1,2,3))

```


The estimate from the Cauchy prior is very close to the MLE, even though it is centered at 0, with the normal prior.  This is due to a property of the Cauchy of having what is called 'bounded influence'.

