Disable non-centered parameterization in brms

We are currently working on a new custom_family for brms. One important part of this family is the ability to specify specific priors for the regression parameters. For this, we need to be able to use the design matrix in exactly the way we pass it without centering. Take a look at this simple example:

data("Machines", package = "MEMSS")
library("brms")
form1 <- bf(score ~ Machine + (1|Worker))
make_stancode(form1, Machines)

From this we get the following in the transformed data block that we do not want:

transformed data { 
  int Kc = K - 1; 
  matrix[N, K - 1] Xc;  // centered version of X 
  vector[K - 1] means_X;  // column means of X before centering 
  for (i in 2:K) { 
    means_X[i - 1] = mean(X[, i]); 
    Xc[, i - 1] = X[, i] - means_X[i - 1]; 
  } 
} 

We have figured out that without the random part, this could work with cmc = FALSE. However, this fails with a random part.

Works:

form2 <- bf(score ~ 0 + Machine, cmc = FALSE)
make_stancode(form2, Machines)

Fails:

form3 <- bf(score ~ 0 + Machine + (1|Worker), cmc = FALSE)
make_stancode(form3, Machines)
# Error in data.frame(id = re$id[[i]], group = re$group[[i]], gn = re$gn[[i]],  : 
#   arguments imply differing number of rows: 1, 0

For us it seems that the best possibility would be a direct option to disable the automatic centering of the predictors (our design matrix is essentially centered). But any work around to get rid of the part in the transformed parameters block would probably work as well.

@paul.buerkner It seems we have found a fix for this issue by always setting cmc to TRUE for the random effects. See here for the actual fix in the code.

I am happy to submit a pull request with this fix. However, there of course might be situations where cmc = TRUE in the random effects. But at least not in the current situation.

thanks! I am still on vacation and will take a look in a few days.

1 Like

I might have spoked too early. While this fix solves the problem for our case, it leads to some failed unit tests: tests.make_standata.R:613 and tests.make_standata.R:614

As I am not the expert on the internals, I am not sure I feel confident to provide a fix that considers all aspects of what cmc is actually useful for. One possibility would be to allow the user to set cmc independently for both fixed and random effects.

I just fixed this issue in the github version of brms.

Related question. Is there any way to get brms to use a “centered” parameterization? What I mean is no:

transformed parameters {
// group-level effects
vector[N_1] r_1_1 = sd_1[1] * (z_1[1]);
}

just declaring r_1_1 in parameters and using directly without scaling by sd_1. Stan manual suggests this is more efficient in large data settings.

brms does not support the centered parameterization for random effects as, for the majority of cases, the non-centered parameterization leads to better convergence and also generalizes to non-hierarchical random effects structures.

2 Likes

thanks Paul. I have a case where my model seems fine with a sub sample of data, but “gets stuck” (i.e. runtime disproportionately longer than the increase in data would suggest it should be) with the full sample, so I was just curious about trying a centered parameterization. I’ll post the modeling issue on a separate thread.