Compute Person Parameters for the 1/2/3/4-PL model and choose between five common estimation techniques: ML, WL, MAP, EAP and a robust estimation. All item parameters are treated as fixed.

PP_4pl(
  respm,
  thres,
  slopes = NULL,
  lowerA = NULL,
  upperA = NULL,
  theta_start = NULL,
  mu = NULL,
  sigma2 = NULL,
  type = "wle",
  maxsteps = 40,
  exac = 0.001,
  H = 1,
  ctrl = list()
)

Arguments

respm

An integer matrix, which contains the examinees responses. A persons x items matrix is expected.

thres

A numeric vector or a numeric matrix which contains the threshold parameter (also known as difficulty parameter or beta parameter) for each item. If a matrix is submitted, the first row must contain only zeroes!

slopes

A numeric vector, which contains the slope parameters for each item - one parameter per item is expected.

lowerA

A numeric vector, which contains the lower asymptote parameters (kind of guessing parameter) for each item.

upperA

numeric vector, which contains the upper asymptote parameters for each item.

theta_start

A vector which contains a starting value for each person. If NULL is submitted, the starting values are set automatically. If a scalar is submitted, this start value is used for each person.

mu

A numeric vector of location parameters for each person in case of MAP or EAP estimation. If nothing is submitted this is set to 0 for each person for MAP estimation.

sigma2

A numeric vector of variance parameters for each person in case of MAP or EAP estimation. If nothing is submitted this is set to 1 for each person for MAP estimation.

type

Which maximization should be applied? There are five valid entries possible: "mle", "wle", "map", "eap" and "robust". To choose between the methods, or just to get a deeper understanding the papers mentioned below are quite helpful. The default is "wle" which is a good choice in many cases.

maxsteps

The maximum number of steps the NR Algorithm will take. Default = 100.

exac

How accurate are the estimates supposed to be? Default is 0.001.

H

In case type = "robust" a Huber ability estimate is performed, and H modulates how fast the downweighting takes place (for more Details read Schuster & Yuan 2011).

ctrl

more controls:

  • killdupli: Should duplicated response pattern be removed for estimation (estimation is faster)? This is especially resonable in case of a large number of examinees and a small number of items. Use this option with caution (for map and eap), because persons with different mu and sigma2 will have different ability estimates despite they responded identically. Default value is FALSE.

  • skipcheck: Default = FALSE. If TRUE data matrix and arguments are not checked - this saves time e.g. when you use this function for simulations.

Value

The function returns a list with the estimation results and pretty much everything which has been submitted to fit the model. The estimation results can be found in OBJ$resPP. The core result is a number_of_persons x 2 matrix, which contains the ability estimate and the SE for each submitted person.

Details

With this function you can estimate:

  • 1-PL model (Rasch model) by submitting: the data matrix, item difficulties and nothing else, since the 1-PL model is merely a 4-PL model with: any slope = 1, any lower asymptote = 0 and any upper asymptote = 1!

  • 2-PL model by submitting: the data matrix, item difficulties and slope parameters. Lower and upper asymptotes are automatically set to 0 und 1 respectively.

  • 3-PL model by submitting anything except the upper asymptote parameters

  • 4-PL model ---> submit all parameters ...

The probability function of the 4-PL model is: $$P(x_{ij} = 1 | \hat \alpha_i, \hat\beta_i, \hat\gamma_i, \hat\delta_i, \theta_j ) = \hat\gamma_i + (\hat\delta_i-\hat\gamma_i) \frac{exp(\hat \alpha_i (\theta_{j} - \hat\beta_{i}))}{\,1 + exp(\hat\alpha_i (\theta_{j} - \hat\beta_{i}))}$$

In our case \(\theta\) is to be estimated, and the four item parameters are assumed as fixed (usually these are estimates of a former scaling procedure).

The 3-PL model is the same, except that \(\delta_i = 1, \forall i\).

In the 2-PL model \(\delta_i = 1, \gamma_i = 0, \forall i\).

In the 1-PL model \(\delta_i = 1, \gamma_i = 0, \alpha_i = 1, \forall i\).

.

The robust estimation method, applies a Huber-type estimator (Schuster & Yuan, 2011), which downweights responses to items which provide little information for the ability estimation. First a residuum is estimated and on this basis, the weight for each observation is computed.

residuum: $$r_i = \alpha_i(\theta - \beta_i)$$

weight:

$$w(r_i) = 1 \rightarrow if\, |r_i| \leq H$$ $$w(r_i) = H/|r| \rightarrow if\, |r_i| > H$$

References

Baker, Frank B., and Kim, Seock-Ho (2004). Item Response Theory - Parameter Estimation Techniques. CRC-Press.

Barton, M. A., & Lord, F. M. (1981). An Upper Asymptote for the Three-Parameter Logistic Item-Response Model.

Birnbaum, A. (1968). Some latent trait models and their use in inferring an examinee's ability. In Lord, F.M. & Novick, M.R. (Eds.), Statistical theories of mental test scores. Reading, MA: Addison-Wesley.

Magis, D. (2013). A note on the item information function of the four-parameter logistic model. Applied Psychological Measurement, 37(4), 304-315.

Samejima, Fumiko (1993). The bias function of the maximum likelihood estimate of ability for the dichotomous response level. Psychometrika, 58, 195-209.

Samejima, Fumiko (1993). An approximation of the bias function of the maximum likelihood estimate of a latent variable for the general case where the item responses are discrete. Psychometrika, 58, 119-138.

Schuster, C., & Yuan, K. H. (2011). Robust estimation of latent ability in item response models. Journal of Educational and Behavioral Statistics, 36(6), 720-735.

Warm, Thomas A. (1989). Weighted Likelihood Estimation Of Ability In Item Response Theory. Psychometrika, 54, 427-450.

Yen, Y.-C., Ho, R.-G., Liao, W.-W., Chen, L.-J., & Kuo, C.-C. (2012). An empirical evaluation of the slip correction in the four parameter logistic models with computerized adaptive testing. Applied Psychological Measurement, 36, 75-87.

See also

Author

Manuel Reif

Examples

################# 4 PL ############################################################# ### real data ########## data(pp_amt) d <- as.matrix(pp_amt$daten_amt[,-(1:7)]) rd_res <- PP_4pl(respm = d, thres = pp_amt$betas[,2], type = "wle")
#> Estimating: 1pl model ... #> type = wle #> Estimation finished!
summary(rd_res)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = d, thres = pp_amt$betas[, 2], type = "wle") #> - job started @ Mon May 24 13:27:52 2021 #> #> Estimation type: wle #> #> Number of iterations: 4 #> ------------------------------------- #> estimate SE #> [1,] 1.4099 0.4178 #> [2,] 0.3516 0.3729 #> [3,] 1.0745 0.3741 #> [4,] 0.3205 0.6900 #> [5,] 1.3879 0.4644 #> [6,] 0.9457 0.4185 #> [7,] 1.8277 0.4109 #> [8,] -0.2274 0.3964 #> [9,] 1.4426 0.4074 #> [10,] 1.6430 0.4033 #> [11,] -0.4802 0.4759 #> [12,] -0.3591 0.4086 #> [13,] -0.1911 0.4137 #> [14,] 0.5781 0.4177 #> [15,] -0.8898 0.4215 #> --------> output truncated <--------
rd_res1 <- PP_4pl(respm = d, thres = pp_amt$betas[,2], theta_start = 0,type = "wle")
#> Estimating: 1pl model ... #> type = wle #> Estimation finished!
summary(rd_res1)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = d, thres = pp_amt$betas[, 2], theta_start = 0, type = "wle") #> - job started @ Mon May 24 13:27:52 2021 #> #> Estimation type: wle #> #> Number of iterations: 40 #> ------------------------------------- #> estimate SE #> [1,] 1.4099 0.4178 #> [2,] 0.3516 0.3729 #> [3,] 1.0745 0.3741 #> [4,] 0.3205 0.6900 #> [5,] 1.3879 0.4644 #> [6,] 0.9457 0.4185 #> [7,] 1.8277 0.4109 #> [8,] -0.2274 0.3964 #> [9,] 1.4426 0.4074 #> [10,] 1.6430 0.4033 #> [11,] -0.4802 0.4759 #> [12,] -0.3591 0.4086 #> [13,] -0.1911 0.4137 #> [14,] 0.5781 0.4177 #> [15,] -0.8898 0.4215 #> --------> output truncated <--------
### fake data ########## # smaller ... faster set.seed(1522) # intercepts diffpar <- seq(-3,3,length=12) # slope parameters sl <- round(runif(12,0.5,1.5),2) la <- round(runif(12,0,0.25),2) ua <- round(runif(12,0.8,1),2) # response matrix awm <- matrix(sample(0:1,10*12,replace=TRUE),ncol=12) ## 1PL model ##### # MLE res1plmle <- PP_4pl(respm = awm,thres = diffpar,type = "mle")
#> Estimating: 1pl model ... #> type = mle #> Estimation finished!
# WLE res1plwle <- PP_4pl(respm = awm,thres = diffpar,type = "wle")
#> Estimating: 1pl model ... #> type = wle #> Estimation finished!
# MAP estimation res1plmap <- PP_4pl(respm = awm,thres = diffpar,type = "map")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 1pl model ... #> type = map #> Estimation finished!
# EAP estimation res1pleap <- PP_4pl(respm = awm,thres = diffpar,type = "eap")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 1pl model ... #> type = eap #> Estimation finished!
# robust estimation res1plrob <- PP_4pl(respm = awm,thres = diffpar,type = "robust")
#> Estimating: 1pl model ... #> type = robust #> Estimation finished!
# summarize results summary(res1plmle)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = awm, thres = diffpar, type = "mle") #> - job started @ Mon May 24 13:27:53 2021 #> #> Estimation type: mle #> #> Number of iterations: 5 #> ------------------------------------- #> estimate SE #> [1,] 0.5903 0.7715 #> [2,] 3.5841 1.1379 #> [3,] 0.5903 0.7715 #> [4,] 0.5903 0.7715 #> [5,] 0.5903 0.7715 #> [6,] 0.0000 0.7668 #> [7,] 0.5903 0.7715 #> [8,] -1.1966 0.7880 #> [9,] 0.5903 0.7715 #> [10,] -1.1966 0.7880
summary(res1plwle)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = awm, thres = diffpar, type = "wle") #> - job started @ Mon May 24 13:27:53 2021 #> #> Estimation type: wle #> #> Number of iterations: 4 #> ------------------------------------- #> estimate SE #> [1,] 0.5778 0.7713 #> [2,] 3.2839 1.0488 #> [3,] 0.5778 0.7713 #> [4,] 0.5778 0.7713 #> [5,] 0.5778 0.7713 #> [6,] 0.0000 0.7668 #> [7,] 0.5778 0.7713 #> [8,] -1.1667 0.7869 #> [9,] 0.5778 0.7713 #> [10,] -1.1667 0.7869
summary(res1plmap)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = awm, thres = diffpar, type = "map") #> - job started @ Mon May 24 13:27:53 2021 #> #> Estimation type: map #> #> Number of iterations: 3 #> ------------------------------------- #> estimate SE #> [1,] 0.3706 0.7686 #> [2,] 1.9069 0.8297 #> [3,] 0.3706 0.7686 #> [4,] 0.3706 0.7686 #> [5,] 0.3706 0.7686 #> [6,] 0.0000 0.7668 #> [7,] 0.3706 0.7686 #> [8,] -0.7436 0.7745 #> [9,] 0.3706 0.7686 #> [10,] -0.7436 0.7745
## 2PL model ##### # MLE res2plmle <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,type = "mle")
#> Estimating: 2pl model ... #> type = mle #> Estimation finished!
# WLE res2plwle <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,type = "wle")
#> Estimating: 2pl model ... #> type = wle #> Estimation finished!
# MAP estimation res2plmap <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,type = "map")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 2pl model ... #> type = map #> Estimation finished!
# EAP estimation res2pleap <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,type = "eap")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 2pl model ... #> type = eap #> Estimation finished!
# robust estimation res2plrob <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,type = "robust")
#> Estimating: 2pl model ... #> type = robust #> Estimation finished!
## 3PL model ##### # MLE res3plmle <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,type = "mle")
#> Estimating: 3pl model ... #> type = mle #> Estimation finished!
# WLE res3plwle <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,type = "wle")
#> Estimating: 3pl model ... #> type = wle #> Estimation finished!
# MAP estimation res3plmap <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,type = "map")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 3pl model ... #> type = map #> Estimation finished!
# EAP estimation res3pleap <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la, type = "eap")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 3pl model ... #> type = eap #> Estimation finished!
## 4PL model ##### # MLE res4plmle <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,upperA=ua,type = "mle")
#> Estimating: 4pl model ... #> type = mle #> Estimation finished!
# WLE res4plwle <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,upperA=ua,type = "wle")
#> Estimating: 4pl model ... #> type = wle #> Estimation finished!
# MAP estimation res4plmap <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,upperA=ua,type = "map")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 4pl model ... #> type = map #> Estimation finished!
# EAP estimation res4pleap <- PP_4pl(respm = awm,thres = diffpar, slopes = sl,lowerA = la,upperA=ua,type = "eap")
#> Warning: all mu's are set to 0!
#> Warning: all sigma2's are set to 1!
#> Estimating: 4pl model ... #> type = eap #> Estimation finished!
## A special on robust estimation: # it reproduces the example given in Schuster & Ke-Hai 2011: diffpar <- c(-3,-2,-1,0,1,2,3) AWM <- matrix(0,7,7) diag(AWM) <- 1 res1plmle <- PP_4pl(respm = AWM,thres = diffpar, type = "mle")
#> Estimating: 1pl model ... #> type = mle #> Estimation finished!
summary(res1plmle)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = AWM, thres = diffpar, type = "mle") #> - job started @ Mon May 24 13:27:53 2021 #> #> Estimation type: mle #> #> Number of iterations: 4 #> ------------------------------------- #> estimate SE #> [1,] -2.9409 1.2524 #> [2,] -2.9409 1.2524 #> [3,] -2.9409 1.2524 #> [4,] -2.9409 1.2524 #> [5,] -2.9409 1.2524 #> [6,] -2.9409 1.2524 #> [7,] -2.9409 1.2524
res1plrob <- PP_4pl(respm = AWM,thres = diffpar, type = "robust")
#> Estimating: 1pl model ... #> type = robust #> Estimation finished!
summary(res1plrob)
#> PP Version: 0.6.3.11 #> #> Call: PP_4pl(respm = AWM, thres = diffpar, type = "robust") #> - job started @ Mon May 24 13:27:53 2021 #> #> Estimation type: robust #> #> Number of iterations: 10 #> ------------------------------------- #> estimate SE #> [1,] -2.7467 1.2114 #> [2,] -2.7467 1.2114 #> [3,] -4.0393 1.6545 #> [4,] -4.2548 1.7791 #> [5,] -4.4176 1.8855 #> [6,] -4.5492 1.9800 #> [7,] -4.6600 2.0658