Chapter 9 showed that for a linear model the Cox-Snell formula recovers ordinary \(R^2\) exactly, while the naive proportional reduction in deviance does not. This appendix follows that up: what happens to these measures once the outcome is no longer continuous, and why the competing versions disagree.
C.1 Two formulas
For models fitted by maximum likelihood there is no sum of squared error to reduce, so \(R^2\) has to be rebuilt out of deviance. Different people rebuilt it differently.
Proportional reduction in deviance (McFadden’s), which mimics PRE directly:
\[\text{PRD} = \frac{D_0 - D_1}{D_0}\]
Cox and Snell’s, which comes from the likelihood ratio and rescales by sample size:
Cox-Snell is a genuine generalization of \(R^2\), and it reduces to it when the model is linear. PRD is a different construction that happens to resemble PRE, and for a linear model it is simply wrong. As Chapter 9 explains, the trouble is the \(\sigma\) estimate: as RSS goes to zero, \(\sigma\) goes to zero and the likelihood diverges, so the ratio of deviances doesn’t behave.
Neither, though, will recover the \(R^2\) you would have obtained had a binary outcome not been dichotomized in the first place. That’s what the rest of this appendix shows.
C.3 A controlled comparison
We can construct data where the truth is known. Generate two variables with an exact correlation, so the latent \(R^2\) is fixed at a value we choose, then dichotomize the outcome and see what the measures report.
# create dataset with exact known correlation# convert outcome to binary and see if PRD = Cox-Snellget_stats <-function(n, r) { Sigma <-matrix(c(1, r, r, 1), 2, 2) mat <- MASS::mvrnorm(n, mu =c(0, 0), Sigma = Sigma, empirical =TRUE) x = mat[,1] ystar = mat[,2] y =if_else(ystar >0, 1, 0) # binom transform m0 <-glm(y ~1, family =binomial()) m1 <-glm(y ~ x, family =binomial()) d0 <-as.numeric(-2*logLik(m0)) d1 <-as.numeric(-2*logLik(m1)) delta <- d0 - d1 prd <- (d0 - d1) / d0 cs <-1-exp(-delta /length(x)) tmp <- tibble::tibble(cs = cs,prd = prd )return(tmp)}set.seed(522)# for a given PRE (r2), get the data and compare stats for increasing Nmytests <-expand_grid(n =seq(50, 1000, 50),r =c(sqrt(.1), sqrt(.5), sqrt(.8))) |>rowwise() |>mutate(stats =list(get_stats(n, r))) |>unnest_wider(stats) |>ungroup() |>mutate(latent =factor(round(r^2, 1)))mytests |>select(n, latent, prd, cs) |>head(4) |>mutate(across(c(prd, cs), \(z) round(z, 4)))
The two measures disagree with each other. At a latent \(R^2\) of 0.1, Cox-Snell runs about a third larger than PRD. At 0.8 the ordering reverses for most sample sizes, with PRD the larger of the two. There is no fixed relationship you can use to convert one into the other, and not even a consistent direction.
Neither recovers the latent \(R^2\). When the truth is 0.8, both report values in the neighbourhood of 0.5, well short of it. Dichotomizing an outcome throws information away, and no summary statistic can retrieve it. Note that this is a different failure from the linear-model case above: there, Cox-Snell was exactly right and PRD was wrong. Here Cox-Snell is behaving correctly as a likelihood-based measure; it is the dichotomization that has destroyed the information.
Cox-Snell cannot reach 1. Its maximum is bounded below one for a binary outcome, a defect that motivated yet another version (Nagelkerke’s), which rescales Cox-Snell by its own maximum. That fixes the ceiling and introduces its own oddities.
ImportantThe practical rule
Report a pseudo-\(R^2\) if a reader expects one, and say which one it is. Never compare a pseudo-\(R^2\) against an ordinary \(R^2\) from a different model, and never compare pseudo-\(R^2\) values computed by different formulas.
For comparing models fitted to the same data, the information criteria of Chapter 10 are better behaved and easier to defend. For describing how much a predictor matters, the average marginal effects of Chapter 16 are more informative than any single-number summary of fit.