# Nonlinear syntax with a multinomial model?

**URL:** <https://discourse.mc-stan.org/t/nonlinear-syntax-with-a-multinomial-model/16122>\
**Category:** brms\
**Created:** [June 20, 2020, 2:39pm UTC](https://discourse.mc-stan.org/t/nonlinear-syntax-with-a-multinomial-model/16122 "2020-06-20T14:39:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Solomon](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/solomon/32/2495_2.png) [@Solomon](https://discourse.mc-stan.org/u/Solomon)\
**Post date:** [June 20, 2020, 2:39pm UTC](https://discourse.mc-stan.org/t/nonlinear-syntax-with-a-multinomial-model/16122/1 "2020-06-20T14:39:29Z")

</div>

Is it possible to use the non-linear syntax to fit a multinomial model? Here’s an example of a simple intercepts-only model for a 3-category response variable that works fine with conventional **brms** syntax.

```
library(brms)

dat <- data.frame(y = rep(letters[1:3], times = 100))

fit_1 <-
  brm(data = dat, 
      family = categorical(link = logit),
      y ~ 1,
      prior = c(prior(normal(0, 1), class = Intercept, dpar = mub),
                prior(normal(0, 1), class = Intercept, dpar = muc))) 

```

I’d like to fit to fit the same model using the nonlinear syntax. My first naïve attempt is incorrect in that it returns a single intercept.

```
fit_2 <-
  brm(data = dat, 
      family = categorical(link = logit),
      bf(y ~ a,
         a ~ 1,
         nl = TRUE),
      prior(normal(0, 1), class = b, nlpar = a)) 

```

My second naïve attempt is rejected by **brms** out of hand.

```
fit_3 <-
  brm(data = dat, 
      family = categorical(link = logit),
      bf(y ~ a,
         a ~ 1,
         nl = TRUE),
      prior = c(prior(normal(0, 1), class = b, dpar = mub, nlpar = a),
                prior(normal(0, 1), class = b, dpar = muc, nlpar = a))) 

```

All I get from this is an error:

```
Error: The following priors do not correspond to any model parameter: 
b_mub_a ~ normal(0, 1)
b_muc_a ~ normal(0, 1)
Function 'get_prior' might be helpful to you.

```

Is there a way to mix the nonlinear syntax with `family = categorical`?

---

<div class="post-metadata">

**Author:** ![paul.buerkner](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/paul.buerkner/32/3303_2.png) [@paul.buerkner](https://discourse.mc-stan.org/u/paul.buerkner)\
**Post date:** [June 20, 2020, 4:27pm UTC](https://discourse.mc-stan.org/t/nonlinear-syntax-with-a-multinomial-model/16122/2 "2020-06-20T16:27:42Z")

</div>

Perhaps the models I discuss in [https://github.com/paul-buerkner/brms/issues/560](https://github.com/paul-buerkner/brms/issues/560) could be helpful to you.

---

<div class="post-metadata">

**Author:** ![Solomon](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/solomon/32/2495_2.png) [@Solomon](https://discourse.mc-stan.org/u/Solomon)\
**Post date:** [June 20, 2020, 10:59pm UTC](https://discourse.mc-stan.org/t/nonlinear-syntax-with-a-multinomial-model/16122/3 "2020-06-20T22:59:29Z")

</div>

Thanks for the nudge, @paul.buerkner. I think I have it. For the sake of continuity, I’m going to switch to the `Fishing` data used in [GitHub issue #560](https://github.com/paul-buerkner/brms/issues/560). For anyone else following, that example was based on a conditional logistic model, which I’m not totally up on but I believe is an alternative parameterization of what I’m calling the multinomial model. Anyway, the code below fits an intercepts-only multinomial model for the 4-category response variable `mode`. In this example, the reference category will be `"boat"`. I’ll show how to fit the model with three styles of syntax, what I’m going to call

- the conventional syntax (`fish1a`),
- the verbose syntax (`fish1b`), and
- the nonlinear syntax (`fish1c`).

```
library(brms)
data("Fishing", package = "mlogit")

# conventional syntax
fish1a <-
  brm(data = Fishing, 
      family = categorical(link = logit, refcat = "boat"),
      mode ~ 1,
      prior = c(prior(normal(0, 1), class = Intercept, dpar = mubeach),
                prior(normal(0, 1), class = Intercept, dpar = mucharter),
                prior(normal(0, 1), class = Intercept, dpar = mupier)))

# verbose syntax
fish1b <-
  brm(data = Fishing, 
      family = categorical(link = logit, refcat = "boat"),
      bf(mode ~ 1,
         mubeach ~ 1,
         mucharter ~ 1,
         mupier ~ 1),
      prior = c(prior(normal(0, 1), class = Intercept, dpar = mubeach),
                prior(normal(0, 1), class = Intercept, dpar = mucharter),
                prior(normal(0, 1), class = Intercept, dpar = mupier)))

# nonlinear syntax 
fish1c <-
  brm(data = Fishing, 
      family = categorical(link = logit, refcat = "boat"),
      bf(mode ~ 1,
         nlf(mubeach ~ abeach),
         nlf(mucharter ~ acharter),
         nlf(mupier ~ apier),
         abeach + acharter + apier ~ 1),
      prior = c(prior(normal(0, 1), class = b, nlpar = abeach),
                prior(normal(0, 1), class = b, nlpar = acharter),
                prior(normal(0, 1), class = b, nlpar = apier)))

```

The results are the same for all.

```
                    Estimate Est.Error Q2.5 Q97.5
mubeach_Intercept -1.13 0.10 -1.32 -0.94
mupier_Intercept -0.85 0.09 -1.02 -0.67
mucharter_Intercept 0.08 0.07 -0.05 0.21
                    Estimate Est.Error Q2.5 Q97.5
mubeach_Intercept -1.13 0.10 -1.32 -0.94
mupier_Intercept -0.85 0.09 -1.02 -0.67
mucharter_Intercept 0.08 0.07 -0.05 0.21
                   Estimate Est.Error Q2.5 Q97.5
abeach_Intercept -1.13 0.10 -1.33 -0.94
acharter_Intercept 0.08 0.07 -0.04 0.22
apier_Intercept -0.85 0.09 -1.02 -0.68

```
