bambinos / formulae

Formulas for mixed-effects models in Python

Home Page:https://bambinos.github.io/formulae/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

model definition

jwdegee opened this issue · comments

I would like to fit a fully specified model. In lme I would write this as:

f = "choice ~ 1 + stimulus*reward + (1+stimulus*reward|subject_id)"`

In formulae this gives the following error:

import formulae as fm
fm.model_description(f)

    891                 return NotImplemented
    892         else:
--> 893             raise ValueError("LHS of group specific term cannot have more than one term.")
    894 
    895     def __repr__(self):

The following does seem to work:

f = "choice ~ 1 + stimulus*reward + (1|subject_id) + (stimulus|subject_id) + (reward|subject_id) + (stimulus:reward|subject_id)"
fm.model_description(f)

Is this the syntax for a fully specified model in formulae? Output:

ModelTerms(
  ResponseTerm(
    Term(
      name= choice
      variable= choice
      kind= None
    )
  ),
  InterceptTerm(),
  Term(
    name= stimulus
    variable= stimulus
    kind= None
  ),
  Term(
    name= reward
    variable= reward
    kind= None
  ),
  InteractionTerm(
    name= stimulus:reward
    variables= {'stimulus', 'reward'}
  ),
  GroupSpecTerm(
    expr= InterceptTerm(),
    factor= Term(
      name= subject_id
      variable= subject_id
      kind= None
    )
  ),
  GroupSpecTerm(
    expr= Term(
      name= stimulus
      variable= stimulus
      kind= None
    ),
    factor= Term(
      name= subject_id
      variable= subject_id
      kind= None
    )
  ),
  GroupSpecTerm(
    expr= Term(
      name= reward
      variable= reward
      kind= None
    ),
    factor= Term(
      name= subject_id
      variable= subject_id
      kind= None
    )
  ),
  GroupSpecTerm(
    expr= InteractionTerm(
      name= stimulus:reward
      variables= {'stimulus', 'reward'}
    ),
    factor= Term(
      name= subject_id
      variable= subject_id
      kind= None
    )
  )
)

Ah, fitting the model does not work and gives:

formula = "choice ~ 1 + stimulus*reward + (1|subject_id) + (stimulus|subject_id) + (reward|subject_id) + (stimulus:reward|subject_id)"
model_fitted = model.fit(formula=formula, family="bernoulli", draws=2000, target_accept=0.8)

    676                 string += f"{self.expr.name}|"
    677         else:
--> 678             raise ValueError("Invalid LHS expression for group specific term")
    679 
    680         if isinstance(self.factor, Term):

ValueError: Invalid LHS expression for group specific term

Hi @jwdegee, thanks for opening this issue!

This problem should be partially solved if you install it from master branch now. The following example works on my computer

import bambi as bmb
import numpy as np
import pandas as pd

np.random.seed(1234)

data = pd.DataFrame({
    "choice": np.random.normal(size=20),
    "stimulus": np.concatenate(
            (
                np.repeat("A", 5),
                np.repeat("B", 5),
                np.repeat("A", 5),
                np.repeat("B", 5),
            )
        ),
    "reward": np.concatenate(
            (
                np.repeat("A", 5),
                np.repeat("A", 5),
                np.repeat("B", 5),
                np.repeat("B", 5),
            )
        ),
    "subject_id": np.arange(20)
})

f = "choice ~ stimulus * reward + (stimulus|subject_id) + (reward|subject_id) + (stimulus:reward|subject_id)"
model = bmb.Model(data)
fitted = model.fit(f)

Just note that it is not necessary to add the "1" before the common and group-specific terms since the intercept is added by default.
It is still not possible to use the * operator within group-specific terms, that's why I had to write the three terms separately. I'm going to track that issue in #11.

Just let me know if you need more help with this :)

This should work with f = "choice ~ stimulus * reward + (stimulus*reward|subject_id)" now since #12.

Please feel free to let me know if you have any problems with this on your side 👍

That works! Thanks for the super fast fix and amazing package!

@jwdegee you may want to reinstall either from master or pip. I've found some bugs with the encoding when using categoric group-specific terms and they are fixed now.

ok will do thanks!