Week 10 Item Response Theory 1

Item response theory models the nonlinear relationship between the examinee’s trait level θi and the response probability Pj(θi) on the items. A few item response functions that are commonly used are:

  • 1PL: Pj(θi)=11+exp[Da(θibj)]
  • 2PL: Pj(θi)=11+exp[Daj(θibj)]
  • 3PL: Pj(θi)=cj+1cj1+exp[Daj(θibj)]

Here:

  • Pj(θi)=P(Yij=1θi) provides the probability of correct response on item j, given ability θi.
  • Yij=0/1 is the response to question j by examinee i
  • θi is the latent trait value (e.g., ability) of examinee i
  • bj: Difficulty (ability required by item)
  • aj: Discrimination (change rate of correct probability as a function of (θibj))
  • cj: Pseudoguessing parameter. Chance of correct response for someone with infinitely low ability.
  • D: Some scaling constant, usually set to 1.7 or 1.

In addition, one common way of fixing the scale of IRT models is:

  • Standardize θ so that μ=0 and σ=1.
  • So, θ is commonly (not always) assumed to follow the standard normal distribution (N(0,1)).
  • Although N(0,1) random variables can range between and , most of the data (>99%) will be between 4 and 4.

In this chapter, students will learn how to plot item characteristic curves and to generate random responses data under item response theory models.

10.1 Item Characteristic Curves (ICC)

10.1.1 Item parameters

The following data set GRE40 contains the item parameters of 40 items following the 3PL model. Therefore, each item has aj,bj,cj parameters.

GRE40 <- read.table("https://raw.githubusercontent.com/sunbeomk/PSYC490/main/GRE40.txt")
head(GRE40)
##   item_ID    a     b    c
## 1       1 0.26 -1.30 0.04
## 2       2 0.40  1.00 0.15
## 3       3 0.43 -2.00 0.14
## 4       4 0.49 -0.60 0.00
## 5       5 0.52 -1.55 0.12
## 6       6 0.55  0.71 0.00

Let’s first see what these parameter values look like.

hist(GRE40$a)

hist(GRE40$b)

hist(GRE40$c)

You can draw multiple plots in a single window by setting the graphical parameters in par() function. Below code will set the graphical parameters such that the subsequent plots are drawn in an 1-by-3 array by rows. That is, we can plot three histograms in a single window.

par(mfrow=c(1,3))
hist(GRE40$a)
hist(GRE40$b)
hist(GRE40$c)

par(mfrow=c(1,1))

Below code chunk will draw the three histograms in a 2-by-2 array, by row.

par(mfrow=c(2,2))
hist(GRE40$a)
hist(GRE40$b)
hist(GRE40$c)
par(mfrow=c(1,1))

10.1.2 Drawing ICC plots

One important way of visualizing IRT models is to draw item characteristic curves (ICC curves). The ICC curve is essentially a curve for an item j that plots the relationship between

  • θ: ability of examinee; and
  • Pj(θ): probability of answering j correctly.

As ability changes, probability of correct response also changes. The ICC shows how it changes. What we want to do next is to draw ICCs for each GRE40 item. Plotting an ICC involves a few steps.

  • Step 1: Create a function for the IRF

  • Step 2: Create a sequence of theta values

  • Step 3: Evaluate Pj at a series of θs

  • Step 4: Plot Pj vs θ as a curve.

10.1.2.1 Step 1: Create a function for the IRF

We need to compute Pj(θ) for a given θ value. We will create an R function that calculates Pj(θ)=P(correct), when θ is the input. The function below, irt_p(), can be used to calculate Pj(θ) for a 3PL item, given specific a,b,c parameter values. Here, we assume D=1.7.

irt_p <- function(theta, a, b, c){   #ability and item parameters as scalars
  p <- c + (1 - c) / (1 + exp(-1.7 * a * (theta - b)))
  
  p
}

Take a look at the function:

  • What are its inputs?
  • What does p calculate?
  • What is the output?

In sum, this function is created, so that it returns Pj(Yij=1θi,aj,bj,cj) by evaluating these values in the 3PL formula: Pj(θi)=cj+1cj1+exp[Daj(θibj)] Let’s now try to plug in a few values.

irt_p(theta = 0, a = 1, b = -.2, c = .25)
## [1] 0.6881429
irt_p(theta = -1, a = 1, b = -.2, c = .25)
## [1] 0.4031802

10.1.2.2 Step 2: Create a sequence of theta values

Drawing an ICC curve involves finding finding Pj(θ) for a variety of θ values. In other words:

  • We want to look at a variety of possible θ values: θ=4,3.9,,.1,0,.1,,3.9,4.
  • For each of these θ values, we calculate Pj(θ).
  • Then we can plot these two in a curve.

We can use the seq() function to create a vector of equally spaced numbers. Specifically, seq(from = m, to = n, by = d) creates a sequence, where it starts from m, ends at n, and each time increases by d. The code chunk below creates a θ sequence that starts at 4, ends at 4, and each time increases by .1.

theta_seq <- seq(from = -4, to = 4, by = .1)
theta_seq
##  [1] -4.0 -3.9 -3.8 -3.7 -3.6
##  [6] -3.5 -3.4 -3.3 -3.2 -3.1
## [11] -3.0 -2.9 -2.8 -2.7 -2.6
## [16] -2.5 -2.4 -2.3 -2.2 -2.1
## [21] -2.0 -1.9 -1.8 -1.7 -1.6
## [26] -1.5 -1.4 -1.3 -1.2 -1.1
## [31] -1.0 -0.9 -0.8 -0.7 -0.6
## [36] -0.5 -0.4 -0.3 -0.2 -0.1
## [41]  0.0  0.1  0.2  0.3  0.4
## [46]  0.5  0.6  0.7  0.8  0.9
## [51]  1.0  1.1  1.2  1.3  1.4
## [56]  1.5  1.6  1.7  1.8  1.9
## [61]  2.0  2.1  2.2  2.3  2.4
## [66]  2.5  2.6  2.7  2.8  2.9
## [71]  3.0  3.1  3.2  3.3  3.4
## [76]  3.5  3.6  3.7  3.8  3.9
## [81]  4.0

10.1.2.3 Step 3: Evaluate Pj at a series of θs

Our next step would be calculating Pj(θi) at each of these θs between 4 and 4. We’ll illustrate this with item 1. Let’s create a for loop to calculate Pj(θi) for each θi[4,4].

p_item1 <- numeric(length(theta_seq))
for (t in 1:length(theta_seq)) {
  p_item1[t] <- irt_p(theta = theta_seq[t],
                   a = GRE40$a[1],
                   b = GRE40$b[1],
                   c = GRE40$c[1])
}

Notice that the question takes tth θ (theta_seq[t]) and item 1’s parameters as input, and outputs the corresponding Pj.

10.1.2.4 Step 4: Plot Pj vs θ as a curve.

Now we have the x axis (θ) and the y axis (Pj), we can draw the ICC curve.

plot(theta_seq, p_item1, 
     type = 'l', 
     ylim = c(0, 1))

Note that type = 'l' tells R that you want to connect the points on the plot with a line (curve).

10.2 Simulating Data Under IRT Models

What we have above define a data generating model. In other words, as long as we have all these information:

  • True θ distribution

  • Item response model

  • Item parameters

We can randomly generate data under an IRT model. That is, we can create a hypothetical data set. This can be convenient for many tasks such as conducting simulation studies. Here, we will generate 1000 subjects’ responses on 40 GRE items. Generating random responses involves several steps.

  • Step 1: Randomly generate ability θs from the standard normal distribution

  • Step 2: Calculate Pj(θi) using the item response function

  • Step 3: Randomly generate Yij from Bernoulli(pij)

10.2.0.1 Step 1: Randomly generate θs

Because we assumed the true abilities θN(0,1), we can use rnorm to randomly generate some standard normal variables. These will be 1000 hypothetical examinees’ true abilties.

set.seed(123)
theta_sim <- rnorm(1000)
hist(theta_sim)

10.2.0.2 Step 2: Calculate Pj(θi)

To simulate Yijs, we need to know each examinees’ correct response probability to each item. Let us create a for loop that calculates:

  • P(correct) for each of the 40 items; for

  • all 1000 examinees.

n_subjects <- 1000
n_items <- 40
pij <- matrix(NA, n_subjects, n_items) # 1000-by-40 matrix
for (i in 1:n_subjects) {
    for (j in 1:n_items) {
      pij[i, j] <- irt_p(theta_sim[i], GRE40$a[j], GRE40$b[j], GRE40$c[j])
    }
}

The outcome vector pij is a 1000 by 40 matrix, where the (i,j) element is the probability of correct response for examinee i on item j.

10.2.0.3 Step 3: Randomly generate Yij from Bernoulli(pij)

One way to do this is using rbinom. For example, for 1st examinee on 1st item:

i <- 1
j <- 1
Y_ij <- rbinom(1, 1, prob = pij[i, j])
Y_ij
## [1] 1

Let’s use a for loop to generate the response matrix.

resp <- matrix(NA, n_subjects, n_items)
for (i in 1:n_subjects) {
  for (j in 1:n_items) {
    resp[i, j] <- rbinom(1, 1, prob = pij[i, j])
  }
}
head(resp)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    1    1    1
## [2,]    1    0    1    0    0
## [3,]    1    0    1    1    1
## [4,]    0    0    1    0    1
## [5,]    1    1    1    1    0
## [6,]    1    0    1    1    1
##      [,6] [,7] [,8] [,9]
## [1,]    0    0    0    0
## [2,]    1    0    0    0
## [3,]    1    0    0    1
## [4,]    1    1    0    1
## [5,]    0    1    1    0
## [6,]    1    1    1    1
##      [,10] [,11] [,12] [,13]
## [1,]     0     1     1     1
## [2,]     1     1     0     1
## [3,]     1     1     1     1
## [4,]     1     1     1     1
## [5,]     1     1     1     1
## [6,]     1     1     1     1
##      [,14] [,15] [,16] [,17]
## [1,]     0     1     1     1
## [2,]     0     1     0     0
## [3,]     1     1     0     1
## [4,]     1     1     1     0
## [5,]     0     1     1     0
## [6,]     1     1     1     1
##      [,18] [,19] [,20] [,21]
## [1,]     0     1     1     0
## [2,]     1     0     0     0
## [3,]     1     1     1     1
## [4,]     1     1     1     1
## [5,]     0     0     1     0
## [6,]     1     1     1     1
##      [,22] [,23] [,24] [,25]
## [1,]     0     0     0     0
## [2,]     1     0     0     1
## [3,]     1     0     1     1
## [4,]     1     0     0     1
## [5,]     1     0     1     1
## [6,]     1     1     0     1
##      [,26] [,27] [,28] [,29]
## [1,]     0     0     1     0
## [2,]     0     0     0     1
## [3,]     1     1     1     1
## [4,]     0     0     1     1
## [5,]     1     1     1     1
## [6,]     1     1     1     1
##      [,30] [,31] [,32] [,33]
## [1,]     0     0     0     0
## [2,]     0     1     0     0
## [3,]     1     1     1     1
## [4,]     0     1     1     1
## [5,]     1     0     1     0
## [6,]     1     1     1     1
##      [,34] [,35] [,36] [,37]
## [1,]     0     1     0     0
## [2,]     0     1     0     1
## [3,]     1     1     0     1
## [4,]     0     1     0     0
## [5,]     1     0     1     1
## [6,]     1     1     0     1
##      [,38] [,39] [,40]
## [1,]     1     0     0
## [2,]     1     0     0
## [3,]     1     0     0
## [4,]     0     0     1
## [5,]     0     0     1
## [6,]     1     0     1

Now, resp is the response matrix we created. In practice, after administering the test, the only thing we get might be resp. That is, we do not know the true θs (theta_sim). In the next chapter, we will use this resp data set to plot empirical ICCs and to estimate individuals’ θs.