That makes sense other than that I wouldn't use the variable "x" for
a parameter --- it violate's Andrew's conventions that "x" is for unmodeled
data, "y" for data, and greek letters for parameters.
Then you need to fix the location and scale of mu for identifiability --- the
model you sent uses normal(0,0.001) in JAGS, which is equivalent to normal(0,sqrt(1000))
in Stan. I'd just use normal(0,1) to make sure the scale of sigma lined up properly.
the numbers easier to scan --- the scale doesn't matter (except in its interaction
with the scale of sigma).
I'd also be inclined to build a hierarchical model for the sigma[j], but that's
another issue.
> Here, i is in [1,N] and j is in [1:Nstaff]. This is then compared to actual rankings for each person, y[1:N, 1:Nstaff]. How do you deal with the fact that some staff members are not observed? For the jth staff member, the y vector has a N rows. In my example, each person only provides X[j] < N rows. You can certainly put the [1:X[j]] rankings in y[1:N,j] in the correct positions, and (in JAGS) put NA values in the other positions. But these rankings will max out at X[j] < N. Doesn't this screw the algorithm up?
The model you sent me is wrong in the text that the rank needs to be something
like
y[j,] <- rank(x[j,])
You can't call rank(x[j,i]) because x[j,i] is a scalar!
I also don't think their JAGS code is going to be efficient because
they're using the dinterval trick for rejection, when they could just
use truncation a la Albert-Chib.
All you need to do for your model where not every individual i
is observed is to trim the implicit rankings down to the ones you observe:
y[j,] <- trim(y[j,],rank(x[j,]));
where the "trim" function just chops the result down to the individuals
for which you have observations, which are just the ones in y[j,].
(I know "trim" isn't a built-in function in anyone's system.)
The hard part is going to be coding it in either Stan or JAGS.
If all the y[i,] are the same size, it's easy. If everything was observed
in Stan, this model's trivial to code:
data {
int<lower=0> I; // number of items being ranked
int<lower=0> J; // number of raters
int<lower=1,upper=I> y[J,I]; // ranks for rater j
}
parameters {
real mu[I]; // true latent positions
real<lower=0,upper=20> sigma[J]; // accuracy of rater j
ordered[I] x[J]; // positions assigned by rater j
}
model {
mu ~ normal(0,1000);
for (j in 1:J)
for (i in 1:I)
x[j,i] ~ normal(mu[i],sigma[j]);
}
The ordered[I] data type is for I ordered values. This is
the appropriate constraint on the underlying values (though it
makes lower better --- you'd have to reverse to get it the other
way around because ordered sorts in ascending order).
I think this is much simpler than you see in the JAGS encoding in the
referenced PDF (though as I said, I don't think this is the best JAGS
encoding --- the alternative would involve truncated normal sampling
statements in JAGS).
If each rater rates the same number of items, say K, then all you
need to do to code in Stan is to add a variable for K, replace y[J,I] with
y[J,K] and ordered[I] with ordered[K] in the declarations and then loop
from 1:K rather than 1:I in the model. The truncations you'd need in
JAGS (or rejections the way the example was coded in the PDF) automatically
get handled by the ordered vector data type.
If not every rater rates the same number of items, then the model's
going to be difficult to code because neither Stan nor JAGS supports
ragged arrays. And Stan doesn't support ragged constraints. So you'd
need to either (a) break the data down ahead of time into groups with
the same number of observations, then proceed as above [although it's
hard to make general], or (b) bite the bullet and code up ragged data
structures (using the trick described in the manual for LDA or naive
Bayes) and define the transforms and Jacobians yourself (they're simple
for the ordered vectors --- see the last chapter of the manual on
variable transforms).
- Bob