If you have colleagues having trouble fitting models in Stan,
please send them to our users list --- we're happy to help.
And no bother at all. Yours are good examples for us to think
about because we have been gearing up to do some teaching
on Stan ourselves (when we create teaching materials, we'll
make them available).
For Gibbs sampling, it's easy to sample from p(a1|a2,sigma)
and from p(a2|a1,sigma). You almost certainly won't get as much drift
from the the initial values for a1 and a2 in the no-prior model.
You should get infinite drift, so Stan's not going far enough
either. There's an improper prior, so all bets are off on MCMC
working at all!
The key to understanding what's going on in Stan is to
think about the posterior geometry.
In the example with no priors, you get a ridge in the posterior
where both parameters can run off long distances in opposite directions
without changing the log probability. Now with initial momenta being
giving randomly, you won't quite run off in opposite directions, but
it'll be close because we use the gradient. The result is that you
often won't get a u-turn at all and the sampler will apply 1000
leapfrog iterations (tree depth = 10).
Tree depth is currently not printed along with the usual print() output
in R and is hard to fish out (see the stanfit-class object). So
I've just created a feature request to dump these out with the other
diagnostics the way that CmdStan does:
https://github.com/stan-dev/rstan/issues/45
You can also see how far the parameters run by inspecting the traceplots
or the posterior intervals (see below).
In the example with priors, when a1 and a2 try to run off
in opposite directions, the prior turns them around. They still get
pretty far, though, because the prior's weak. Tighter priors would
speed things up even further.
I'm working on the next edition of the manual right now and I'm going
to add a chapter on identifiability and use your example (and cite
you, of course). We need to say more on identifiability anyway, and
this is a good place to start because it's such a nice clean example.
Here are the models I used (I dropped the prior for sigma --- it doesn't
suffer from the same problem because it's identified in the posterior).
noprior.stan
-----------------------------
data {
int N;
real y[N];
}
parameters {
real a1;
real a2;
real<lower=0> sigma;
}
model {
y ~ normal(a1 + a2, sigma);
}
generated quantities {
real a;
a <- a1 + a2;
}
weakprior.stan
-------------------------------
data {
int N;
real y[N];
}
parameters {
real a1;
real a2;
real<lower=0> sigma;
}
model {
a1 ~ normal(0,10);
a2 ~ normal(0,10);
y ~ normal(a1 + a2 , sigma );
}
generated quantities {
real a;
a <- a1 + a2;
}
sim.R
--------------------------------------
library('rstan');
N <- 100;
y <- rnorm(N);
fit_weak <- stan('weakprior.stan', data=c("N","y"), seed=12345);
fit_no <- stan('noprior.stan', data=c("N","y"), seed=12345);
print(fit_weak);
print(fit_no);
Timing
----------------------------------
fit_weak: 1.0s per chain
fit_no: 6.5s per chain
Fits:
weakprior.stan
--------------------------------------------
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
a1 -0.5 0.2 7.1 -14.0 -5.2 -0.5 4.3 12.9 864 1
a2 0.5 0.2 7.1 -13.0 -4.4 0.4 5.1 14.0 864 1
sigma 1.2 0.0 0.1 1.0 1.1 1.2 1.3 1.4 1083 1
a 0.0 0.0 0.1 -0.3 -0.1 0.0 0.1 0.2 3458 1
lp__ -67.3 0.0 1.2 -70.5 -67.8 -67.0 -66.4 -65.9 818 1
noprior.stan
--------------------------------------------------
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
a1 -1888.8 483.6 938.1 -3609.5 -2522.1 -1971.5 -1327.2 290.9 4 1.6
a2 1888.8 483.6 938.1 -291.1 1327.0 1971.3 2522.1 3609.5 4 1.6
sigma 1.2 0.0 0.1 1.1 1.2 1.2 1.3 1.4 40 1.1
a 0.0 0.0 0.1 -0.3 -0.1 0.0 0.1 0.2 3213 1.0
lp__ -66.9 0.1 1.1 -69.9 -67.2 -66.6 -66.1 -65.8 59 1.1
So you see that both get reasonable Rhat and n_eff for a. weakprior.stan gets
reasonable n_eff for sigma, but norprior.stan doesn't. Also look at those intervals
on a1 and a2 in noprior; those are highly dependent on initialization.
The big difference is that weakprior.stan actually identifies a1 and a2! If
you ran a really long time, you should see them both take posterior mean of 0.
As is, you can see a very high posterior sd for their estimates and hence
a fairly high MCSE (which is estimated by posterior sd / sqrt(n_eff)).
Here's what happens at iter=100000:
Inference for Stan model: weakprior.
4 chains, each with iter=1e+05; warmup=50000; thin=1;
post-warmup draws per chain=50000, total post-warmup draws=2e+05.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
a1 0.0 0 7.0 -13.8 -4.8 0.0 4.7 13.8 38150 1
a2 0.0 0 7.0 -13.9 -4.8 0.0 4.7 13.8 38144 1
sigma 1.2 0 0.1 1.0 1.1 1.2 1.2 1.4 50701 1
a 0.0 0 0.1 -0.3 -0.1 0.0 0.1 0.2 177514 1
lp__ -67.3 0 1.2 -70.5 -67.9 -67.0 -66.4 -65.9 43360 1
Tighter priors would, of course, continue to improve behavior for weak_prior.
- Bob