The Rasch model

Module: Item response theory
Tranche: core (a first course)
Before this: Where CTT breaks: toward item response models
Builds toward: From the 1PL to the 4PL · What is an item? Explanatory item response models · Scale properties: is the scale equal-interval? · Competitions and paired comparisons: Bradley-Terry and Elo · Rater models: many-facet Rasch and beyond · Nonparametric IRT: Mokken scaling
Starts threads: The sum score is sufficient under the Rasch model (→ From the 1PL to the 4PL · Estimating abilities: MLE and EAP · Models for polytomous responses · Differential item functioning · Latent classes and cognitive diagnosis · Scale properties: is the scale equal-interval? · Rater models: many-facet Rasch and beyond · Mixture models: when respondents differ in kind · Person fit: does a respondent’s pattern fit the model?); Item comparisons don’t depend on who took the items (→ From the 1PL to the 4PL · Parameter invariance · Scale properties: is the scale equal-interval? · Nonparametric IRT: Mokken scaling · Mixture models: when respondents differ in kind); Only θ − b is identified; the scale has no origin (→ Linking and equating · Scale properties: is the scale equal-interval?); Conditioning on the sum score removes θ (→ Estimating item parameters: JML and EM · Model fit and out-of-sample prediction · Parameter invariance · Person fit: does a respondent’s pattern fit the model?); Misfit as overfit or underfit (outfit and infit) (→ Model fit and out-of-sample prediction · Item banks and adaptive testing · Scale properties: is the scale equal-interval? · Mixture models: when respondents differ in kind · Person fit: does a respondent’s pattern fit the model?); Responses are independent given θ (→ Dimensionality and multidimensional IRT · What is an item? Explanatory item response models · Unfolding models · Rater models: many-facet Rasch and beyond · Nonparametric IRT: Mokken scaling)
Picks up threads: Chess item Y15: Elo barely predicts it (from The likelihood and logistic regression); The sum score contains the item (from Where CTT breaks: toward item response models); Item curves rise with the sum score (monotonicity) (from Where CTT breaks: toward item response models); The sum score depends on which items were taken (from Where CTT breaks: toward item response models)
IRW tables: chess_lnirt, wirs
From EDUC 252: slides c3; code c3/rasch0.R, c3/rasch1.R, c3/rasch2.R
Status: draft
Authorship: Written largely by Claude (Anthropic), from Ben Domingue’s EDUC 252 materials and under Ben’s direction. Ben reviews each lesson before it is marked done.
Comments: open an issue on GitHub about this lesson.

What this is for

Sum scores treat every item as interchangeable: a correct answer is worth one point no matter which item it came from. Yet items differ, and the chance of getting any one of them right does not rise in a straight line with the sum score (Where CTT breaks). What is the simplest model that takes items seriously? The Rasch model (Rasch, 1960), with one parameter per person and one per item, on the same scale. That parsimony buys some unusual properties, chief among them that the sum score is all the model needs to know about a person, and it makes demands of the data. This lesson is about both.

Recall from Where CTT breaks: against the sum score, the proportion correct on each item of a mathematics test rose in an S-shape, at its own place and rate, and a logistic regression on the sum score described each curve. But the sum score is an observed stand-in: it contains the item, and it depends on which items were taken.

Goals

By the end of this lesson you should be able to:

  • write down the Rasch model and say what \(\theta\) and \(b\) mean;
  • read an item characteristic curve and a Wright map;
  • explain why the scale has no natural origin (and what software does about it);
  • explain why the sum score is all the Rasch model needs to know about a person, and what “specific objectivity” asks of the data;
  • fit the model to real item response data with mirt, and read item fit statistics and plots to judge where it fits and where it doesn’t.

Core ideas

From logistic regression to the Rasch model

Recall from The likelihood and logistic regression: we regressed 40 chess problems on the players’ Elo ratings, \(\Pr(y = 1) = \exp(\beta_0 + \beta_1 x)/(1 + \exp(\beta_0 + \beta_1 x))\). Giving each problem its own intercept raised the Elo slope from 0.50 to 0.83. Problem Y15 stood out: about as hard as Y29, but success on it barely moved with Elo. That lesson ended on a question: what if each player had an unknown parameter of their own instead of an observed Elo rating?

The Rasch model answers it, and takes the step Where CTT breaks pointed to. It keeps the shape of the logistic regression, but everything on the right-hand side is unknown. For person \(j\) and item \(i\), \[\Pr(x_{ij} = 1) = \frac{\exp(\theta_j - b_i)}{1 + \exp(\theta_j - b_i)}.\]

  • \(\theta_j\) is the person’s ability, an idealized version of the sum score. It, and it alone, determines how a person performs on the items. It takes the place of \(\beta_1 \times \text{Elo}\), or of the sum score in the item curves.
  • \(b_i\) is the item’s difficulty, the item intercept with its sign flipped. When \(\theta = b\), the odds of a correct response are even.

Plotting the probability of a correct response against \(\theta\) for a single item gives the item characteristic curve (ICC): the item curve of Where CTT breaks, with \(\theta\) where the sum score was. Move the difficulty around and watch what happens.

Try it: an item characteristic curve

Changing \(b\) slides the curve left and right without changing its shape: a harder item needs more ability for the same chance of success. The curve never reaches 0 or 1, so nobody is certain to get any item right or wrong. The Rasch model fixes the slope at 1 for every item; letting it vary gives the 2PL of From the 1PL to the 4PL.

Especially if you know probit regression: turn on the normal CDF in the widget and find the slope that makes the two curves nearly identical. The answer is roughly 1.7: the scaling constant \(D\) that older IRT papers carry around so that logistic and normal-ogive parameters can be compared. Camilli (1994) traces where it came from.

The scale has no origin

Where is zero on this scale? Nowhere in particular. Add the same constant \(C\) to every ability and every difficulty: the model only ever sees \(\theta - b\), so no predicted response changes.

Try it: shift everything

The probabilities in the last column do not move. The data say how far apart people and items are, but not where zero is: without an extra constraint the model is not identified. Software picks one for you. mirt (Chalmers, 2012) fixes the mean of the ability distribution at 0, as the chess fit below shows. Programs that use conditional maximum likelihood (see the Go deeper callout below) instead fix one item’s difficulty at 0 or make the difficulties sum to 0 (Mair & Hatzinger, 2007). The choice is arbitrary, so two programs’ results can differ by exactly such a shift.

People and items on one scale: the Wright map

Recall from Where CTT breaks: the same 664 students averaged 9.6 on an easy half of a test and 5.7 on a hard half. A sum score doesn’t locate anyone until we know the items.

In the Rasch model a person’s location is \(\theta\), not a count of items, and \(\theta\) and \(b\) live on the same scale, so we can plot them together. A Wright map puts the distribution of people on one side and the item difficulties on the other, and shows at a glance whether a test is well matched to the people who took it.

Try it: build a Wright map

Where people and items overlap, the test can tell people apart; where people sit beyond every item, it cannot. That precision depends on where you are on the scale is the subject of Information, precision, and short forms.

What the model assumes

Two assumptions merit emphasis (Lord, 1980). First, the formula is right: in particular, a single \(\theta\) drives every response (the model is unidimensional). Second, responses are locally independent: once we know \(\theta\), knowing how someone answered item 3 tells us nothing more about item 4. Both can fail: think of two items that share a reading passage, or a test whose last ten items measure something else. IRW vignettes look at how often each assumption holds across many IRW datasets: dimensionality and local dependence.

The sum score is sufficient

The Rasch model has a property that sets it apart from nearly every other item response model: the sum score \(r\) is a sufficient statistic for \(\theta\) (Fisher, 1922). Once you know how many items someone got right, nothing else in their responses, not even which items, changes what we can learn about their ability.

Recall from The likelihood and logistic regression: in a logistic regression with an intercept, the derivative of the log likelihood with respect to the intercept is \(\sum_i (y_i - p_i)\), so at the maximum the model’s predicted number of successes equals the observed number.

For one respondent, \(\theta\) plays the part of that intercept. So the maximum-likelihood estimate of \(\theta\) is the value at which the expected number correct, \(\sum_i \Pr(x_i = 1 \mid \theta)\), equals the observed number correct, \(r\). Which items make up \(r\) never enters the equation.

Below are five items of increasing difficulty. Pick a response pattern and look at the likelihood for \(\theta\); then look at every other pattern with the same sum score.

Try it: sufficiency

Under the Rasch model the column is constant. Switch to the 2PL and it no longer is: getting a highly discriminating item right now counts for more. The relationship between sum scores and Rasch abilities is one-to-one but not linear. On these five items the step from 3 to 4 correct moves the estimate from 0.50 to 1.67, and 5 of 5 has no finite estimate at all.

So which to report, the sum score or \(\hat\theta\)? It rests on two assumptions. In the case that the Rasch model fits and everyone took the same items, the sum score carries everything the model knows about the respondent, it orders people exactly as \(\hat\theta\) does, and nobody needs it explained, so it may be sufficient for many purposes. When respondents take different items, as in Linking and equating, the sum scores are no longer comparable and \(\theta\) is. Whether the Rasch model fits well enough is itself something the data can answer, by setting it against its rivals on held-out responses (Model fit and out-of-sample prediction).

Specific objectivity

The Rasch tradition has a name for the property it prizes: specific objectivity (Rasch, 1977). Comparisons between people should not depend on which items we happened to use, and comparisons between items should not depend on which people happened to take them. It is a demand we place on the data, not something the data grants us for free.

If two items’ curves never cross, then everyone finds item A easier than item B, whatever their ability. If they cross, the ordering of the items depends on who you ask—and the statement “item A is easier than item B” stops meaning anything on its own.

Try it: do the curves cross?

This is why advocates of the Rasch model hold to it so firmly: specific objectivity and sufficiency are what classical measurement in the physical sciences looks like (Wright, 1997). The catch is that the model has to fit. In that tradition, consistency with the Rasch model comes from hard work—iterative item development and pruning of items that don’t behave—not from applying it to whatever data you have. Whether equal slopes are plausible for typical test data is an empirical question, and the 2PL discrimination vignette looks at it across many IRW datasets.

Assumptions: one respondent answers \(I\) dichotomous items; the Rasch model holds for every item; responses are locally independent given \(\theta\); the difficulties \(b_1, \dots, b_I\) are fixed. Write \(\varepsilon_i = e^{-b_i}\) (the item’s easiness) and \(r = \sum_i x_i\).

Factorize the likelihood. Using \(\Pr(x_i \mid \theta) = e^{x_i(\theta - b_i)}/(1 + e^{\theta - b_i})\) for \(x_i \in \{0, 1\}\), \[\Pr(\mathbf{x} \mid \theta) = \prod_{i=1}^{I} \frac{e^{x_i(\theta - b_i)}}{1 + e^{\theta - b_i}} = \frac{e^{r\theta} \; \prod_i \varepsilon_i^{x_i}}{\prod_i \big(1 + e^{\theta - b_i}\big)}.\] The data meet \(\theta\) in one place only, \(e^{r\theta}\). The product \(\prod_i \varepsilon_i^{x_i}\) depends on which items were right but not on \(\theta\), and the denominator depends on \(\theta\) but not on the data. Taking logs and differentiating gives \(r - \sum_i \Pr(x_i = 1 \mid \theta)\), the score equation from the main text.

Condition on \(r\). Add up the probabilities of all the patterns with the same sum score: \[\Pr(r \mid \theta) = \frac{e^{r\theta}\,\gamma_r(\boldsymbol\varepsilon)}{\prod_i \big(1 + e^{\theta - b_i}\big)}, \qquad \gamma_r(\boldsymbol\varepsilon) = \sum_{\mathbf{y}:\, \sum_i y_i = r} \; \prod_i \varepsilon_i^{y_i},\] where \(\gamma_r\), the elementary symmetric function of order \(r\), is a sum over patterns and contains no \(\theta\). Divide: \[\Pr(\mathbf{x} \mid r, \theta) = \frac{\prod_i \varepsilon_i^{x_i}}{\gamma_r(\boldsymbol\varepsilon)}.\] \(\theta\) has cancelled. Given \(r\), the pattern carries no further information about \(\theta\); that is the definition of a sufficient statistic. Three things follow.

  1. Conditional maximum likelihood. Multiply \(\Pr(\mathbf{x}_j \mid r_j)\) over respondents and you have a likelihood for the difficulties with no \(\theta\) in it. Maximizing it is conditional maximum likelihood (CML). It needs no assumption about how \(\theta\) is distributed, and it gives consistent estimates of the \(b_i\) as the number of respondents grows (Andersen, 1970). Estimating every \(\theta_j\) jointly with the \(b_i\) does not, because the number of person parameters grows with the data (Neyman & Scott, 1948). The wirs analysis below uses \(\Pr(x_i = 1 \mid r)\) to compare the model with the data without estimating anyone’s \(\theta\).
  2. Specific objectivity is a theorem. Take two items, \(i\) and \(k\), and condition on the respondent getting exactly one of them right. The same cancellation, with two items, gives \[\Pr(x_i = 1 \mid x_i + x_k = 1, \theta) = \frac{\varepsilon_i}{\varepsilon_i + \varepsilon_k} = \frac{1}{1 + e^{b_i - b_k}},\] which contains no \(\theta\). Whoever the respondents are, strong or weak, the comparison of the two items comes out the same. Swap the roles of people and items (two respondents, one item, exactly one of them right) and the comparison depends on \(\theta_j - \theta_l\) and not on \(b\). This is Rasch’s specific objectivity, derived rather than assumed. When the model fails, it fails in a checkable way: CML estimates of the difficulties from high and low scorers should agree, and Andersen (1973) turned that into a likelihood-ratio test. Problem 3 tries the two-item version on the chess data.
  3. The converse. For dichotomous items, if some statistic is sufficient for \(\theta\) and is the same statistic whatever the item parameters, it is the sum score, and the model must be the Rasch model: logistic curves with equal slopes (Andersen, 1977). Fischer (1995) collects this and other derivations of the Rasch model. Under the 2PL, the weighted score \(\sum_i a_i x_i\) plays the part of \(r\), but its weights are item parameters, which is where From the 1PL to the 4PL picks up.

A note on estimation

Nothing on the right-hand side is known, so fitting takes two steps. mirt estimates the item parameters first, integrating over the distribution of abilities with the EM algorithm (Bock & Aitkin, 1981), then estimates abilities with those item parameters treated as known. Conditional maximum likelihood (Go deeper, above) is the Rasch model’s own alternative. Estimating abilities and Estimating item parameters take these in turn.

Simulate

The code below simulates responses from the Rasch model, fits the model with mirt, and compares the estimated difficulties to the truth. It runs here in your browser; the first run takes about 20 seconds while R and mirt load.

Try changing np to 50, then to 2000, and watch the scatter around the line. With the seed as written, the root mean squared error of the estimated difficulties is 0.34 with 50 people, 0.13 with 500 and 0.04 with 2,000. Now change ni to 40: with 500 people the error barely moves (0.13), because each difficulty rests on the people who answered that item. More items sharpen the abilities instead, which is where Information, precision, and short forms picks up.

mirt writes the Rasch model as \(\Pr(x = 1) = 1/(1 + \exp(-(\theta + d)))\), so its parameter d is an easiness. Our difficulty is \(b = -d\), which is why the code negates it.

Download this code to run it as large as you like in your own R session.

With real data

Our main example is chess_lnirt, the 40 problems of the Amsterdam Chess Test (van der Maas & Wagenmakers, 2005), which we met in The likelihood and logistic regression; its job here is to show what the Rasch model says about a test built for a wide range of skill. A response is 1 if the player solved the problem; download the code behind every number below.

Code
library(mirt)
# Each IRW table has a landing page (itemresponsewarehouse.org/tables/<name>/)
# with a CSV download. This link is pinned to one version of the data.
chess_url <- "https://redivis.com/api/v1/tables/datapages.item_response_warehouse:v57_0.chess_lnirt/rows?format=csv"
df <- read.csv(chess_url)
head(df[, c("id", "item", "resp")])
id item resp
147 Y39 NA
147 Y20 NA
147 Y28 NA
147 Y9 NA
147 Y16 NA
147 Y10 NA

We reshape to one row per player. The first rows above belong to a player with no responses; three of the 259 players are like that, and we drop them, leaving 256.

Code
# IRW tables are long: one row per person-item response. mirt wants wide: one
# row per person, one column per item.
long2wide <- function(df) {
  wide <- tapply(df$resp, list(df$id, df$item), function(x) x[1])
  as.data.frame(wide[, order(as.numeric(gsub("\\D", "", colnames(wide))))])
}
resp <- long2wide(df)
# A few players have no responses at all (resp is NA for every item; the first
# rows of the table are one of them). They carry no information, so drop them.
c(players_in_table = nrow(resp), with_no_responses = sum(rowSums(!is.na(resp)) == 0))
 players_in_table with_no_responses 
              259                 3 
Code
resp <- resp[rowSums(!is.na(resp)) > 0, ]
dim(resp)
[1] 256  40
Code
m1 <- mirt(resp, 1, itemtype = "Rasch", verbose = FALSE)
# mirt writes the Rasch model as P(x = 1) = 1 / (1 + exp(-(theta + d))), so its
# "d" is an easiness. The difficulty in our notation is b = -d.
b <- -coef(m1, simplify = TRUE)$items[, "d"]
round(head(sort(b)), 2)   # the easiest items
  Y31    Y1    Y2    Y3   Y21    Y5 
-4.87 -3.56 -3.48 -3.24 -2.99 -2.82 
Code
round(tail(sort(b)), 2)   # the hardest items
 Y36  Y18  Y19  Y15  Y29  Y30 
2.12 2.19 2.74 3.02 3.14 3.61 

The easiest problem (Y31) sits nearly five logits below zero, the mean ability, and the hardest (Y30) more than three and a half above. Is that a wide spread, and compared with what? The IRW’s difficulty pool holds Rasch difficulties for 145 IRW tables (Zhang et al., 2025), and chess is one of them.

Code
# How wide is wide? The IRW's difficulty pool (the diffsim vignette) holds
# difficulty estimates for 145 IRW tables and ships with the irw package.
round(c(sd_b = sd(b), range_b = diff(range(b))), 2)   # chess, from our fit
   sd_b range_b 
   2.13    8.48 
Code
if (requireNamespace("irw", quietly = TRUE)) {
  data("diff_long", package = "irw")
  pool_sd <- tapply(diff_long$difficulty, diff_long$dataset, sd)
  print(c(tables = length(pool_sd), round(quantile(pool_sd, c(.25, .5, .75)), 2)))
  # chess_lnirt is in the pool. Compare its entry with the rest of the pool:
  cat(sprintf("chess_lnirt in the pool: SD %.2f, wider than %.0f%% of the %d tables\n",
              pool_sd[["chess_lnirt"]], 100 * mean(pool_sd < pool_sd[["chess_lnirt"]]),
              length(pool_sd)))
  # The pool's chess SD is ours divided by the SD of ability in our fit: the pool
  # puts ability on a scale with SD 1, while mirt's Rasch fit estimates it.
  sd_theta <- sqrt(coef(m1, simplify = TRUE)$cov[1, 1])
  cat(sprintf("SD of ability in our fit %.2f; our SD of b divided by it: %.2f\n",
              sd_theta, sd(b) / sd_theta))
}
tables    25%    50%    75% 
145.00   0.70   0.99   1.75 
chess_lnirt in the pool: SD 1.75, wider than 74% of the 145 tables
SD of ability in our fit 1.22; our SD of b divided by it: 1.75

The median table in the pool has a standard deviation of difficulties of 0.99; chess, at 1.75 on the pool’s scale, is more spread out than 74% of them. (The pool fixes the SD of ability at 1, while the Rasch model fixes the slopes at 1 and lets the SD of ability float, here to 1.22; dividing our 2.1 by 1.22 recovers the pool’s 1.75.) That spread is what you want from a test meant to separate novices from masters.

How do these difficulties relate to the simplest measure of item difficulty, the proportion of players who solve the problem?

Code
p <- colMeans(resp, na.rm = TRUE)
plot(p, b, xlab = "Proportion correct (p-value)", ylab = "Rasch difficulty (b)",
     pch = 19, col = "#2780e3")

Code
sprintf("%.4f", cor(p, b, method = "spearman"))   # rank correlation of p and b
[1] "-0.9998"

The rank correlation is −0.9998. That is sufficiency from the item side: with complete data an item’s total is sufficient for its difficulty (Mair & Hatzinger, 2007), and a few missing responses keep it from being exactly −1. The relationship is not linear, though: the Rasch scale stretches out the extremes, where a few percentage points correct correspond to a large difference in difficulty.

Code
theta <- fscores(m1)[, 1]
br <- seq(floor(min(c(theta, b))), ceiling(max(c(theta, b))), by = 0.25)
h <- hist(theta, breaks = br, plot = FALSE)
op <- par(mar = c(4, 4, 2, 1))
plot(NULL, xlim = c(-max(h$counts), 12), ylim = range(br), xaxt = "n",
     xlab = "", ylab = "Logits", main = "Wright map: chess_lnirt")
rect(-h$counts, h$breaks[-length(h$breaks)], 0, h$breaks[-1], col = "#dbeafe", border = "white")
points(rep(1.5, length(b)) + (seq_along(b) %% 8), b, pch = 18, col = "#c2410c")
abline(v = 0)
axis(1, at = c(-max(h$counts) / 2, 5), labels = c("People", "Items"), tick = FALSE)

Code
par(op)
round(c(mean_theta = mean(theta), mean_b = mean(b)), 2)
mean_theta     mean_b 
      0.00       0.12 
Code
# mirt fixes the mean of the ability distribution at 0. Any other origin fits
# exactly as well: add 1 to every theta and every b, and no probability moves.
all.equal(plogis(outer(theta + 1, b + 1, "-")), plogis(outer(theta, b, "-")))
[1] TRUE

The mean ability is 0.00, the constraint mirt imposes, and adding 1 to every ability and difficulty leaves every probability unchanged (all.equal returns TRUE). So the mean difficulty says how hard the test is for this sample: 0.12, about a tenth of a logit, against an SD of ability of 1.22. The test is well targeted.

Does the model fit? One first look is the infit and outfit statistics (Wright & Masters, 1982): mean squared standardized residuals, which should be near 1 if the model is right. Values well below 1 mean an item is more predictable than the Rasch model expects (typically an item that discriminates better than average); values well above 1 mean it is noisier. How far from 1 is too far is the subject of Model fit and out-of-sample prediction.

Code
fit <- itemfit(m1, fit_stats = "infit")
head(fit[order(-abs(fit$z.outfit)), ], 5)   # the five worst-fitting items, by |z|
item outfit z.outfit infit z.infit
9 Y9 0.6360787 -4.986545 0.7049058 -5.7677088
8 Y8 0.7291513 -3.491464 0.7777831 -4.1453249
38 Y38 0.7295410 -2.965869 0.8142504 -3.2988899
10 Y10 0.7308588 -2.854375 0.8370314 -2.8271237
15 Y15 2.2221666 2.606262 1.1813203 0.9787916
Code
fit[which.max(fit$outfit), ]                # the largest outfit of all 40 items
item outfit z.outfit infit z.infit
15 Y15 2.222167 2.606262 1.18132 0.9787916
Code
# itemfit() computes residuals from mirt's default EAP abilities, which shrink toward
# the mean; method = "ML" uses maximum-likelihood abilities instead.
fit_ml <- itemfit(m1, fit_stats = "infit", method = "ML")
round(c(median_outfit_EAP = median(fit$outfit), median_outfit_ML = median(fit_ml$outfit)), 2)
median_outfit_EAP  median_outfit_ML 
             0.95              1.01 
Code
ml <- data.frame(item = fit_ml$item, outfit_ML = round(fit_ml$outfit, 2),
                 z_ML = round(fit_ml$z.outfit, 1))
ml[ml$item %in% c("Y8", "Y9", "Y10", "Y38"), ]   # the four overfitting items above
item outfit_ML z_ML
8 Y8 0.74 -2.6
9 Y9 0.63 -4.0
10 Y10 0.74 -2.2
38 Y38 0.74 -2.3
Code
head(ml[order(-ml$outfit_ML), ], 3)              # the largest outfits
item outfit_ML z_ML
2 Y2 2.46 2.4
15 Y15 2.45 2.8
33 Y33 2.07 2.7
Code
itemfit(m1, empirical.plot = 15)            # Y15: observed vs. model

Four of the five worst-fitting items by \(|z|\) overfit (outfit from 0.64 to 0.73): they separate strong and weak players more sharply than a common slope allows. The exception is Y15, whose outfit of 2.2 is the largest of all 40 items under mirt’s default: by the size of its misfit, it is among the worst-fitting items on the test. It is the problem whose success barely moved with Elo in The likelihood and logistic regression. The empirical plot compares the model’s curve with the proportions solved among players grouped by ability. Those proportions barely rise: below-average players solve Y15 more often than the model expects, and the strongest group less often. Why is a question about the problem itself, which the responses alone can’t answer. These outfits come from mirt’s default EAP abilities, which pull outfit below 1 even when the model is true (Model fit and out-of-sample prediction). With maximum-likelihood abilities the median is 1.01 rather than 0.95, but the four overfitting items stay at 0.63 to 0.74, and Y15 (2.45) is second only to Y2 (2.46).

For contrast, a table whose job is to show a setting where one ability and equal slopes describe the data less well: wirs, six items from the 1990 Workplace Industrial Relations Survey analysed by Bartholomew (1998). Each item asks whether a kind of consultation took place about the most recent introduction of new equipment (1 = yes), from informal discussion with individual workers (item 1) through joint consultative committees (item 3) to paid union officials (wording from the ltm documentation, Rizopoulos, 2006). Because the sum score is sufficient, the Rasch model says what proportion of respondents with each sum score should say yes to each item, without estimating anyone’s \(\theta\) (the Go deeper callout gives the formula).

Code
wirs_url <- "https://redivis.com/api/v1/tables/datapages.item_response_warehouse:v57_0.wirs/rows?format=csv"
resp_w <- long2wide(read.csv(wirs_url))
dim(resp_w)
[1] 1005    6
Code
m2 <- mirt(resp_w, 1, itemtype = "Rasch", verbose = FALSE)
b_w <- -coef(m2, simplify = TRUE)$items[, "d"]
# Because the sum score r is sufficient, the Rasch model predicts the proportion
# endorsing item i among respondents with sum score r without reference to theta:
#   P(x_i = 1 | r) = eps_i * gamma_(r-1)(items other than i) / gamma_r(all items),
# with eps = exp(-b) and gamma_r the elementary symmetric functions (see the
# Go deeper callout in the lesson).
esf <- function(eps) {               # gamma_0, gamma_1, ..., gamma_n
  g <- 1
  for (e in eps) g <- c(g, 0) + c(0, g) * e
  g
}
p_given_r <- function(b, i) {        # P(x_i = 1 | r) for r = 0, ..., n
  eps <- exp(-b); g <- esf(eps); g_i <- esf(eps[-i]); r <- seq_along(b)
  c(0, eps[i] * g_i[r] / g[r + 1])
}
r_w <- factor(rowSums(resp_w), levels = 0:6)
tab <- data.frame(r = 0:6, n = as.vector(table(r_w)),
  item1_observed = as.vector(tapply(resp_w[, 1], r_w, mean)),
  item1_rasch    = p_given_r(b_w, 1),
  item3_observed = as.vector(tapply(resp_w[, 3], r_w, mean)),
  item3_rasch    = p_given_r(b_w, 3))
round(tab, 2)
r n item1_observed item1_rasch item3_observed item3_rasch
0 132 0.00 0.00 0.00 0.00
1 284 0.23 0.17 0.04 0.11
2 256 0.56 0.38 0.19 0.26
3 191 0.58 0.59 0.52 0.44
4 89 0.36 0.76 0.81 0.65
5 50 0.40 0.90 0.96 0.84
6 3 1.00 1.00 1.00 1.00

Item 3 (a joint consultative committee) rises more steeply than the model allows: 0.04 of respondents with a sum score of 1 said yes, against a predicted 0.11, and 0.96 of those with 5, against 0.84. Item 1 (informal discussion with individual workers) barely tracks the sum score. It rises from 0.23 to 0.58 between sum scores 1 and 3, then falls to 0.36 and 0.40 at 4 and 5, where the model predicts 0.76 and 0.90. The data are telling us something about the construct: workplaces that use many formal channels don’t talk more with individual workers, so “amount of consultation” may not be a single dimension. Whether the Rasch model describes a dataset is something to check item by item, not assume (Model fit and out-of-sample prediction).

Recall from Where CTT breaks: the sum score contains the item, so at the extremes each item’s proportion is fixed. Here, at sum scores 0 and 6, observed and predicted agree by construction.

Problems

  1. The logit. Show that \(\frac{e^x}{1+e^x} = \frac{1}{1+e^{-x}}\). Then show that under the Rasch model, \(\log\frac{\Pr(x=1)}{\Pr(x=0)} = \theta - b\). What does a one-unit increase in \(\theta\) do to the odds of a correct response, on any item?
  2. Indeterminacy. Suppose \(\theta' = \theta + C\) and \(b' = b + C\). Show that \(\Pr(x = 1)\) is unchanged. Now suppose instead \(\theta' = k\theta\) and \(b' = kb\) for some \(k \ne 1\). Is the Rasch model still unchanged? What does your answer say about which feature of the scale the Rasch model does pin down, and how does it square with the difficulty pool’s chess SD of 1.75 against our 2.1?
  3. Specific objectivity in the chess data. By the Go deeper callout, among players who solved exactly one of problems \(i\) and \(k\), the proportion who solved \(i\) should be \(1/(1 + e^{b_i - b_k})\) whatever their ability. Pick two problems of middling difficulty, take the players who solved exactly one, and split them at the median of their sum score on the other 38. Compare the two halves with each other and with the prediction. Repeat for a pair that includes Y15. What do you see?
  4. Targeting. Draw the Wright map for chess_lnirt. For which players does this test give the least information, and why? Suggest the difficulty of two items you would add to the test to improve measurement for them.
  5. Fit, two ways. Using itemfit(..., empirical.plot = i), compare several items in chess_lnirt and in wirs. Which dataset does the Rasch model describe better? Now run the simulation above with np = 2000 and ni = 50 and look at the same plots. What does “good fit” look like when you know the model is true?
  6. Challenge: sufficiency in the data. In chess_lnirt, find two players with the same sum score but very different response patterns. Compare their estimated abilities (fscores). Then fit a 2PL (itemtype = "2PL") and compare again. Explain what you see. Then the open part: if the 2PL fits the chess data better, how much would you lose by reporting the sum score anyway, and how would you decide?

Stuck, or curious about something this lesson doesn’t cover? Ask Claude about this lesson opens a new conversation that already knows what the lesson is about; add your question at the end. Claude shows a caution notice on any prompt that arrives through a link; that’s expected.

Going further

  • Rasch, G. (1960). Probabilistic models for some intelligence and attainment tests. Danish Institute for Educational Research; expanded edition, University of Chicago Press, 1980. https://openlibrary.org/works/OL4506215W. Where the model starts, including the case for separating people from items.
  • Andersen, E. B. (1970). Asymptotic properties of conditional maximum-likelihood estimators. Journal of the Royal Statistical Society, Series B, 32(2), 283–301. https://doi.org/10.1111/j.2517-6161.1970.tb00842.x. Why conditioning on the sum score gives consistent difficulty estimates.
  • Andersen, E. B. (1977). Sufficient statistics and latent trait models. Psychometrika, 42(1), 69–81. https://doi.org/10.1007/BF02293746. The converse: sufficiency of the sum score implies the Rasch model.
  • Fischer, G. H. (1995). Derivations of the Rasch model. In G. H. Fischer & I. W. Molenaar (Eds.), Rasch models: Foundations, recent developments, and applications (pp. 15–38). Springer. https://doi.org/10.1007/978-1-4612-4230-7_2. The Go deeper callout, done properly and from several directions.
  • Rasch, G. (1977). On specific objectivity: An attempt at formalizing the request for generality and validity of scientific statements. Danish Yearbook of Philosophy, 14, 58–94. https://doi.org/10.1163/24689300-01401006. Rasch’s own statement of specific objectivity.
  • Wright, B. D. (1997). A history of social science measurement. Educational Measurement: Issues and Practice, 16(4), 33–45. https://doi.org/10.1111/j.1745-3992.1997.tb00606.x. The case for the Rasch model, from one of its leading advocates.
  • Wright, B. D., & Masters, G. N. (1982). Rating scale analysis. MESA Press. https://www.rasch.org/rsa.htm. Infit and outfit, and Rasch analysis in practice.
  • Tutz, G. (2025). A short guide to item response theory models. Springer. https://doi.org/10.1007/978-3-031-87271-6. Chapter 2 is a compact modern treatment of the binary Rasch model.
  • Camilli, G. (1994). Origin of the scaling constant d = 1.7 in item response theory. Journal of Educational and Behavioral Statistics, 19(3), 293–295. https://doi.org/10.3102/10769986019003293. The 1.7 in the ICC challenge.
  • Chalmers, R. P. (2012). mirt: A multidimensional item response theory package for the R environment. Journal of Statistical Software, 48(6). https://doi.org/10.18637/jss.v048.i06. The package used throughout.
  • van der Maas, H. L. J., & Wagenmakers, E.-J. (2005). A psychometric analysis of chess expertise. American Journal of Psychology, 118(1), 29–60. https://doi.org/10.2307/30039042. The source of the chess data.
  • Bartholomew, D. J. (1998). Scaling unobservable constructs in social science. Journal of the Royal Statistical Society, Series C, 47(1), 1–13. https://doi.org/10.1111/1467-9876.00094. The source of the wirs data.
  • From the IRW: simulating item difficulties shows what real difficulty distributions look like across the IRW (the baseline for the chess spread), and why they matter for simulation studies (Zhang, L., Liu, Y., Molenaar, D., Gilbert, J. B., Kanopka, K., & Domingue, B. W. (2025). Realistic simulation of item difficulties. PsyArXiv. https://doi.org/10.31234/osf.io/jbhxy_v4). The dimensionality, local dependence and 2PL discrimination vignettes take the model’s assumptions across the IRW.
  • San Martín, E. (2017). Identification of item response theory models. In W. J. van der Linden (Ed.), Handbook of item response theory: Vol. 2. Statistical tools (pp. 127–150). Chapman and Hall/CRC. https://doi.org/10.1201/b19166-8. A handbook chapter on when the parameters of item response models are identified.
  • von Davier, M. (2016). Rasch model. In W. J. van der Linden (Ed.), Handbook of item response theory: Vol. 1. Models (pp. 31–48). Chapman and Hall/CRC. https://doi.org/10.1201/9781315374512. A handbook chapter on the Rasch model.

Data sources

Data from the Item Response Warehouse (each table name links to its IRW page); references from IRW biblio.

For instructors

  • Source: EDUC 252 class 3 (slides c3, “Probabilistic item response modeling” through “Estimation of the RM”) and the code in ben-domingue/252: c3/rasch0.R, c3/rasch1.R, c3/rasch2.R.
  • Timing: the core ideas and widgets fit in about 75 minutes of class; the real-data section works well as an in-class lab. The Go deeper callout is optional reading for students with some mathematical statistics.
  • Changed from 252 (retrofit, 09-24): the sufficiency derivation (factorization, conditional ML, specific objectivity as a theorem, Andersen’s converse) was added as a Go deeper callout; the wirs contrast now compares observed and model-implied proportions given the sum score rather than an empirical plot; the “wide spread” of chess difficulties is judged against the IRW difficulty pool; a problem on reading mirt’s raw d was replaced by problem 3 (specific objectivity in the chess data).
  • Held back: item and test information, and the estimation algorithms, have their own lessons. The problem set questions on Rasch fit statistics (outfit’s sampling distribution) are in Model fit and out-of-sample prediction.
  • Solutions: held back in solutions/rasch.qmd (not published).