Setting starting values on ndt intercept of shifted lognormal model

I’m trying to fit a shifted lognormal model to a large data set of response times. I’m having some difficulty with trade-offs between the ndt parameter and the scale parameter (mu): sometimes in one chain the ndt starts out out in an unreasonable part of the parameter space, and just stays there.

I’m seeing whether I can mitigate this with some reasonable priors, I’m less familiar with how to specify things in brms than I would be in stan or JAGS. I’m trying to specify a prior (which seems to work) and starting values. When I specify the starting values for b_ndt as a function (see code below) the stan errors indicate problems with the starting values:

# SAMPLING FOR MODEL '48d47669f619bbb26676a523eb3d8c6e' NOW (CHAIN 1).
# Chain 1: Rejecting initial value:
# Chain 1:   Error evaluating the log probability at the initial value.
# Chain 1: Exception: lognormal_lpdf: Random variable[1] is -163.201, but must be >= 0!  (in 'model4b2c6ff13fd9_48d47669f619bbb26676a523eb3d8c6e' at line 118)

I don’t get this, given that Y is lognormally distributed and must be greater than 0, so I figure it must be some issue with the generation of starting values yielding incompatible values (?). I’d think that since everything is defined on the log scale this would work, but I guess I’m missing something.

Code follows.

## Read in the data
library(dplyr)
library(brms)

data_url = "https://www.dropbox.com/s/94ccglb6kd1ifm0/data.Rda?dl=1"
data_file = tempfile(fileext = ".Rda")

download.file(url = data_url,
              destfile = data_file,
              mode="wb")

load(data_file)

## brms
formula <- bf(LiftOffLatency ~ 0 + Intercept + CueDirection*SentenceDirection*duration + CueDirection*SentenceDirection*min_freq + (1|ptid) + (0+SentenceDirection|ItemNumber),
              sigma ~ 0 + Intercept + (1|ptid),
              ndt ~  0 + Intercept + (1|ptid), family=shifted_lognormal())

priors <- c(
  set_prior("normal(7,1)", class = "b", coef = "Intercept", dpar = "ndt")
)

fit = brm(formula = formula,
          data = mono_data,
          prior = priors,
          chains = 1,
          seed = 394,
          control = list(
            #adapt_delta = .95,
            #max_treedepth = 15
          ), inits = function(){
            list(b_ndt = array(runif(1,6,8)))
          })

Please also provide the following information in addition to your question:

  • Operating System: Windows and OSX
  • brms Version: 2.13.3

Welcome in the Stan forum!

Did you have a look at the Stan code to check what link function brms uses for the lognormal?

(Brms generated Stan code for complex models can be hard to parse. If this is the case, it can help to start with a simpler model).

If it is the identity link function, as this discussion here Understanding shifted lognormal parameters and priors suggests, that could be part of the problem.

Also:
If I remember correctly, brms uses flat priors for regression coefficients other than the intercept if not specified otherwise. To get a better behaved model you could put priors on the other regression coefficients.
It’s also not necessary to use ‘0 + Intercept’. You can just use ‘1 +’ … and specify a prior for the intercept.

In addition to what Guido said, models with predicted ndt are hard to initialize since the ndt must be initialized so that it is smaller than the corresponding responses. Please note that, by default, ndt is modelled on the log-scale if predicted. In my experience, setting the initial values of the ndt intercept to some small(ish) values, e.g., -3 or -5 on the log scale should suffice. This could be done as follows:

inits <- list(list(b_ndt = as.array(-5)))

The length of the outer list must match the number of chains. Of course, the function approach you are doing could work as well.

3 Likes

Hi,

Did you get this to work? What was the solutions if so?

I tried Paul’s suggestion and had no luck.