Find the predictor value at which posterior_epred(model) = x (in a multilevel logistic regression)

Context

Hello,

I am modelling behavioural data with a multilevel model specified as:

model <- brm(
    formula = resp ~ 1 + test * stim * trial + (1 + test * stim * trial | dyad / ppt),
    family = bernoulli(link = "logit"),
    data = df
    )

where resp is thus a binary (0/1) variable, test is a binary (factor) predictor with two levels (“individual” and “interactive”, contrast-coded as -0.5/+0.5), stim is a numerical variable, trial is also a numerical variable, ppt refers to the participant’s ID and dyad refers to the dyad in which the participant belongs (therefore ppt is nested within dyad).

I am particularly interested in the interaction effect between stim and test, for all possible values of trial. With some help from the brms::conditional_effects() function, I can retrieve the estimates of p(resp) for each crossing of stim, test, and trial (i.e., the output of posterior_epred()) using the following code (where the trial is represented in colour, and test levels in columns):

cond_effects <- conditional_effects(
    model,
    conditions = data.frame(trial = unique(model$data$trial) ),
    effects = "stim:test",
    method = "posterior_epred",
    plot = FALSE
    )[[1]]

cond_effects %>%
    ggplot(aes(x = stim, y = estimate__, color = as.factor(trial) ) ) +
    geom_hline(yintercept = 0.5, linetype = 2) +
    geom_line(show.legend = FALSE) +
    facet_wrap(~test) +
    scale_color_viridis_d() +
    theme_bw() +
    labs(
        x = "Standardised trial",
        y = "Predicted probability",
        color = "Trial"
        )

Then, I am interested in the same effect for each participant, which I can also retrieve using conditional_effects(). Below is an example for two participants (in columns, and for the two test levels, in rows).

# creating a grid of values for predictions for only two participants
conditions <- crossing(
    trial = unique(df_trial$trial),
    ppt = c("6_06_A", "6_06_B")
    )

# computing conditional effects for each participant and trial
cond_effects <- conditional_effects(
    x = trial_model,
    effects = "stim:test",
    conditions = conditions,
    method = "posterior_epred",
    re_formula = NULL,
    resolution = 500,
    plot = FALSE
    )[[1]]

The problem

Now, I want to compute the value of stim for which p(resp) = 0.5 (i.e., posterior_epred(model)=0.5, for each ppt, test, and trial.

If we ignore the random/varying effects (intercepts and slopes), and if we only had one slope, this would be given by -\alpha / \beta (i.e., minus the intercept divided by the slope). But because the model involves several interactions and random/varying slopes, I am struggling a bit to compute this “threshold” (as called in Kruschke’s book, adapted to brms here: 21 Dichotomous Predicted Variable | Doing Bayesian Data Analysis in brms and the tidyverse).

What I have tried

I have tried to extend the analytical solution above to include interactions and varying slopes, but I am not fully satisfied with the results (they look weird), so I am wondering whether there is any implemented function that could help?

I have also tried to numerically approximate the value of stim for which p(resp)=0.5 from the output of conditional_effects(), but that is not fully satisfying either (it is not very precise and computationally intensive).

Do you have any idea how to compute this in a more principled way? In brief, I am looking for something to perform the inverse operation that is performed by posterior_epred(). Instead of computing the value of p(resp) given some model parameters, I want to compute the value of stim for which p(resp)=0.5 (for all possible combinations of test, ppt, and trial).

Thank you in advance for your help!

Ladislas

Hi @Ladislas yeah this is a very useful calculation and sometimes confusing with lots of interactions! How have you calculated this for just one predictor? If you use index variables (ie estimate the slope for all conditions vs their differences) would that help?

Hi,

thank you very much for your reply!

The solution -\alpha/\beta comes from Kruschke’s book and Solomon Kurz’ translation in brms (see link in my original post), but it’s a general property of the logit function I guess (solving for logit(p=0.5) = 0) (this is the point of the steepest slope, also known as the “median effective level”).

You are right that using an index variable may facilitate the computation, although I am not sure to understand how that would be different from retrieving the predictions using conditional_effects()? I already have retrieved the predictions (i.e., p(resp)) in each condition of interest. What I don’t know, is how to compute is the value of stim for which p(resp)=0.5 (in each condition).

Ladislas

What I meant is that if for each condition z (the index) you have alphaz and betaz computing the point of subjective equality for each z is trivial.

Oh, OK I got it now, sorry for the misunderstanding. In this situation, this would entail estimating the intercept and slope for each trial (and test and participant), thus going from estimating only one slope for trial (currently treated as a numeric variable) to as many slopes as there are trials, if I understood correctly. I am not sure this sort of model would converge, but I can try!