fit.FCGDINA: Fit the Forced-Choice GDINA Model

View source: R/fit.FCGDINA.R

fit.FCGDINAR Documentation

Fit the Forced-Choice GDINA Model

Description

Fits a forced-choice cognitive diagnostic model (FCGDINA) to comparative response data. The statement-level cognitive diagnosis component can be DINA, DINO, ACDM, or GDINA, and the block-level response model transforms statement endorsement probabilities into forced-choice probabilities for full rankings ("RANK"), most-least choices ("MOLE"), or best-only choices ("PICK").

Usage

fit.FCGDINA(
  data,
  Q.matrix,
  model = c("GDINA", "DINA", "DINO", "ACDM"),
  block.items = NULL,
  fc.type = NULL,
  method = c("EM", "stan", "iStEM"),
  control.model = NULL,
  control.method = NULL
)

Arguments

data

An N \times B forced-choice data matrix.

Q.matrix

An I \times D binary Q-matrix. Rows correspond to statements, columns correspond to attributes, and every row must contain at least one 1.

model

CDM item model: "GDINA", "DINA", "DINO", or "ACDM".

block.items

A list of length B. Each element gives the global statement indices in the corresponding forced-choice block. If NULL, the block structure is parsed from full-ranking character data when possible.

fc.type

Forced-choice response type: "RANK", "MOLE", or "PICK". A scalar is recycled to all blocks. If NULL, the type is inferred from character data when possible and otherwise defaults to "RANK".

method

Estimation method. "EM" (default) runs a deterministic posterior-weight EM algorithm, "stan" runs full Bayesian MCMC, and "iStEM" runs improved stochastic EM.

control.model

Optional list of model-level controls. For Stan, delta.mu and delta.sigma set the normal prior \delta \sim N(\mu, \sigma) for the free Stan FCGDINA logit-scale delta effects (defaults: 0 and 1). pi.prior.alpha sets the Dirichlet concentration for the structural parameters \pi (default 1, uniform prior over the simplex). For EM and iStEM, Stan priors are ignored; use delta.lower and delta.upper in control.method instead.

control.method

Optional list of method-specific controls.

Value

An object of class "FCGDINA", a list containing:

npar

Number of free CDM delta parameters.

method

Estimation method actually used: "stan", "iStEM", or "EM".

alpha

List with est, se, Rhat, and prob. est is an N \times D matrix of posterior attribute mastery probabilities; prob contains posterior probabilities for all 2^D attribute profiles.

delta

List with est, se, and Rhat. For Stan fits, each element is the probability-scale transform of the identified minimum-norm logit coefficient vector. Absolute statement endorsement probabilities are not identified by forced-choice data alone.

delta.identification

Stan-only rank, nullity, blockwise rank diagnostics, and the identifying convention.

delta.store

Stored posterior, iStEM, or bootstrap delta draws when available.

Q.matrix, block.items, patterns, patterns.total, design.matrix.list, alpha.patterns, fc.type, response

Processed model and data structures used by prediction, fit indices, and S3 methods.

stan.obj, MCMC.obj

Stan fit and extracted posterior draws for method = "stan"; otherwise NULL.

iStEM

iStEM convergence diagnostics and chains for method = "iStEM"; otherwise NULL.

EM

EM convergence diagnostics, log-likelihood trace, and bootstrap summary for method = "EM"; otherwise NULL.

logLik

Marginal log-likelihood with class "logLik".

call, arguments

Matched call and effective fitting arguments.

Model Specification

Let \boldsymbol{\alpha}_n \in \{0, 1\}^D denote the latent attribute profile for person n. For statement i, the binary Q-vector \mathbf{q}_i selects the required attributes and the reduced attribute pattern is mapped to a CDM design row \mathbf{x}_{ic}. For Stan estimation, \boldsymbol{\delta}_i is represented directly as the item-specific CDM effect vector on the logit scale: intercept, attribute main effects, and interaction effects. The item-level endorsement probability for attribute class c is

p_{ic} = \mathrm{logit}^{-1}(\mathbf{x}_{ic}' \boldsymbol{\delta}_i),

so main effects and interactions may be negative while probabilities remain in (0, 1). Forced-choice observations identify only within-block utility contrasts, not the absolute endorsement logits of individual statements. The Stan implementation therefore removes the exact null space of those contrasts and reports the unique minimum-norm coefficient representative. The design matrix is generated according to model: "DINA", "DINO", "ACDM", or "GDINA". EM and iStEM retain the existing probability-scale CDM parameterisation.

For each forced-choice block, the statement endorsement probabilities are converted to ranking-pattern probabilities by the same sequential Luce–Plackett transformation used by fit.FCMIRT and fit.FCGGUM. The likelihood marginalizes over all 2^D attribute profiles using a uniform latent-class prior:

P(\mathbf{Y}_n) = \sum_{c=1}^{2^D} \pi_c \prod_{b=1}^{B} P(Y_{nb} \mid \boldsymbol{\alpha}_c, \boldsymbol{\delta}, \mathrm{block}_b).

Data Coding

data must be an N \times B matrix, with one column per forced-choice block. Entries may be character rankings such as "2>1>3" or 1-based integer pattern indices. If integer pattern indices are supplied, block.items must be provided because item identities cannot be recovered from indices alone. For "MOLE" and "PICK" character data, supplying block.items is recommended and required whenever partial rankings do not identify all items in a block.

Estimation Controls

Common control.method entries are:

seed

Integer random seed.

cores

Number of cores used by Stan chains; ignored by the deterministic EM updates.

vis

Logical progress flag.

delta.lower, delta.upper

Lower and upper bounds for delta optimization in EM and iStEM. Defaults are -4 and 4.

Stan-specific entries include chains, iter, warmup, thin, init, algorithm, and the usual Stan control entries such as adapt_delta, max_treedepth, stepsize, and metric. Defaults are inherited from the common ForceChoice Stan helper: 4 chains, 2000 iterations, and half the iterations used as warmup. The default init = 0 is valid for Stan FCGDINA because it implies p_{ic} = 0.5 under the logit link.

iStEM-specific entries include M, B, burnin.maxitr, maxitr, eps1, eps2, frac1, frac2, optim.maxit, and estimate.se. Each iStEM update samples discrete attribute classes from the current posterior and optimises \delta parameters given the sampled class memberships.

EM-specific entries are:

maxitr

Maximum EM iterations; default 500.

minitr

Minimum EM iterations before convergence checks; default 2.

tol

Absolute log-likelihood change tolerance; default 1e-6.

par.tol

Maximum absolute delta-parameter change tolerance; default 1e-4.

optim.maxit

Maximum L-BFGS-B iterations for blockwise delta updates; default 200.

estimate.se

Logical; whether to estimate standard errors by nonparametric bootstrap. Default FALSE.

bootstrap

Number of bootstrap samples when estimate.se = TRUE. Default 100; must be at least 2.

References

de la Torre, J. (2011). The generalized DINA model framework. Psychometrika, 76(2), 179–199. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1007/s11336-011-9207-7")}

Templin, J., & Henson, R. A. (2006). Measurement of psychological disorders using cognitive diagnosis models. Psychological Methods, 11(3), 287–305. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1037/1082-989X.11.3.287")}

See Also

sim.data.FCGDINA, model.FCGDINA, get.fit.index.FCGDINA, fit.FCDCM, fit.FCMIRT, fit.FCGGUM

Examples

sim <- sim.data.FCGDINA(N.person = 20, N.block = 2, I.block = 2,
                        D = 2, model = "DINA", fc.type = "RANK")

fit <- fit.FCGDINA(
  sim$data,
  Q.matrix = sim$Q.matrix,
  block.items = sim$block.items,
  model = "DINA",
  fc.type = sim$fc.type,
  method = "EM",
  control.method = list(seed = 123, vis = FALSE,
                        maxitr = 2, estimate.se = FALSE)
)

coef(fit, type = "par")
head(fit$alpha$est)
logLik(fit)


# stan code, long time
fit.stan <- fit.FCGDINA(
  sim$data,
  Q.matrix = sim$Q.matrix,
  block.items = sim$block.items,
  model = "GDINA",
  method = "stan",
  control.method = list(seed = 123, cores = 2,
                        chains = 1, iter = 200, warmup = 100)
)



ForceChoice documentation built on Sept. 13, 2026, 1:06 a.m.