The SequentialSamplingModels.jl package implements distributions that are used in psychology research. One such model, the Linear Ballistic Accumulator (LBA), is used to model simultaneously reaction time (RT) and choice (a binary variable).
The LBA()
distribution returns a tuple of the two vectors:
using Turing
using SequentialSamplingModels
using Random
using LinearAlgebra
using DataFrames
rand(LBA(ν=[3.0, 2.0], A=0.8, k=0.2, τ=0.3), 3)
(choice = [1, 1, 1], rt = [0.4951585198314631, 0.4486594724069529, 0.5222694726662244])
One can use such distribution in Turing in a simple model as follows:
data = DataFrame(rand(LBA(ν=[3.0, 2.0], A=0.8, k=0.2, τ=0.3), 500))
@model function model_lba(data)
data = (choice=data.choice, rt=data.rt)
min_rt = minimum(data[2])
# Priors
drift ~ filldist(MvNormal(zeros(2), I * 2), 2)
A ~ truncated(Normal(0.8, 0.4), 0.0, Inf)
k ~ truncated(Normal(0.2, 0.2), 0.0, Inf)
tau ~ Uniform(0.0, min_rt)
# Likelihood
data ~ LBA(; τ=tau, A=A, k=k, ν=drift)
return (; data, drift, A, k, tau)
end
chain = sample(model_lba(data), Prior(), 50000)
I would like to re-write the model to accept two independent vectors as inputs.
My initial input was to make a simple change and capture the LBA()
output as a tuple:
@model function model_lba(choice, rt)
min_rt = minimum(rt)
# Priors
drift ~ filldist(MvNormal(zeros(2), I * 2), 2)
A ~ truncated(Normal(0.8, 0.4), 0.0, Inf)
k ~ truncated(Normal(0.2, 0.2), 0.0, Inf)
tau ~ Uniform(0.0, min_rt)
# Likelihood
(choice, rt) ~ LBA(; τ=tau, A=A, k=k, ν=drift)
return (; choice, rt, drift, A, k, tau)
end
ERROR: LoadError: Malformed variable name (choice, rt)!
But that seems incompatible with Turing (?). I then tried a workaround by creating the data
tuple inside the model:
@model function model_lba(choice, rt)
data = (choice=choice, rt=rt)
min_rt = minimum(rt)
# Priors
drift ~ filldist(MvNormal(zeros(2), I * 2), 2)
A ~ truncated(Normal(0.8, 0.4), 0.0, Inf)
k ~ truncated(Normal(0.2, 0.2), 0.0, Inf)
tau ~ Uniform(0.0, min_rt)
# Likelihood
data ~ LBA(; τ=tau, A=A, k=k, ν=drift)
return (; data.choice, data.rt, drift, A, k, tau)
end
chain = sample(model_lba(data.choice, data.rt), Prior(), 50000)
ERROR: MethodError: no method matching iterate(::LBA{Matrix{Float64}, Float64, Float64, Float64})
...
But to no avail. Any ideas or recommendations are welcome!
(note: this question was originally asked on the package’s repo in the context of using predict()
from the priors, but the author suggested to ask the wider Turing community)