# Brms: Prior setting for IRT 2PL ordinal models

Hello all,

I am new to Brms and IRT, and I am trying to understand the theory and modeling of IRT by reading and replicating @paul.buerkner 's great piece https://arxiv.org/pdf/1905.09501.pdf line by line. And, I plan to utilize the instructions for modeling in the paper in my own IRT 2PL ordinal modeling.

What I am confusing is about the prior setting in IRT 2PL ordinal models in the paper. In the model formula of 2PL Graded Response Model (on page 37),

``````R> formula_va_ord_2pl <- bf(
R+ resp ~ 1 + (1 |i| item) + (1 | id),
R+ disc ~ 1 + (1 |i| item)
R+ )
``````

the paper sets the â€śweakly informative priors on hierarchical standard deviationsâ€ť as below.

``````R> prior_va_ord_2pl <-
R+ prior("constant(1)", class = "sd", group = "id") +
R+ prior("normal(0, 3)", class = "sd", group = "item") +
R+ prior("normal(0, 1)", class = "sd", group = "item", dpar = "disc")
``````

As far as I understand, the partial pooling for item and person parameters, the normal prior on those parameters is automatically set and cannot be changed via the prior option, but may change the hyperparameters defining the covariance matrix of the person or item parameters that is on the standard deviations and correlation matrices (as the author explains on page 17).

Question 1. In the above 2PL GRM model, what are the default (or hidden?) normal priors on item and person? Is â€śnormal (0,5)â€ť or â€śnormal (0,3)â€ť set to item and person?
If I look at the manual of Brms (https://cran.r-project.org/web/packages/brms/brms.pdf), the manual says the corresponding standard deviation parameters are restricted
to be non-negative and, by default, have a half student-t prior with 3 degrees of freedom on page 194. If my understanding is correct, in the above model, priors on hyperparameters (standard deviations) are changed into â€śconstant (1)â€ť, â€śnormal (0,3)â€ť, and â€śnormal (0,1)â€ť from â€śdefault half student-t prior with 3 degrees of freedomâ€ť. Still, I am uncertain what are default normal priors on item and person.

Comparing 2PL GRM, if I look into the prior setting for the 2PL binary model on page 27 in the paper, the model formula of 2PL binary as follows

``````R> formula_va_2pl <- bf(
R+ r2 ~ exp(logalpha) * eta,
R+ eta ~ 1 + (1 |i| item) + (1 | id),
R+ logalpha ~ 1 + (1 |i| item),
R+ nl = TRUE
R+ )
``````

with prior setting,

``````R> prior_va_2pl <-
R+ prior("normal(0, 5)", class = "b", nlpar = "eta") +
R+ prior("normal(0, 1)", class = "b", nlpar = "logalpha") +
R+ prior("constant(1)", class = "sd", group = "id", nlpar = "eta") +
R+ prior("normal(0, 3)", class = "sd", group = "item", nlpar = "eta") +
R+ prior("normal(0, 1)", class = "sd", group = "item", nlpar = "logalpha")
``````

Ok, it seems like priors for priors on hyperparameters (standard deviations) are the same with 2PL GRM except for setting â€śnormal (0,5)â€ť and â€śnormal (0,1)â€ť to two parameters â€śetaâ€ť and â€ślogalphaâ€ť.

Question 2. The author says, â€śThe parameter eta represents the sum of person parameter and item easiness, whereas logalpha represents the log discrimination.â€ť If so, is it a correct understanding that â€śnormal (0, 3)â€ť is set to â€śperson parameterâ€ť and â€śitem easiness parameterâ€ť, whereas â€śnormal (0,1)â€ť is set to â€śitem discrimination parameterâ€ť?
And, I am wondering whether I can utilize this 2PL binary formula and prior setting into the modeling of my own 2PL ordinary model. This is because I want to adjust priors for item and person with more flexibility, and I want item discrimination function to be positive for all items using â€ślogalphaâ€ť as the author did.

Thank you for reading my long questions. If anyone who is familiar with this paper and 2PL IRT ordinal modeling can help me, it would be really appreciated.

Hi,

For Question 1:
One way to check on how the priors have been set is to pass your model to `prior_summary()`, this will show you a summary of the priors for each of the parameters in the model.

Itâ€™s possible you want to change the prior for the `Intercept` parameter to something other than the default student_t prior. In and ordinal model with `brms` the `Intercept` parameter(s) refer to the thresholds/cutpoints on the latent variable.

For Question 2:
The nonlinear syntax of `brms` cannot handle the ordinal thresholds in the way that is required when
adding discrimination parameters. So the way you have specified the model is correct as far as I know.

1 Like

Hi JLC,

As you suggested, I used `prior_summary(formula_va_ord_2pl, all=FALSE)` to figure out the parameters in the model and got the result below,

``````                prior class    coef  group resp dpar nlpar bound  source
student_t(3, 0, 2.5) Intercept                                  default
normal(0, 1) Intercept                 disc             default
lkj_corr_cholesky(1)         L                                  default
student_t(3, 0, 2.5)        sd                                  default
student_t(3, 0, 2.5)        sd                 disc             default
constant(1)        sd         id                          user
normal(0, 3)        sd       item                          user
normal(0, 1)        sd       item      disc                user
``````

Since I set `constant(1)`, `normal(0,3)`, and `normal (0,1)` to each hyperparameter (standard deviation) of ID and Item, I can see them in the result.

@paul.buerkner writes in the paper : "the normal prior on item and person parameters is automatically set and cannot be changed via the prior option if we use partial pooling for item and person parameter.â€™â€™

In the above, I can see that `student_t (3, 0, 2.5)` is set to class `Intercept` , and `normal (0, 1)` is set to class `Intercept` along with `dpar (distributional parameter)` as default. Given this, is it a correct understanding that "the normal prior `normal (0, 1)` on item and `student_t (3, 0, 2.5) ` on person parameters is automatically setâ€™â€™?

Yes, they are set automatically, but Iâ€™ve been able to change all of the available priors.

If you try something like:

``````prior("normal(0,3)", class = "Intercept") +
prior("normal(0,3)", class = "sd", group = "id") +
prior("normal(0,3)", class = "sd", group = "item") +
prior("normal(0,3)", class = "Intercept", dpar = "disc") +
prior("normal(0,3)", class = "sd", dpar = "disc") +
prior("normal(0,3)", class = "sd")
``````

Then you can fit an empty model by passing `empty = TRUE` to your `brm` call, so it will fit immediately. If you then call `prior_summary()` you should see all the `Intercept` and `sd` priors set to â€śnormal(0,3)â€ť.

1 Like

Great, it works now! Thank you so much.