Multinomial Processing Tree (MPT) models measure the probabilities of
discrete latent cognitive states from categorical responses. A model is
specified as a set of trees created with mpt_tree(), one per distinct
branch structure, such as one tree for targets and one for lures in a
recognition test. Branch expressions that terminate in the same response
category are summed within each tree, and parameters shared across trees
are equated by giving them the same name. All latent probability
parameters are estimated on an unconstrained latent scale (logit or
probit); predictor formulas supplied via bmmformula() apply on that
latent scale.
Usage
mpt(
trees,
tree_id = NULL,
covariates = NULL,
simplex = NULL,
restrictions = NULL,
links = "logit",
...
)Arguments
- trees
A single
mpt_treeobject or a list ofmpt_treeobjects. All trees must share the same set of response categories, counting those declared impossible.- tree_id
Character. Name of the data column whose values name the tree each observation belongs to; the values must match the tree names. Can be omitted for single-tree models. Effects of experimental conditions belong in the parameter formulas, not here; see Details.
- covariates
Character vector. Names of data columns that appear in branch expressions but are not latent parameters, for example design-fixed guessing rates. Covariates pass into the model formulas unchanged and have no naming restrictions.
bmm()stops when, with a row's covariate values, the branches of a tree do not sum to 1, leave (0, 1], are undefined on the rows of another tree, or when a covariate that a branch uses is missing. Every declared covariate needs a numeric column in the data, also one that no branch uses. The range is checked at the vertices of each branch's parameter box, which is exact when no term of the branch contains the same parameter twice (a * (1 - b) * G + (1 - a) * c). A parameter that does is also checked at 0.5, which is exact for a factoru * (1 - u)and approximate otherwise, e.g. foru * (1 - u)^2.- simplex
A character vector, or a list of character vectors, naming groups of parameters that are jointly constrained to sum to 1. Each group is reparameterized via stick-breaking: the last parameter of each group is derived as 1 minus the sum of the other members, and each other member
pgets an unconstrained componentprawthat predictor formulas forpare applied to. The listing order sets the default prior and the meaning of the coefficients; see Details.- restrictions
Parameter restrictions in the string syntax of MPTinR and TreeBUGS, e.g.
c("Dn = Do", "g = 0.5"), or as a named list,list(Dn = "Do", g = 0.5). A restriction either equates a parameter with another one (chains such as"G1 = G2 = G3"map all earlier names onto the last) or fixes it to a numeric constant ("g = 0.5";bmmalso reads fractions such as"g = 1/4", which MPTinR rejects). Constants must lie strictly between 0 and 1. The unnamed list of MPTinR and TreeBUGS,list("Dn = Do", "g = 0.5"), works as well. Restriction files are not read: in MPTinR and TreeBUGS a character vector names a restrictions file, inbmmit holds the restrictions. To use such a file, passreadLines(path); blank lines and lines starting with#are skipped, and a#after a restriction starts a comment, as in MPTinR. A restricted parameter is removed from the model; the Details say how this differs from fixing a parameter in the formula. Order constraints ("Do > Dn") are not supported here; see Details.- links
The link function of the latent probability parameters:
"logit"(default) or"probit". A single string sets every parameter; a named list,links = list(D = "probit"), sets the named parameters and leaves the others at"logit". Members of asimplexgroup and theirprawcomponents take no link of their own. A parameter switched to the other link, in the list or afterwards withmodel$links$D <- "probit", takes that link's default priors (see Details).- ...
used internally for testing, ignore it
Details
Domain: Categorical decision making, memory, and reasoning
Task: Any task with categorical responses generated by a discrete processing-tree structure
Name: Multinomial Processing Tree (MPT) models
Citation:
Batchelder, W. H., & Riefer, D. M. (1999). Theoretical and empirical review of multinomial process tree modeling. Psychonomic Bulletin & Review, 6(1), 57-86. https://doi.org/10.3758/BF03210812
The data hold aggregated counts: one row per participant and tree (and per condition, if conditions are crossed with the trees), with one count column per response category. The count columns must be named exactly like the branch names given to
mpt_tree()(oldandnewin the example below);bmm()finds them by these names, so no response variable is passed. Thetree_idcolumn names the tree of each row, and the counts of a row must come from trials of that tree. Wide tables with one column per category of an EQN file, as MPTinR and TreeBUGS take them, are reshaped withmpt_data_reshape().A separate tree is needed only when the branch expressions differ, that is, when the trial determines which latent processes apply or which response categories are reachable (targets versus lures, a response set with or without distractors, inclusion versus exclusion instructions). Experimental factors whose effect on the parameters you want to estimate belong in the parameter formulas, exactly as in every other
bmmmodel:bmf(D ~ 0 + condition). The two roles are independent, and one data column can serve both when a factor happens to change the structure as well. When several levels of a factor share a branch structure, add a column naming the tree and keep the factor for the formulas.Equating and fixing parameters. Parameters are equated across trees by giving them the same name. Beyond that, there are two mechanisms, and they differ in when the constraint is decided. A restriction (
restrictions = c("Dn = Do", "g = 0.5")) is applied when the model is built: it is substituted into the branch expressions before the parameters are identified, so the restricted parameter is not part of the model, gets no formula and no prior, cannot be a simplex member, and is listed byprint(model)underRestrictions:but not byparameter_info(). A constant in the formula (bmf(D ~ 1, g = 0.5)) is applied at fit time: the parameter stays part of the model, is listed byprint()underFixed:and byparameter_info()with its value, and is freed again by giving it a formula. The value is mapped to the latent scale when the constant prior is built, sodefault_prior()showsconstant(0)for a guessing rate of 0.5 under the logit link, andsummary()lists it asg_Intercept 0.00under "Constant Parameters";prior_info()andparameter_info()show the probability, 0.5. Members of asimplexgroup and theirprawcomponents cannot be fixed this way; fix parameters outside the group instead. As a rule of thumb, a constant that defines the model goes intorestrictions, a constant you compare against a free version goes into the formula; the section "Constraining parameters" of the MPT article walks through both.Default priors. Under the logit link, intercepts and regression coefficients get a
logistic(0, 1)prior and random-effect SDs getexponential(1). Under the probit link, intercepts and coefficients getnormal(0, 1)and SDs getexponential(2). Group-level correlation matrices getlkj(2). A parameter switched to the other link after construction (model$links$D <- "probit") takes that link's priors unless its default prior was replaced.default_prior()lists the rows a given formula produces.The default prior of a simplex group of K members is the uniform (symmetric Dirichlet(1)) distribution on the simplex: each member has prior mean 1/K, whatever the listing order. Under stick breaking this is a Beta(1, K - k) prior on stick k, which
default_prior()shows aslogitbeta(1, K - k)(orprobitbeta(1, K - k)) on the intercept of the k-thpraw; the last stick keepslogistic(0, 1)(ornormal(0, 1)), which is the same distribution. The result is exact under both links, and under0 + condit holds in every cell. Under1 + condit holds in the reference cell only, because the effects keep their own prior. TreeBUGS instead puts a uniform prior on each branch parameter, under which the first member has prior mean 0.5 (0.50/0.25/0.25 for three members). To get it for a groupgA,gB,gC,gD, passprior = brms::set_prior("logistic(0, 1)", nlpar = c("gAraw", "gBraw")), with"normal(0, 1)"under the probit link; withoutcoef, it covers every cell of a0 + condformula. A predictor on memberpacts on the logit (or probit) ofp's share of the probability left over by the members listed before it. A predictor on the first member therefore scales all later members by the same factor, leaving their ratios unchanged. Read such effects on the probability scale withnative_parameters().Identifiability. Printing the model ends with an identifiability check for intercept-only formulas. It compares the number of free parameters with the degrees of freedom (response categories minus 1, summed over trees) and computes the rank of the Jacobian of the category probabilities with respect to the free parameters, from exact derivatives at five interior test values (and five test values of each covariate); parameters fixed in the formula enter at their values. A rank below the number of free parameters means that a combination of the named parameters is not identified by the branch expressions, even when the count passes. The check is local: it holds at the test values, not at the boundaries of the parameter space. A test value with a non-finite derivative is left out, and the printout says how many; if
stats::D()cannot differentiate a branch expression, the rank is not computed and the count decides. The rank sees the tree parameters only: after a non-linear formula, the rank line names that formula's parameter as not analysed.bmm()warns when the rank is deficient and every formula is intercept-only. When a formula has a predictor or is non-linear, it only says that these may identify the parameters and that it did not check.Example: separate detection parameters
DoandDnin a single old/new test give three free parameters and rank 2 of 3, so one combination ofDo,Dnandgcannot be estimated; a second condition that varies the response bias identifies them.Reading the estimates.
summary()reports intercepts and regression coefficients on the latent (logit or probit) scale.native_parameters()returns the posterior draws of every parameter on the probability scale for each observed combination of the predictors, e.g.native_parameters(fit, re_formula = NA, summary = TRUE); a difference between conditions is the difference of these draws. Withre_formula = NAthese are the probabilities of the median participant (the quantity TreeBUGS reports as"mean"), not the population mean of the participants' probabilities; see the section on group-level effects innative_parameters().Person effects written as
(1 | id)in each parameter's formula are independent across parameters. A shared label,(1 |p| id)in every formula, estimates their correlations (priorlkj(2)), which corresponds to the latent-trait MPT model.For posterior predictive checks,
brms::posterior_predict()returns simulated counts (draws x rows x categories) andbrms::posterior_epred()the expected counts;ppp()computes the T1 and T2 statistics of Klauer (2010) and their posterior predictive p-values from them. Withnewdata,brms::posterior_predict()needs the columnsnTrials,Idx_<tree>andPoss_<category>thatcheck_data()builds;fit$datacontains them.Non-linear formulas. Parameters that receive a non-linear predictor formula (a formula whose right-hand side references other formula parameters, e.g.
D ~ Dmax * (1 - exp(-rate * ptime))) are not transformed by the link function: the user-supplied expression must keep the parameter within (0, 1). Sub-parameters of such formulas (e.g.,Dmaxandrate) are estimated on the identity scale withnormal(0, 1)default priors on their intercepts andnormal(0, 0.5)on their regression coefficients. Their random-effect SDs keep brms's default prior,student_t(3, 0, 2.5), because no single rate fits every scale such a formula can give them.Order constraints between parameters (
Do > Dn) are expressed by reparameterizing the larger parameter in the model formula, e.g.bmf(Do ~ Dn + (1 - Dn) * inv_logit(phi), Dn ~ 1, phi ~ 1); the section "Order constraints" of the MPT article walks through the recipe.Names. Parameter and response category names must start with a letter and may contain only letters and digits, because brms does not allow underscores or dots in non-linear parameter names.
All latent parameters are non-linear parameters of the underlying brms model, and brms has no separate
Interceptprior class for those: their intercept prior is stored asclass = "b", coef = "Intercept". A prior given asclass = "b", nlpar = "D"replaces the defaults of all coefficients ofD, the intercept included; addcoef = "Intercept"to set the intercept alone. Calldefault_prior()to see which rows a given formula produces.
Examples
if (FALSE) { # \dontrun{
# two-high-threshold (2HTM) model of recognition memory
# one tree per probe type: targets (studied items) and lures (new items),
# each ending in the responses "old" and "new"
tree_target <- mpt_tree("target",
old ~ D + (1 - D) * g,
new ~ (1 - D) * (1 - g)
)
tree_lure <- mpt_tree("lure",
old ~ (1 - D) * g,
new ~ D + (1 - D) * (1 - g)
)
model <- mpt(
trees = list(tree_target, tree_lure),
tree_id = "item_type"
)
# simulate data for 20 participants with D = 0.7, g = 0.5:
# one row per participant x tree; count columns named after the branches
data <- data.frame(
id = rep(1:20, each = 2),
item_type = rep(c("target", "lure"), 20)
)
counts <- t(sapply(data$item_type, function(cond) {
rmpt(
n = 1, size = 50, pars = c(D = 0.7, g = 0.5),
mpt_model = model, tree = cond, unpack = TRUE
)
}))
data <- cbind(data, counts)
# predict both parameters by a fixed intercept and correlated random
# intercepts (the shared label |p| estimates the correlation)
formula <- bmf(
D ~ 1 + (1 |p| id),
g ~ 1 + (1 |p| id)
)
fit <- bmm(
formula = formula,
data = data,
model = model,
cores = 4
)
summary(fit)
# population-level D and g on the probability scale
native_parameters(fit, re_formula = NA, summary = TRUE)
} # }
