Not from documentation, but from inspecting the stan code generated by brms, it looks like it’s using non-centered parameterization for the group-level random effects but not the population-level fixed effects.
Here is the full stan code for my model:
// generated with brms 2.23.0
functions {
}
data {
int<lower=1> N; // total number of observations
vector[N] Y; // response variable
int<lower=1> K_sigma; // number of population-level effects
matrix[N, K_sigma] X_sigma; // population-level design matrix
// data for group-level effects of ID 1
int<lower=1> N_1; // number of grouping levels
int<lower=1> M_1; // number of coefficients per level
array[N] int<lower=1> J_1; // grouping indicator per observation
// group-level predictor values
vector[N] Z_1_sigma_1;
// data for group-level effects of ID 2
int<lower=1> N_2; // number of grouping levels
int<lower=1> M_2; // number of coefficients per level
array[N] int<lower=1> J_2; // grouping indicator per observation
// group-level predictor values
vector[N] Z_2_sigma_1;
int prior_only; // should the likelihood be ignored?
}
transformed data {
}
parameters {
vector[K_sigma] b_sigma; // regression coefficients
vector<lower=0>[M_1] sd_1; // group-level standard deviations
array[M_1] vector[N_1] z_1; // standardized group-level effects
vector<lower=0>[M_2] sd_2; // group-level standard deviations
array[M_2] vector[N_2] z_2; // standardized group-level effects
}
transformed parameters {
vector[N_1] r_1_sigma_1; // actual group-level effects
vector[N_2] r_2_sigma_1; // actual group-level effects
// prior contributions to the log posterior
real lprior = 0;
r_1_sigma_1 = (sd_1[1] * (z_1[1]));
r_2_sigma_1 = (sd_2[1] * (z_2[1]));
lprior += normal_lpdf(b_sigma[1] | 3,1);
lprior += normal_lpdf(b_sigma[2] | 0,0.5);
lprior += normal_lpdf(b_sigma[3] | 0,0.5);
lprior += normal_lpdf(b_sigma[4] | 0,0.5);
lprior += normal_lpdf(b_sigma[5] | 0,0.5);
lprior += normal_lpdf(b_sigma[6] | 0,0.5);
lprior += normal_lpdf(b_sigma[7] | 0,0.5);
lprior += normal_lpdf(b_sigma[8] | 0,0.5);
lprior += normal_lpdf(b_sigma[9] | 0,0.5);
lprior += normal_lpdf(b_sigma[10] | 0,0.5);
lprior += normal_lpdf(b_sigma[11] | 0,0.5);
lprior += normal_lpdf(b_sigma[12] | 0,0.5);
lprior += normal_lpdf(b_sigma[13] | 0,0.5);
lprior += normal_lpdf(b_sigma[14] | 0,0.5);
lprior += normal_lpdf(b_sigma[15] | 0,0.5);
lprior += normal_lpdf(b_sigma[16] | 0,0.5);
lprior += normal_lpdf(b_sigma[17] | 0,0.5);
lprior += normal_lpdf(b_sigma[18] | 0,0.5);
lprior += normal_lpdf(b_sigma[19] | 0,0.5);
lprior += normal_lpdf(b_sigma[20] | 0,0.5);
lprior += normal_lpdf(b_sigma[21] | 0,0.5);
lprior += normal_lpdf(sd_1 | 0,0.5)
- 1 * normal_lccdf(0 | 0,0.5);
lprior += normal_lpdf(sd_2 | 0,0.5)
- 1 * normal_lccdf(0 | 0,0.5);
}
model {
// likelihood including constants
if (!prior_only) {
// initialize linear predictor term
vector[N] mu = rep_vector(0.0, N);
// initialize linear predictor term
vector[N] sigma = rep_vector(0.0, N);
sigma += X_sigma * b_sigma;
for (n in 1:N) {
// add more terms to the linear predictor
sigma[n] += r_1_sigma_1[J_1[n]] * Z_1_sigma_1[n] + r_2_sigma_1[J_2[n]] * Z_2_sigma_1[n];
}
sigma = exp(sigma);
target += normal_lpdf(Y | mu, sigma);
}
// priors including constants
target += lprior;
target += std_normal_lpdf(z_1[1]);
target += std_normal_lpdf(z_2[1]);
}
generated quantities {
}
At the beginning of the transformed parameters block, we see the following two lines “undoing” the non-centered paramterization for the group-level effects but not for the other effects:
vector[N_1] r_1_sigma_1; // actual group-level effects
vector[N_2] r_2_sigma_1; // actual group-level effects
My concern is that because the value being predicted is a distributional parameter, the Devil’s funnel may be relevant for all predictors, including the population-level effects.