One parameter logistic model,how to estimate the item discrimination for all items?

#1

I am thinking about estimating the item discrimination parameter for the one parameter logistic model, not the Rasch model. The one logistic model is scaled on the person/theta scale, while the Rasch model is scaled on the item scale for model identification. The one parameter logistic model also has a common item discrimination parameter, which is not necessarily 1 as assumed by the Rasch model. I wonder how could I set an equality constraint on the item discrimination parameter across all items in Stan. In the end, I want to fit a hiearchical 1PL model with Stan. Any help would be highly appreciated!

The following is the 2PL code from Dr. Daniel Fur (https://mc-stan.org/users/documentation/case-studies/tutorial_twopl.html#twoplstancode). How could I set a equality constraint based on his code as attached below:

data {
  int<lower=1> I;               // # questions
  int<lower=1> J;               // # persons
  int<lower=1> N;               // # observations
  int<lower=1, upper=I> ii[N];  // question for n
  int<lower=1, upper=J> jj[N];  // person for n
  int<lower=0, upper=1> y[N];   // correctness for n
}
parameters {
  vector<lower=0>[I] alpha;     // discrimination for item i
  vector[I] beta;               // difficulty for item i
  vector[J] theta;              // ability for person j
}
model {
  vector[N] eta;
  alpha ~ lognormal(0.5,1);
  beta ~ normal(0,10);
  theta ~ normal(0,1);
  for (n in 1:N)
    eta[n] <- alpha[ii[n]] * (theta[jj[n]] - beta[ii[n]]);
  y ~ bernoulli_logit(eta);
}

0 Likes

#2

If you just want all items to have the same discrimination parameter, just replace vector<lower = 0>[I] alpha; with real<lower = 0> alpha; and replace alpha[ii[n]] with alpha.

You can identify either of theta or beta and make the other one hierarchical. We often try to reparameterize so that rather than alpha[i] * (theta[j] - beta[i]), we use alpha[i] * theta[j] - gamma[i], where now gamma[i] does the job of alpha[i] * beta[i].

1 Like

#3

Thank you so much for your quick response, Dr Carpenter. Does the following code look correct to you if I am going to fit a multilevel 1PL model based on the multilevel 2PL model I had:

data {
int<lower=1> N; // number of students
int<lower=1> NFam; // number of item families
int<lower=1> NObs; // number of observations
int<lower=1,upper=N> ID_Stu[NObs]; // student id
int<lower=1,upper=NFam> ID_Fam[NObs]; // item family id
int<lower=0,upper=1> Resp[NObs];// resp
int NIC; //number of item clones, fixed in this syntax
int<lower=1,upper=NIC> ID_Clone[NObs];//item clone id
}
parameters {
real theta[N]; // ability
real<lower=0, upper=5> alpha; // discrimination
real mu[NFam]; // difficulty
real<lower=0> sigma[NFam]; // random variation
vector[NIC] beta_z[NFam]; //*beta reparameterization;
}

transformed parameters {
vector[NIC] beta[NFam]; // item clone difficulties
for(i in 1:NFam) {
beta[i]= mu[i] + beta_z[i] * sigma[i];
}
}

model {
row_vector[NObs] alpha_local; // temporary parameters
row_vector[NObs] diff_local;
int fam_n;
theta~normal(0,1); // priors
mu~normal(0,10);
sigma~normal(0,1);
//alpha~uniform(0,5);
for(i in 1:NFam){
beta_z[i] ~ normal(0, 1);
//beta[i] ~normal(mu[i], sigma[i]);
}
for (n in 1:NObs) {
fam_n <- ID_Fam[n];
alpha_local[n] <- alpha;
diff_local[n] <- theta[ID_Stu[n]] - beta[fam_n, ID_Clone[n]];
}
Resp~bernoulli_logit(alpha_local .* diff_local);
}

I did beta reparameterization because I find it runs much faster than the one without reparameterization, thought both model converged. Thank you so much.

0 Likes