티스토리 뷰

PerFit 패키지의 lz, lzstar는 응답의 비정상 여부를 판단하는 Person-fit statistics를 계산해 준다. 문제는 lz, lzstar는 ltm::ltm 함수를 기본으로 하는데 이 ltm은 parameter에 범위를 지정할 수가 없다. 따라서 mirt로 fit한 결과를 활용하여 lz, lzstar를 구하는 방법을 생각해보았다.

R package PerFit has functions like lz and lzstar which return person fit statistics. The problem is that these functions are based on ltm::ltm but ltm::ltm can set bounds on parameters which is easily incorporated by mirt::mirt. So I figured out the way to use mirt fit for lz and lzstar. 


한 가지 주의할 점은 mirt와 ltm은 서로 다른 방식의 parametrization을 이용한다는 점이다. 흔히 말하는 IRT 파라미터는 난이도와 변별도를 쓴다. mirt::coef(    , IRTpars=T, digits=Inf)을 써야 한다.

One thing to be cautious about is that mirt and ltm have different way of parametrization. Bare in mind. mirt::coef(   , IRTpars=T, digits=Inf)


library(mirt)

library(ltm) # install.packages(c("ltm", "PerFit"))

library(PerFit)


NCYCLES = 10000


coef2mat = function(cf) {

  stopifnot(is.list(cf))

  do.call(rbind, cf[1:(length(cf)-1)])

}


#http://www.r-bloggers.com/five-ways-to-visualize-your-pairwise-comparisons/

panel.cor <- function(x, y, digits=2, prefix="", cex.cor) 

{

  usr <- par("usr"); on.exit(par(usr)) 

  par(usr = c(0, 1, 0, 1)) 

  r <- abs(cor(x, y)) 

  txt <- format(c(r, 0.123456789), digits=digits)[1] 

  txt <- paste(prefix, txt, sep="") 

  if(missing(cex.cor)) cex <- 0.8/strwidth(txt) 

  

  test <- cor.test(x,y) 

  # borrowed from printCoefmat

  Signif <- symnum(test$p.value, corr = FALSE, na = FALSE, 

                   cutpoints = c(0, 0.001, 0.01, 0.05, 0.1, 1),

                   symbols = c("***", "**", "*", ".", " ")) 

  

  text(0.5, 0.5, txt, cex = cex * r) 

  text(.8, .8, Signif, cex=cex, col=2) 

}


Pairs <- function(x, ...) {

  stopifnot(is.matrix(x) | is.data.frame(x))

  pairs(x, lower.panel=panel.smooth, upper.panel=panel.cor)

}


R <- simdata(a=c(1,0.8,1.2,1.5), d=c(-2,-1,0,1,2), 200, itemtype="dich")

# Compare the personfit from mirt and lz

# mirt::personfit(  , method="ML","EAP","MAP","WLE")$Zh

# PerFit::lz(       , method="ML",     ,"BM", "WL")$PFscores$PFscores


# Compare the personfit from mirt and lz with coefs from mirt and lz

fitMirt <- mirt(R, 1, itemtype="2PL", technical = list(NCYCLES=NCYCLES))

#fitLtm <- ltm(R ~ z1, control=list(GHk=61, iter.em=NCYCLES, iter.qN=1000))

fitLtm <- ltm(R ~ z1, control=list(GHk=61, iter.em=NCYCLES))


# Convergence?

fitMirt@OptimInfo$converged

fitLtm$convergence


# logLik

fitMirt@Fit$logLik

fitLtm$log.Lik


# Coefficients

IPMirt <- coef2mat(coef(fitMirt, IRTpars=T, digits=Inf))[,1:2]

IPMirt <- cbind(IPMirt, 0)



IPLtm <- coef(fitLtm)

IPLtm <- IPLtm[,c(2,1)]

IPLtm <- cbind(IPLtm, 0)

IPLtm


Pairs(data.frame(IPMirt[,"a"], IPLtm[,"Dscrmn"], IPMirt[,"b"], IPLtm[,"Dffclt"]))


# theta Estimates

thLtmEAP <- factor.scores(fitLtm, method="EAP", resp.patterns=R)$score.dat$z1

thLtmEB <- factor.scores(fitLtm, method="EB", resp.patterns=R)$score.dat$z1


thMirtML <- fscores(fitMirt, full.scores=T, method="ML")[,1]

thMirtEAP <- fscores(fitMirt, full.scores=T, method="EAP")[,1]

thMirtWLE <- fscores(fitMirt, full.scores=T, method="WLE")[,1]

thMirtMAP <- fscores(fitMirt, full.scores=T, method="MAP")[,1]


thIrtoysML <- irtoys::mlebme(R, IPLtm, method="ML")[,1]

thIrtoysBM <- irtoys::mlebme(R, IPLtm, method="BM")[,1]


lapply(data.frame(thLtmEAP, thMirtEAP, thLtmEB, thMirtMAP, thIrtoysBM, thMirtML,  thIrtoysML, thMirtWLE),

       function(x) c(nan = sum(is.nan(x)), na = sum(is.na(x)), inf = sum(is.infinite(x)),

                     min = min(x), max = max(x)))

plot(data.frame(thLtmEAP, thMirtEAP, thLtmEB, thMirtMAP, thIrtoysBM, thMirtML,  thIrtoysML, thMirtWLE))

Pairs(data.frame(thLtmEAP, thMirtEAP, thLtmEB, thMirtMAP, thIrtoysBM, thMirtML,  thIrtoysML, thMirtWLE))

thMirtML2 <- thMirtML

thMirtML2[is.infinite(thMirtML2)] = 6 * sign(thMirtML2[is.infinite(thMirtML2)])

Pairs(data.frame(thLtmEAP, thMirtEAP, thLtmEB, thMirtMAP, thIrtoysBM, thMirtML2,  thIrtoysML, thMirtWLE))


# -Inf vs -3.99995(for thMirtML/thIrtoysML)


# personfit from Ltm and Mirt

lzMirtML <- personfit(fitMirt, method="ML")[,"Zh"]

lzMirtEAP <- personfit(fitMirt, method="EAP")[,"Zh"]

lzMirtWLE <- personfit(fitMirt, method="WLE")[,"Zh"]

lzMirtMAP <- personfit(fitMirt, method="MAP")[,"Zh"]


lzPFML <- lz(R, Ability.PModel = "ML")$PFscores$PFscores

lzPFBM <- lz(R, Ability.PModel = "BM")$PFscores$PFscores

lzPFWL <- lz(R, Ability.PModel = "WL")$PFscores$PFscores


plot(data.frame(lzMirtML, lzPFML, lzMirtEAP, lzMirtWLE, lzPFWL, lzMirtMAP, lzPFBM))

Pairs(data.frame(lzMirtML, lzPFML, lzMirtEAP, lzMirtWLE, lzPFWL, lzMirtMAP, lzPFBM))


# personfit from Ltm using irtoys

lzPFML.ltm <- lz(R, Ability.PModel = "ML",  IP=IPLtm, Ability = thIrtoysML)$PFscores$PFscores

lzPFBM.ltm <- lz(R, Ability.PModel = "BM",  IP=IPLtm, Ability = thIrtoysBM)$PFscores$PFscores

plot(data.frame(lzPFML, lzPFML.ltm, lzPFBM, lzPFBM.ltm))

Pairs(data.frame(lzPFML, lzPFML.ltm, lzPFBM, lzPFBM.ltm))


# personfit from Mirt using Mirt

lzMirtML.mirt <- personfit(fitMirt, Theta = matrix(thMirtML, ncol=1))

lzMirtMAP.mirt <- personfit(fitMirt, Theta = matrix(thMirtMAP, ncol=1))

lzMirtWLE.mirt <- personfit(fitMirt, Theta = matrix(thMirtWLE, ncol=1))

plot(data.frame(lzMirtML, lzMirtML.mirt, lzMirtMAP, lzMirtMAP.mirt, lzMirtWLE, lzMirtWLE.mirt))

Pairs(data.frame(lzMirtML, lzMirtML.mirt, lzMirtMAP, lzMirtMAP.mirt, lzMirtWLE, lzMirtWLE.mirt))


# personfit from Ltm using Mirt

lzPFML.Mirt <- lz(R, Ability.PModel = "ML",  IP=IPMirt, Ability = thMirtML)$PFscores$PFscores

lzPFML.Mirt2 <- lz(R, Ability.PModel = "ML",  IP=IPMirt, Ability = thMirtML2)$PFscores$PFscores

lzPFBM.Mirt <- lz(R, Ability.PModel = "BM",  IP=IPMirt, Ability = thMirtMAP)$PFscores$PFscores

lzPFWL.Mirt <- lz(R, Ability.PModel = "WL",  IP=IPMirt, Ability = thMirtWLE)$PFscores$PFscores

plot(data.frame(lzPFML, lzPFML.Mirt, lzPFWL, lzPFWL.Mirt, lzPFBM, lzPFBM.Mirt))

Pairs(data.frame(lzPFML, lzPFML.Mirt, lzPFWL, lzPFWL.Mirt, lzPFBM, lzPFBM.Mirt))

Pairs(data.frame(lzPFML, lzPFML.Mirt2, lzPFWL, lzPFWL.Mirt, lzPFBM, lzPFBM.Mirt))


# personfit from Mirt using irtoys

fitMirtTemp <- mirt(R, 1, itemtype="2PL", pars="values")

fitMirtTemp[fitMirtTemp$name == "a1","value"] = IPLtm[,"Dscrmn"]

fitMirtTemp[fitMirtTemp$name == "d","value"] = -IPLtm[,"Dffclt"]*IPLtm[,"Dscrmn"]

fitMirtTemp2 <- mirt(R, 1, itemtype="2PL", pars=fitMirtTemp, TOL=NaN)


lzMirtBM.irtoys <- personfit(fitMirtTemp2, Theta = matrix(thIrtoysBM, ncol=1))

lzMirtML.irtoys <- personfit(fitMirtTemp2, Theta = matrix(thIrtoysML, ncol=1))


plot(data.frame(lzMirtMAP, lzMirtBM.irtoys, lzMirtML, lzMirtML.irtoys), bg="blue")

Pairs(data.frame(lzMirtMAP, lzMirtBM.irtoys, lzMirtML, lzMirtML.irtoys), bg="blue")


#So the correlations are at least 0.99



'차기작 : R을 배우자' 카테고리의 다른 글

Fitting GRSM ( a.k.a RS-GRM)  (0) 2016.04.18
long form/wide form(conceptual understanding and R implementation)  (0) 2016.04.04
fitting RSM  (0) 2016.01.30
I have a table!  (0) 2015.11.11
Naming files by date  (0) 2015.11.11
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함