I am reimplementing the change detection model from Lee&Wagenmakers Bayesian Cognitive Modeling (based on Smira’s earlier recoding).
The data (CognitiveModelingRecoded/13_data.txt at main · fusaroli/CognitiveModelingRecoded · GitHub) is generated by having a certain mean til time t and a different mean after. We want to infer t.
I am however only getting very slow sampling, both when coding it directly in Stan, and when using an equivalent brms model, and I am not sure whether I am missing more effective ways of coding the model.
Reprex is here: CognitiveModelingRecoded/13_ChangeDetection at main · fusaroli/CognitiveModelingRecoded · GitHub
data {
int n;
vector[n] t;
vector[n] c;
}
parameters {
vector[2] mu;
real<lower=0> sigma;
real<lower=0,upper=n> tau;
vector[2] muprior;
real<lower=0> sigmaprior;
}
model {
// Group Means
mu ~ normal(0, 10);
muprior ~ normal(0, 10);
// Standard deviation
sigma ~ normal(0, 10);
sigmaprior ~ normal(0, 10);
// Which Side is Time of Change Point?
// Data Come From A Gaussian
for (i in 1:n) {
if ((t[i] - tau) < 0.0)
c[i] ~ normal(mu[1], sigma);
else
c[i] ~ normal(mu[2], sigma);
}
}
Brms recoding
bform <- bf(
c ~ Intercept1 * step(change - t) + # Section 1
Intercept2 * step(t - change), # Section 2,
Intercept1 + Intercept2 ~ 1, # Fixed intercept and slopes
change ~ 1, # Per-person changepoints around pop mean
nl = TRUE
)
# Priors
bprior <- prior(normal(35, 10), nlpar = "Intercept1") +
prior(normal(35, 10), nlpar = "Intercept2") +
prior(uniform(0, 1178), nlpar = "change") # Within observed range
# Fit it!
m <- brm(
bform,
df,
family = gaussian,
prior = bprior,
sample_prior = T,
seed = 123,
chains = 1,
cores = 1,
iter = 500,
refresh=10,
backend = "cmdstanr",
threads = threading(2),
control = list(
max_treedepth = 20,
adapt_delta = 0.99)
)
stancode(m)