SE for a and b parameters for the 2-parameter Logistic Model on 3 binary items

153 views
Skip to first unread message

aniramfoggy

unread,
Sep 13, 2021, 5:45:13 AM9/13/21
to mirt-package
Hi there,
I'm new to mirt and would appreciate your help.
Specifically, I'm trying to get the SE for a and b parameters for the 2-parameter Logistic Model on 3 binary items (also the df for X2* item fit statistic, further below).
Here is the information regarding the 3 items and the 2-PL model:
#select items:
podaci.CRT3.rec <- as.data.frame(select(df.NA, CRT1:CRT3))
psych::describe(podaci.CRT3.rec)
#vars   n mean  sd median trimmed mad min max range  skew kurtosis   se
#CRT1    1 448 0.43 0.5      0    0.41   0   0   1     1  0.29    -1.92 0.02
#CRT2    2 448 0.49 0.5      0    0.48   0   0   1     1  0.05    -2.00 0.02
#CRT3    3 448 0.51 0.5      1    0.51   0   0   1     1 -0.04    -2.00 0.02

#2PL model:
fit.crt3 <- mirt(podaci.CRT3.rec, model = 1, calcNull = T) #calcNull - logical; calculate the Null model for additional fit statistics (e.g., TLI)? Only applicable if the data contains no NA's and the data is not overly sparse

#Get fit indices:
fit.crt3@Fit
#$G2
#[1] 0.0004630958  

#$p
#[1] 0.9828311

#$TLI
#[1] 1.016118

#$CFI
#[1] 1

#$RMSEA
#[1] 0

#$df
#[1] 1

#$AIC
#[1] 1613.402

#$AICc
#[1] 1613.593

#$BIC
#[1] 1638.031

#$SABIC
#[1] 1618.989

#$HQ
#[1] 1623.111

#$logLik
#[1] -800.701

#$logPrior
#[1] 0

#$SElogLik
#[1] 0

#$F
#F1
#CRT1 0.8504659
#CRT2 0.7118403
#CRT3 0.8996261

#$h2
#CRT1      CRT2      CRT3 
#0.7232922 0.5067166 0.8093271 

Here is where I get stuck - although I have specified "printSE = T", I get only the and b parameter estimates but not their SE:
#GET the COEFFICIETS with STANDARD ERRORS:
coef(fit.crt3, IRTpars = T, printSE = T )

#$CRT1
 #       a        b         g u
#par 2.752 0.213 0 1

#$CRT2
#       a        b         g u
#par 1.725 0.047 0 1

#$CRT3
#       a        b         g u
#par 3.507 -0.031 0 1

#$GroupPars
 #   MEAN_1 COV_11
#par      0      1

Also, it's worth saying that when I don't specify "printSE = T" (i.e., coef(fit.crt3, IRTpars = T)), I don't get the confidence intervals that I do get with the 2-PL model with 8 binary items.

Also, since there are only 3 items, the S_X2 and X2 (X2 is pretty much useless anyway, given inflated Type I error rates) item fit indices cannot be calculated: Thus, I use the X2*:
itemfit(fit.crt3, na.rm = T, fit_stats = "X2*")
#item X2_star p.X2_star
#1 CRT1   0.031     0.791
#2 CRT2   0.056     0.889
#3 CRT3   0.016     0.740
But, I do not know how to get the degrees of freedom for X2*. How can I obtain them?

Finnaly, I've tried boot.mirt for bootstrapped confidence intervals, and I get the parameter a estimates ( t1*,  t3*,  t5*, they are the same as the "a" estimates I get with coef(fit.crt3, IRTpars = T, printSE = T )), but not the parameter b estimates (t2*,  t4*,  t6*, they differ from the "b" estimates I get with coef(fit.crt3, IRTpars = T, printSE = T )) instead of which I get the 
boot.mirt(fit.crt3, R = 100)
#ORDINARY NONPARAMETRIC BOOTSTRAP       
#        Call:
#                boot::boot(data = dat, statistic = boot.draws, R = R, npars = npars, 
#                           constrain = constrain, class = class, parprior = parprior, 
#                           model = model, itemtype = itemtype, group = group, LR = LR, 
#                           obj = x, technical = technical)
#        
        
#        Bootstrap Statistics :
#                original       bias    std. error
#        t1*  2.75172966  0.161429860   0.6073123
#        t2* -0.58673221 -0.074924130   0.2534655
#        t3*  1.72501883  0.119301687   0.2837102
#        t4* -0.08147124 -0.009537416   0.1475875
#        t5*  3.50652627  0.671293226   2.0593330
#        t6*  0.10958272  0.006503643   0.2608795


I am really lost and would very much appreciate your help!

Thank you in advance.

Kind regards,
Marina

Phil Chalmers

unread,
Sep 20, 2021, 1:53:52 PM9/20/21
to aniramfoggy, mirt-package
Standard errors are not computed by default due to the use of the EM algorithm default; hence, you need to pass mirt(..., SE = TRUE). 

X2* doesn't follow the usual df comparison in the large sample sense, and instead uses a bootstrapping methodology based on resampling and permutations. 

Regarding the bootstrap, I believe this is only supported for the slope-intercept parameterizations. It's possible to pass a secondary function to boot.mirt(), but this is currently not supported. I'll consider adding this to the next version of the package. HTH.

Phil


--
You received this message because you are subscribed to the Google Groups "mirt-package" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mirt-package...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mirt-package/3c6f5d8b-fc05-48a1-89a9-826f10977dfbn%40googlegroups.com.

aniramfoggy

unread,
Nov 11, 2021, 12:55:08 PM11/11/21
to mirt-package
 Hi Phill,
 I appreciate your time and effort to help end educate us all!

I just want to make something clearer for myself - in the case of a 2PL model on 3 binary variables (sample size of 448 with no missing values), the M2() statistic cannot be calculated due to too few degrees of freedom, isn't that right?
But, the G2() statistic can be calculated, and the degrees of freedom are equal to 1, isn't that right?

Specifying the following: itemfit(fit.2pl.model, c('X2*')) the X2*  statistic for the three items are produced, together with the accompanying p values, but the degrees of freedom cannot be calculated, isn't that right?
  item X2_star p.X2_star
1 CRT1   0.031     0.789
2 CRT2   0.056     0.909
3 CRT3   0.016     0.783

And, by specifying the following:  itemfit(fit.2pl.model, fit_stats = "X2*_df" ), the scaled X2*  with scaled degrees of freedom (in this case they are < 1) are calculated. How are they scaled? And what is better to report - X2* or scaled X2*?
item X2_star_scaled df.X2_star_scaled RMSEA.X2_star_scaled p.X2_star_scaled
1 CRT1          0.858             0.180                0.092            0.061
2 CRT2          0.840             0.419                0.047            0.149
3 CRT3          1.062             0.514                0.049            0.150

Thank you once again.

P.s. the data is attached (data_448.csv) and the specification of the 2PL model on 3 binary variables is:
#selectiong the 3 variables (CRT1, CRT2, CRT3)
podaci.CRT3.rec <- as.data.frame(dplyr::select(df.NA.zaCRT3, CRT1:CRT3))

#Model:
fit.crt3.2pl <- mirt(podaci.CRT3.rec, model = 1, calcNull = T,  SE = T)
print(fit.crt3.2pl) #get fit indices
#Log-likelihood = -800.701
#Estimated parameters: 6 
#AIC = 1613.402; AICc = 1613.593
#BIC = 1638.031; SABIC = 1618.989
#G2 (1) = 0, p = 0.9828
#RMSEA = 0, CFI = 1, TLI = 1.016


#item parameters with SE
coef(fit.crt3.2pl , IRTpars = T, printSE = T )
#$CRT1
#a     b  g  u
#par 2.752 0.213  0  1
#SE  0.545 0.072 NA NA

#$CRT2
#a     b  g  u
#par 1.725 0.047  0  1
#SE  0.255 0.083 NA NA

#$CRT3
#a      b  g  u
#par 3.507 -0.031  0  1
#SE  0.908  0.066 NA NA

#$GroupPars
#MEAN_1 COV_11
#par      0      1
#SE      NA     NA




Kind regards,
Marina
data_N448.csv

Phil Chalmers

unread,
Nov 15, 2021, 3:31:48 PM11/15/21
to aniramfoggy, mirt-package
On Thu, Nov 11, 2021 at 12:55 PM aniramfoggy <morni...@gmail.com> wrote:
 Hi Phill,
 I appreciate your time and effort to help end educate us all!

I just want to make something clearer for myself - in the case of a 2PL model on 3 binary variables (sample size of 448 with no missing values), the M2() statistic cannot be calculated due to too few degrees of freedom, isn't that right?

That sounds correct. There are k(+1)/2 = 3(4)/2 = 6 unique degrees of freedom for first two moments, and three 2PL models would have 6 estimated parameters, and so M2() should complain.
 
But, the G2() statistic can be calculated, and the degrees of freedom are equal to 1, isn't that right?

In this case, yes that sounds correct. 2^3 - 1 = 7 unique cell df combinations with 6 estimated parameters.
 

Specifying the following: itemfit(fit.2pl.model, c('X2*')) the X2*  statistic for the three items are produced, together with the accompanying p values, but the degrees of freedom cannot be calculated, isn't that right?
  item X2_star p.X2_star
1 CRT1   0.031     0.789
2 CRT2   0.056     0.909
3 CRT3   0.016     0.783

And, by specifying the following:  itemfit(fit.2pl.model, fit_stats = "X2*_df" ), the scaled X2*  with scaled degrees of freedom (in this case they are < 1) are calculated. How are they scaled? And what is better to report - X2* or scaled X2*?
item X2_star_scaled df.X2_star_scaled RMSEA.X2_star_scaled p.X2_star_scaled
1 CRT1          0.858             0.180                0.092            0.061
2 CRT2          0.840             0.419                0.047            0.149
3 CRT3          1.062             0.514                0.049            0.150

Thank you once again.

The scaled df are estimated from the Monte Carlo simulations, so you'd have to refer to the original publications on how this is obtained. That said, I think with only 3 items there isn't much that you can do in terms of fit. Also, with only 3 items the measurement precision of the latent traits will be extremely high, so it's questionable how useful the estimates of the latent traits (read: composite scores) will be in this context....
 

aniramfoggy

unread,
Nov 15, 2021, 5:01:34 PM11/15/21
to mirt-package
Dear Phill,
thank you once again, I greatly appreciate your answers!

Best,
Marina

Reply all
Reply to author
Forward
0 new messages