# outs[, 4]# distribution looks different if we include 25000 vs ... 1000
Output of the Metropolis algorithm
Need to run until stationarity
Different proposal distributions. Delta as a tradeoff between rate of approach towards the HPD region versus overshooting (like learning rate in gradient descent, etc)
Acceptance rate of between 20 and 50% is good. Control length
2.1 Combining Metropolis and Gibbs algorithms
Since proposal distributions for different parameters can all be different - could use Gibbs for some parameters (where Gibbs is just a special case of Metropolis-Hastings)
A regression model with correlated errors
This section explores running multiple independent MCMC chains and combining the data (which is theoretically OK). The approach in icecore_parallel.R is to take the MH algorithm for analyzing the icecore data and distribute it across multiple cores with parallel::mclapply. That file creates icecore_mcmc which is analyzed here.
[R code]
if (!file.exists('./icecore_mcmc')) {stop("Run icecore_parallel.R first to get MCMC data")}load('./icecore_mcmc')# Should have "outs" now# TODO: put colnames in icecore_parallelcolnames(outs) =c('b1', 'b2', 's2', 'phi')plot(density(outs[seq(1, 80000), 'phi']))
[R code]
plot(density(outs[seq(1, 80000, by =25), 'phi']))
[R code]
outs.df =data.frame(outs)outs.df$iteration =1:nrow(outs.df)message(nrow(outs.df), " samples in ./icecore_mcmc")ggplot(outs.df, aes(x = iteration, y = phi)) +geom_line()
It’s helpful to think about this in terms of the log-odds, i.e., \(\text{log-odds}(\theta_i) = a + \beta x_i\). With an uninformative prior where no interaction between wingspan \(x_i\) and nesting is assumed by default, the prior for \(\beta\) should be centered around 0. To also be uninformative about the prior proportion of nesting birds regardless of wingspan, the prior for \(\alpha\) should be centered around 0 as well, so the prior expectation regardless of \(x_i\) is \(\text{log-odds}(\theta_i) = 0 + 0 x_i = 0\) (thus not favoring nesting or not).
The question is what to use for a prior distribution and how diffuse to make the priors. Priors for \(\alpha\) and \(\beta\) should be symmetric, so normal distributions for both make sense. For an uninformative prior, the variance of these normals should be set high.
If \(\alpha\) is always 0, then as \(x\) moves from 10 to 15, the possible values of \(\beta\) should allow for a change in the log-odds ratio from approximately 0 to 1. Note the log-odds ratio of some sufficiently small number e.g. 1e-5 is -11.5129155 which is roughly 10. Since \(x\) at a minimum is 10, it makes sense to have most of the prior on \(\beta\) in the range \([-10 / 10, 10 / 10] = [-1, 1]\), so the standard deviation of the \(\beta\) prior is set to 0.5 and the variance to 0.25.
Similarly, the standard deviation of the \(\alpha\) prior to be 5 and the variance 25, so that, if \(\beta = 0\), the most of the \(\alpha\) prior falls in the log-odds interval \([-10, 10]\).
library(MASS)inv = solve# In this sampling scheme, when we sample, we keep the values together# ($\theta$). But when I store the values, I split them (ALPHA, BETA).S =10000burnin =5000y = msparrownest[, 1]n =length(y)# Use linear regression format, where column 1 is 1 (for alpha) and column 2 is# the wingspanx =cbind(rep(1, n), msparrownest[, 2])# Start with X^T X but increase until acceptance ratio between 30% - 50%var.prop =7*inv(t(x) %*% x)# Prior parameterspmn.theta =c(0, 0)psd.theta =sqrt(c(25, 0.25))# Where to store valuesALPHA =numeric(S + burnin)BETA =numeric(S + burnin)# Acceptancesacs =0# Initial estimatestheta =c(0, 0)# For calculating likelihood ratiolog.p.y =function(x, y, theta) { exp_term =exp(x %*% theta) p = exp_term / (1+ exp_term)sum(dbinom(y, 1, p, log =TRUE))}p.theta =function(theta) {sum(dnorm(theta, pmn.theta, psd.theta, log =TRUE))}for (s in1:(S + burnin)) { theta.star =mvrnorm(1, theta, var.prop) lhr =log.p.y(x, y, theta.star) +p.theta(theta.star) -log.p.y(x, y, theta) -p.theta(theta)if (log(runif(1)) < lhr) { theta = theta.starif (s > burnin) { acs = acs +1 } } ALPHA[s] = theta[1] BETA[s] = theta[2]}ALPHA = ALPHA[burnin:length(ALPHA)]BETA = BETA[burnin:length(BETA)]message("Acceptance ratio: ", acs / S) # Good to goc(effectiveSize(ALPHA), effectiveSize(BETA))#> var1 var1 #> 1569.255 1549.445
Using the samples of \(\alpha\) and \(\beta\), simply compute a distribution on \(f_{\alpha\beta}(x)\). Confidence intervals can then be constructed around this distribution. However, this needs to be done for many \(x\) values: