Chapter 6 Markov Chain Monte Carlo Methods
6.1 Introduction to Discrete Markov Chains
Illustration of sampling from a random walk distribution.
<- matrix(c(.5, .5, 0, 0, 0, 0,
P 25, .5, .25, 0, 0, 0,
.0, .25, .5, .25, 0, 0,
0, 0, .25, .5, .25, 0,
0, 0, 0, .25, .5, .25,
0, 0, 0, 0, .5, .5),
nrow=6, ncol=6, byrow=TRUE)
P
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.50 0.50 0.00 0.00 0.00 0.00
## [2,] 0.25 0.50 0.25 0.00 0.00 0.00
## [3,] 0.00 0.25 0.50 0.25 0.00 0.00
## [4,] 0.00 0.00 0.25 0.50 0.25 0.00
## [5,] 0.00 0.00 0.00 0.25 0.50 0.25
## [6,] 0.00 0.00 0.00 0.00 0.50 0.50
<- array(0, c(50000, 1))
s 1] <- 3
s[for (j in 2:50000){
<- sample(1:6, size=1, prob=P[s[j - 1],])
s[j] }
<- c(500, 2000, 8000, 50000)
m for (i in 1:4){
print(table(s[1:m[i]]) / m[i])
}
##
## 1 2 3 4 5 6
## 0.102 0.224 0.208 0.186 0.236 0.044
##
## 1 2 3 4 5 6
## 0.1075 0.2115 0.2110 0.2180 0.1765 0.0755
##
## 1 2 3 4 5 6
## 0.095250 0.189875 0.219000 0.215875 0.193875 0.086125
##
## 1 2 3 4 5 6
## 0.09686 0.19760 0.20490 0.20618 0.19830 0.09616
<- matrix(c(.1, .2, .2, .2, .2, .1),
w nrow=1, ncol=6)
%*% P w
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.1 0.2 0.2 0.2 0.2 0.1
6.2 Learning about a Normal Population from Grouped Data
Have normally distributed data where the data is observed in grouped form. Consider the posterior of \((\mu, \log \sigma)\).
<- list(int.lo=c(-Inf, seq(66, 74, by=2)),
d int.hi=c(seq(66, 74, by=2), Inf),
f=c(14, 30, 49, 70, 33, 15))
<- c(rep(65,14), rep(67,30), rep(69,49),
y rep(71,70), rep(73,33), rep(75,15))
mean(y)
## [1] 70.16588
log(sd(y))
## [1] 0.9504117
First obtain normal approximation to posterior.
<- c(70, 1)
start <- laplace(groupeddatapost, start, d)
fit fit
## $mode
## [1] 70.169880 0.973644
##
## $var
## [,1] [,2]
## [1,] 3.534713e-02 3.520776e-05
## [2,] 3.520776e-05 3.146470e-03
##
## $int
## [1] -350.6305
##
## $converge
## [1] TRUE
Now use a Metropolis (random walk) MCMC algorithm.
<- sqrt(diag(fit$var))
modal.sds <- list(var=fit$var, scale=2)
proposal <- rwmetrop(groupeddatapost,
fit2
proposal,
start,10000, d)
$accept fit2
## [1] 0.2908
<- apply(fit2$par, 2, mean)
post.means <- apply(fit2$par, 2, sd)
post.sds cbind(c(fit$mode), modal.sds)
## modal.sds
## [1,] 70.169880 0.18800834
## [2,] 0.973644 0.05609341
cbind(post.means, post.sds)
## post.means post.sds
## [1,] 70.1636783 0.18672292
## [2,] 0.9811132 0.05767941
mycontour(groupeddatapost,
c(69, 71, .6, 1.3), d,
xlab="mu",ylab="log sigma")
points(fit2$par[5001:10000, 1],
$par[5001:10000, 2]) fit2
6.3 Example of Output Analysis
Illustrate MCMC diagnositics for different Metropolis chains with different proposal widths.
<- list(int.lo=c(-Inf, seq(66, 74, by=2)),
d int.hi=c(seq(66, 74, by=2), Inf),
f=c(14, 30, 49, 70, 33, 15))
library(coda)
library(lattice)
<- c(70,1)
start <- laplace(groupeddatapost, start, d) fit
<- c(65,1)
start <- list(var=fit$var, scale=0.2)
proposal <- rwmetrop(groupeddatapost,
bayesfit
proposal,
start,10000, d)
dimnames(bayesfit$par)[[2]] <- c("mu", "log sigma")
xyplot(mcmc(bayesfit$par[-c(1:2000), ]),
col="black")
par(mfrow=c(2, 1))
autocorr.plot(mcmc(bayesfit$par[-c(1:2000), ]),
auto.layout=FALSE)
summary(mcmc(bayesfit$par[-c(1:2000), ]))
##
## Iterations = 1:8000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 8000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## mu 70.1880 0.19752 0.0022083 0.025874
## log sigma 0.9709 0.05422 0.0006062 0.006305
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## mu 69.8124 70.0563 70.1806 70.31 70.588
## log sigma 0.8628 0.9342 0.9723 1.01 1.071
batchSE(mcmc(bayesfit$par[-c(1:2000), ]),
batchSize=50)
## mu log sigma
## 0.013983542 0.003739656
<- c(70,1)
start <- list(var=fit$var, scale=2.0)
proposal <- rwmetrop(groupeddatapost,
bayesfit
proposal,
start,10000, d)
dimnames(bayesfit$par)[[2]] <- c("mu", "log sigma")
<- mcmc(bayesfit$par[-c(1:2000), ])
sim.parameters xyplot(mcmc(bayesfit$par[-c(1:2000), ]),
col="black")
par(mfrow=c(2,1))
autocorr.plot(sim.parameters,auto.layout=FALSE)
summary(sim.parameters)
##
## Iterations = 1:8000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 8000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## mu 70.165 0.18467 0.0020646 0.005728
## log sigma 0.982 0.05744 0.0006422 0.001770
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## mu 69.8097 70.0346 70.1650 70.289 70.542
## log sigma 0.8715 0.9416 0.9817 1.021 1.101
batchSE(sim.parameters, batchSize=50)
## mu log sigma
## 0.005387819 0.001751675
6.4 Modeling Data with Cauchy Errors
Assuming data that is sampled from a Cauchy density with a noninformative prior placed on the location and scale parameters.
mean(darwin$difference)
## [1] 21.66667
log(sd(darwin$difference))
## [1] 3.65253
First illustrate normal approximation.
laplace(cauchyerrorpost,
c(21.6, 3.6),
$difference) darwin
## $mode
## [1] 24.701745 2.772619
##
## $var
## [,1] [,2]
## [1,] 34.9600525 0.3672899
## [2,] 0.3672899 0.1378279
##
## $int
## [1] -73.2404
##
## $converge
## [1] TRUE
laplace(cauchyerrorpost,
1 * c(21.6,3.6),
.$difference)$mode darwin
## [1] 24.698151 2.772345
c(24.7 - 4 * sqrt(34.96), 24.7 + 4 * sqrt(34.96))
## [1] 1.049207 48.350793
c(2.77 - 4 * sqrt(.138), 2.77 + 4 * sqrt(.138))
## [1] 1.284066 4.255934
mycontour(cauchyerrorpost,
c(-10, 60, 1, 4.5),
$difference,
darwinxlab="mu", ylab="log sigma")
<- laplace(cauchyerrorpost,
fitlaplace c(21.6, 3.6),
$difference) darwin
mycontour(lbinorm,
c(-10, 60, 1, 4.5),
list(m=fitlaplace$mode,
v=fitlaplace$var),
xlab="mu",ylab="log sigma")
Next illustrate random walk Metropolis.
<- list(var=fitlaplace$var, scale=2.5)
proposal <- c(20, 3)
start <- 1000
m <- rwmetrop(cauchyerrorpost, proposal,
s $difference) start, m, darwin
mycontour(cauchyerrorpost,
c(-10, 60, 1, 4.5),
$difference,
darwinxlab="mu", ylab="log sigma")
points(s$par[,1], s$par[,2])
<- simcontour(cauchyerrorpost,
fitgrid c(-10,60,1,4.5),
$difference,
darwin50000)
<- list(var=fitlaplace$var,
proposal scale=2.5)
=c(20, 3)
start=rwmetrop(cauchyerrorpost,
fitrw
proposal,
start,50000,
$difference) darwin
Illustrate metropolis-hastings independence chain.
<- list(var=fitlaplace$var,
proposal2 mu=t(fitlaplace$mode))
<- indepmetrop(cauchyerrorpost,
fitindep
proposal2,
start,50000,
$difference) darwin
Illustrate metropolis-within-Gibbs.
<- gibbs(cauchyerrorpost,
fitgibbs
start,50000,
c(12,.75),
$difference) darwin
apply(fitrw$par,2,mean)
## [1] 25.696204 2.841003
apply(fitrw$par,2,sd)
## [1] 7.1026378 0.3778886
6.5 Analysis of the Stanford Heart Transplant Data
Using a Pareto model to analyze heart transplant data.
Laplace fit.
<- c(0, 3, -1)
start <- laplace(transplantpost,
laplacefit
start, stanfordheart) laplacefit
## $mode
## [1] -0.09210954 3.38385249 -0.72334008
##
## $var
## [,1] [,2] [,3]
## [1,] 0.172788525 -0.009282308 -0.04995160
## [2,] -0.009282308 0.214737054 0.09301323
## [3,] -0.049951602 0.093013230 0.06891796
##
## $int
## [1] -376.2504
##
## $converge
## [1] TRUE
Random walk metropolis.
<- list(var=laplacefit$var, scale=2)
proposal <- rwmetrop(transplantpost,
s
proposal, 10000, stanfordheart)
start, $accept s
## [1] 0.1893
par(mfrow=c(2,2))
<- exp(s$par[,1])
tau plot(density(tau), main="TAU")
<- exp(s$par[,2])
lambda plot(density(lambda), main="LAMBDA")
<- exp(s$par[,3])
p plot(density(p), main="P")
apply(exp(s$par), 2, quantile, c(.05, .5, .95))
## [,1] [,2] [,3]
## 5% 0.4880657 13.43615 0.3149892
## 50% 0.9422897 29.55993 0.4807512
## 95% 1.9776292 64.32047 0.7666747
par(mfrow=c(1, 1))
<- seq(1, 240)
t <- 0*t
p5 <- 0 * t
p50 <- 0 * t
p95 for (j in 1:240){
<- (lambda / (lambda + t[j])) ^ p
S <- quantile(S, c(.05, .5, .95))
q <- q[1]
p5[j] <- q[2]
p50[j] <- q[3]
p95[j] }
Estimating a patient’s survival curve.
plot(t, p50, type="l",
ylim=c(0,1),
ylab="Prob(Survival)",
xlab="time")
lines(t, p5, lty=2)
lines(t, p95, lty=2)