The problem with your coding of the model is that you need to use
constraints to guarantee your parameters are within bounds. You have:
parameters {
...
vector[n_item] guessing; // guessing for item
...
model {
...
y[k] ~ bernoulli(guessing[k]*ones+(1-guessing[k])*p[k]);
...
}
You need to declare
vector<lower=0,upper=1>[n_item] guessing;
because guessing[i] has to be in the interval [0,1]. In Stan, if
a variable is constrained in the log probability function (say by being
drawn from a beta or being part of a bernoulli parameter)n, then you need
to declare it with those constraints.
And rather than taking log_alpha, you can just declare
vector<lower=0>[n_item] alpha; // discrimination for item
and then give it a lognormal distribution if you want. Or you can
do it the way you did it.
You probably don't need to constrain both beta and theta to be normal(0,1)
to deal with the additive and multiplicative invariances. Just taking one
to be normal(0,1) solves additive invariance by setting the location of that
parameter to be centered on 0 and setting its scale to be 1. The other one
could be normal(0,5) or normal(0,10).
Unlike some of our other distributions, there's really no benefit
speed-wise to vectorizing the bernoulli because there aren't any computations
that can be shared across the vectorized instances. So it'd probably be
clearer to just write it as your version two (and I'd suggest always using the
same variables to loop over the same indices):
for (i in 1:n_item)
for (j in 1:n_student)
y[i,j] ~ bernoulli(guessing[i] + (1 - guessing[i]) * inv_logit(alpha[i] * (theta[j] - beta[i])));
Because of the alpha[i] * beta[i] term, it can be more well behaved to reparameterize
to
inv_logit(gamma[i] * theta[i] - xi[i])
and then recover the alpha[i] and beta[i] with some algebra from the gamma[i] and xi[i].
- Bob
>
stan-users+...@googlegroups.com <javascript:>.
> > For more options, visit
https://groups.google.com/groups/opt_out <
https://groups.google.com/groups/opt_out>.