Is it possible to fit a model where the variance is proportional to the mean?

Heya,

In short I was hoping to a fit a model of the form

\begin{align} N( \mu_i, \ \mu_i \cdot \sigma) \\ \mu_i = f(X_i) \end{align}

where f(X_i) is some non-linear function of the data for subject i

Is this possible in brms? I saw in another post a link to an article where it looks like you can set the variance to be a function of parameters in your data but I don’t think this is quite what I was after.

Any hints or pointers would be greatly appreciated, thank you !

EDIT -

Apologies to be clear I am aware brms can already fit non-linear means it was more the scaled variance that I wasn’t sure was supported or not and if so what the syntax for it was.

g’day @gowerc ,
Not a direct answer to your question but a couple thoughts/ideas:
First, if f(X_i) is simple enough to work with, perhaps use the same formula for both \mu_i and for \sigma_i ? So I’m replacing \mu_i \cdot \sigma with \sigma_i and using \sigma_i = f(X_i) as well.
I think this is close but not exactly what you had in mind, since distributional models in brms will fit separate parameters for both mu and sigma:

Code example with distributional regression
library(brms); library(tidyverse)
set.seed(20240807)
dat <- tibble(
  x = seq(1, 30, length.out = 100)
) %>% 
  mutate(
    mu_y = 10 + 3 * x,
    sigma_y = mu_y * 0.15, # so base sigma is 0.15, but scales with mu
      # i.e., sigma_y = 0.15 * (10 + 3 x) = 1.5 + 0.45 x
    y = rnorm(n = n(), mean = mu_y, sd = sigma_y)
      # today i learned you can give rnorm vector means and sd's
  )
dat %>% ggplot(aes(x, y))+geom_point() # cool

# first test with a distributional model, but not quite what OP was thinking
# sigma just depends on x (not on mu)
# but if mu and sigma use same formula... that's kinda it, no?
bf_1 <- bf(
  y ~ x,
  sigma ~ x,
  family = gaussian()
)
# NOTE: brms automatically applies the log link to sigma (zero-positive)
get_prior(bf_1, dat)
fit_1 <- brm(bf_1, data = dat, backend = 'cmdstanr', cores = 4, chains = 4)
summary(fit_1); pp_check(fit_1) # not bad

(Is there a way to get parameters on both mu and sigma to correlate in brms?)

My example cheats by using a linear case. Also, sigma is fit on the log-link scale, so its parameters are multiplicative instead of additive like in my simulated data.

Another thought I had when I first read your question was to just use a distribution whose variance scales with the mean. The Gamma is a natural contender if it suits your data (no zeroes, positive only?), since var(Y)=\mu^2\phi where \phi is the dispersion parameter. But that’s the square of the mean it scales with…

This model does ok in my example but doesn’t outperform fit_1.

Example with Gamma
bf_2 <- bf(
  y ~ x, family = Gamma('log')
)
get_prior(bf_2, dat)
fit_2 <- brm(bf_2, data = dat, backend = 'cmdstanr', cores = 4, chains = 4)
summary(fit_2); pp_check(fit_2) # a wee bit off compared to fit_1

# compare models:
fit_1 <- add_criterion(fit_1, 'loo')
fit_2 <- add_criterion(fit_2, 'loo')
loo_compare(fit_1, fit_2) # favors fit_1

I did try digging around if you can get brms to use mu * sigma somehow but didn’t find anything. Maybe this requires editing Stan code? Curious to hear what others know here :^)

hope that helps