The flexmet package provides utilities for use with the filtered monotonic polynomial (FMP) item response model. One of the unique features of the FMP model is the ability to transform the model to a user-specified metric. The FMP model can also transform the two-, three-, and four-parameter models, as well as generalized partial credit models.
A general form of the FMP model is specified using the composite function,
P(Xi=c|θ)=exp(c∑v=0(b0iv+mi(θ)))/(Ci−1∑u=0exp(u∑v=0(b0iv+mi(θ))))
where P indicates the probability of a response in category c, c=0,…,Ci−1, θ is the latent trait parameter, biv indicates an intercept for category v, v=1,…,Ci−1, and ∑0v=0(biv+mi(θ))≡0. In addition, let
mi(θ)=b1iθ+b2iθ2+⋯+b2ki+1,iθ2ki+1, where 2ki+1 equals the order of the polynomial for item i, ki is a nonnegative integer, and \boldsymbol{b}_{i}=(b_{0i_{1}},\ldots, b_{0i_{C_i-1}} b_{1i},\ldots,b_{2k_{i}+1,i})^{\prime} are item parameters that define the location and shape of the IRF. When k = 0, the general FMP model reduces to the two-parameter item response model (for binary item responses) or the generalized partial credit model (for polytomous item responses).
For models with binary (0/1) item responses, flexmet also allows the use to include a lower asymptote parameter c_i and upper asymptote parameter d_i for the extended FMP model:
P_i(\theta)=c_i + (d_i - c_i)[1+\exp(-m_{i}(\theta))]^{-1}.
The c_i and d_i parameters are unaffected by parameter transformations.
Below is a worked example of how to transform a two-parameter model to the expected sum score metric. The original two-parameter metric is denoted \theta and the expected sum score metric is denoted \theta^\star. This example uses the 23 two-parameter model low self-esteem parameter estimates reported in Table 7 of Reise & Waller (2003).
First, we need to express the two-parameter model as an FMP model. The FMP model with k=0 is identical to the slope-intercept parameterization of the two-parameter model. The Reise & Waller parameters are expressed on the more familiar difficulty-discrimination parameterization of the FMP model.
## example parameters from Table 7 of Reise & Waller (2003)
<- c(0.57, 0.68, 0.76, 0.72, 0.69, 0.57, 0.53, 0.64,
a 0.45, 1.01, 1.05, 0.50, 0.58, 0.58, 0.60, 0.59,
1.03, 0.52, 0.59, 0.99, 0.95, 0.39, 0.50)
<- c(0.87, 1.02, 0.87, 0.81, 0.75, -0.22, 0.14, 0.56,
b 1.69, 0.37, 0.68, 0.56, 1.70, 1.20, 1.04, 1.69,
0.76, 1.51, 1.89, 1.77, 0.39, 0.08, 2.02)
## convert from difficulties and discriminations to FMP parameters
<- 1.702 * a
b1 <- - 1.702 * a * b
b0 <- cbind(b0, b1) bmat
The transformation from \theta to \theta^\star is defined by the test response function, which is the sum of item response functions:
\theta^\star =\sum_iP_i(\theta)
There is usually not a closed form expression for \theta as a function of \theta^\star. In addition, to transform the FMP item parmaeters, \theta must be expressed as a polynomial function of \theta^\star:
\theta = t_0 + t_1\theta^\star + t_2\theta^{\star2} + \cdots + t_{2k_\theta+1}\theta^{\star 2k_\theta+1}.
In this example, the metric transformation is known exactly, but it can be approximated by a monotonic polynomial. To approximate the metric transformation, we can generate a large number of observations and fit a monotonic polynomial function to the simulated values.
# generate a large number of theta and TRF (thetastar) values
<- seq(-3, 5, length = 5000)
theta <- rowSums(irf_fmp(theta = theta, b = bmat)) TRF
Monotonic polynomial regression using the MonoPoly package can be used to approximate the metric transformation coefficients \boldsymbol{t}=(t_0,t_1,\ldots,t_{2k_\theta+1})^\prime. We can fit a sequence of k_\theta values to find a good choice for the polynomial degree.
<- MonoPoly::monpol(theta ~ TRF, K = 0)
fmp0 <- MonoPoly::monpol(theta ~ TRF, K = 1)
fmp1 <- MonoPoly::monpol(theta ~ TRF, K = 2)
fmp2 <- MonoPoly::monpol(theta ~ TRF, K = 3)
fmp3 <- MonoPoly::monpol(theta ~ TRF, K = 4) fmp4
Choose a “good enough” polynomial degree by looking at the residual sum of squares and by viewing patterns of residuals.
$RSS
fmp0#> [1] 59.88323
$RSS
fmp1#> [1] 7.231035
$RSS
fmp2#> [1] 7.225206
$RSS
fmp3#> [1] 0.2263184
$RSS
fmp4#> [1] 0.04808141
<- c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00")
cols par(lwd = 2)
curve(0*x, xlim = c(0, 22), ylim = c(-1, 1), col = "darkgray",
xlab = "Expected Sum Score",
ylab = "Residuals of Polynomial Approximation")
points(TRF, residuals(fmp0), type = 'l', col = cols[1], lty = 2)
points(TRF, residuals(fmp1), type = 'l', col = cols[2], lty = 3)
points(TRF, residuals(fmp2), type = 'l', col = cols[3], lty = 2)
points(TRF, residuals(fmp3), type = 'l', col = cols[4], lty = 1)
points(TRF, residuals(fmp4), type = 'l', col = cols[5], lty = 3)
legend("bottomright",
legend = c(expression(paste(italic(k[theta])," = 0")),
expression(paste(italic(k[theta])," = 1")),
expression(paste(italic(k[theta])," = 2")),
expression(paste(italic(k[theta])," = 3")),
expression(paste(italic(k[theta])," = 4"))),
col = cols, lty = c(2, 3, 2, 1, 3), bty = "n")
Suppose we choose to retain the k_\theta = 3 approximation. Then, the metric transformation vector equals,
<- coef(fmp3))
(tvec #> beta0 beta1 beta2 beta3 beta4
#> -3.807887e+00 2.141638e+00 -6.477732e-01 1.171824e-01 -1.208074e-02
#> beta5 beta6 beta7
#> 7.022950e-04 -2.138094e-05 2.651772e-07
and the transformed item parameters equal
<- t(apply(bmat, 1, transform_b, tvec = tvec))
bstarmat
## inspect transformed parameters
signif(head(bstarmat), 2)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] -4.5 2.1 -0.63 0.11 -0.012 0.00068 -2.1e-05 2.6e-07
#> [2,] -5.6 2.5 -0.75 0.14 -0.014 0.00081 -2.5e-05 3.1e-07
#> [3,] -6.1 2.8 -0.84 0.15 -0.016 0.00091 -2.8e-05 3.4e-07
#> [4,] -5.7 2.6 -0.79 0.14 -0.015 0.00086 -2.6e-05 3.2e-07
#> [5,] -5.4 2.5 -0.76 0.14 -0.014 0.00082 -2.5e-05 3.1e-07
#> [6,] -3.5 2.1 -0.63 0.11 -0.012 0.00068 -2.1e-05 2.6e-07
We can check that the transformation worked by plotting the test response function for the transformed model. If successful, this is a straight line because the latent trait \theta^\star should be as close as possible to the expected sum score.
par(pty = "s")
curve(rowSums(irf_fmp(x, bmat = bstarmat)), xlim = c(0, 23),
ylim = c(0, 23), xlab = expression(paste(theta,"*")),
ylab = "Expected Sum Score")
abline(0, 1, col = 2)
The bstarmat parameters can then be used as item parameters for subsequent analyses, such as trait score estimation.