
Sensitivity on the noise, signal, or root-mean-square scale
Source:R/helpers-analysis.R
sdt_sensitivity.RdRe-expresses the posterior sensitivity of a fitted SDT model against a
different reference standard deviation. As long as sdratio is fixed at its
default, d is the familiar \(d'\) and all three scales below are the same
number. Once sdratio is estimated, d is \(d_a\), which measures the
separation of the two evidence distributions in units of their
root-mean-square SD, and the same separation can also be read against the
noise SD (\(d_N\), the classical \(d'\)) or against the signal SD
(\(d_S\)). This function returns any of the three as posterior draws, so
contrasts and intervals can be computed on whichever scale a literature
reports.
Arguments
- fit
A
bmmfitobject returned bybmm()from an SDT model.- measure
Character vector naming the scales to return:
"da"(root-mean-square SD, the estimated parameter),"dn"(noise SD), and/or"ds"(signal SD). Defaults to all three.- conditions
Optional data frame of predictor values at which to evaluate the model. Column names must match predictor variables used in the formula. If
NULL(default), unique predictor combinations are derived from the data.- probs
Numeric vector of length 2. Lower and upper quantiles for the credible interval (default
c(0.025, 0.975)).- ...
Additional arguments passed to
brms::posterior_linpred(), such asdraw_idsto use a subset of the posterior draws.ndrawsis refused: each parameter is drawn by its own call, so random subsets would not match across parameters.
Value
A data frame of class "bmm_sdt_sensitivity" with columns measure,
value, .draw, and any condition columns. The object carries a summary
attribute (measure, mean, lower, upper, plus condition columns),
and probs, model_class, dist and conditions attributes.
Details
The model places the noise distribution at \(-\delta/2\) with SD \(\sigma_N = 1\) and the signal distribution at \(+\delta/2\) with SD \(\sigma_S = \exp(\mathrm{sdratio})\), so \(\delta\) is the separation in noise-SD units. Dividing that separation by each reference SD gives
$$d_N = \delta / \sigma_N, \quad d_S = \delta / \sigma_S, \quad d_a = \delta / \sqrt{(\sigma_N^2 + \sigma_S^2)/2}.$$
The estimated parameter is \(d_a\), hence \(\delta = d_a \sqrt{(1 + \sigma_S^2)/2}\) and
$$d_N = d_a \sqrt{(1 + \sigma_S^2)/2}, \qquad d_S = d_a \sqrt{(1 + \sigma_S^2)/2} \,/\, \sigma_S.$$
All three coincide when sdratio is 0 (equal variance), which is the case
for sdt_mafc() and for any fit that leaves sdratio at its default of 0.
The conversion is applied draw by draw, so the returned intervals propagate the
joint posterior uncertainty in d and sdratio rather than combining
point estimates.
Only \(d_a\) is invariant to which distribution is treated as the
reference. \(d_N\) and \(d_S\) are not comparable across conditions that
differ in sdratio: two conditions with identical discriminability can show
a large, confidently estimated \(d_N\) difference. Prefer \(d_a\) for
contrasts, and use \(d_N\)/\(d_S\) for comparison with published values.
When sdratio is estimated but constant across the conditions being
compared, all three differ by one common factor per draw and give the same
contrasts up to scale.
The criterion and rating thresholds are not converted: they stay on the
noise-SD axis whichever sensitivity scale you report. Under the Gumbel
distributions with sdratio estimated, none of the three is the
AUC-equivalent index; use auc_sdt() to compare discriminability on the
probability scale.
Examples
if (FALSE) { # \dontrun{
# Three base-rate conditions shift the criterion, which identifies sdratio
dat <- expand.grid(id = 1:20, stimulus = c(0L, 1L),
condition = c("liberal", "neutral", "strict"))
dat$n_trials <- 100L
# simulated as bias, measured from the midpoint between the means (0 = boundary at the midpoint)
criteria <- c(liberal = -0.5, neutral = 0, strict = 0.5)
dat$n_old <- rsdt_yn(nrow(dat), dat$n_trials, dat$stimulus, d = 1.5,
bias = criteria[as.character(dat$condition)],
sdratio = 1.3)
fit <- bmm(
formula = bmf(d ~ 1, criterion ~ 0 + condition, sdratio ~ 1),
data = dat,
model = sdt_yn(response = "n_old", stimulus = "stimulus",
n_trials = "n_trials"),
cores = 4,
backend = "cmdstanr"
)
# d_a (the fitted d), d_N and d_S, converted draw by draw
sdt_sensitivity(fit)
sdt_sensitivity(fit, measure = "dn", draw_ids = 1:500)
} # }