MCMC of mixture model using Mamba

I am trying to fit my experimental data( ~40k circular data, [-\pi, +\pi], bimodal) with mixture of von mises distribution using Mamba.
I want to predict the parameters(\mu, \kappa, weights) of the data.

Problem

The following code returns
TypeError: in new, expected ScalarStochastic, got Float64
However, I can’t figure out what is wrong with my code…
How can I fix this error?
Any suggestions are welcomed !!
Thank you in advance.

Dependencies and data

# Julia version 1.2.0
using Mamba # v0.12.2
using Distributions # v0.21.8

data = Dict{Symbol, Any}(
    :sample => Array(data[:, 1]),
    :N => length(data[:, 1]),
)
"""
Dict{Symbol,Any} with 2 entries:
  :N      => 374718
  :sample => [2.49329, 0.143419, -1.23308, 2.42615, -1.74222, -0.180238, 0.3280…
"""

Model specification

\kappa1 \sim Gamma(\alpha=1., \beta=1.0)\\ \kappa2 \sim Gamma(\alpha=1., \beta=1.0)\\ \mu1 \sim VonMises(\mu=0, \kappa=0.5)\\ \mu2 \sim VonMises(\mu=pi, \kappa=0.5)\\ w \sim Dirichlet([1., 1.])\\ y \sim w[1]*VonMises(\mu=\mu1, \kappa=\kappa1) + w[2]*VonMises(\mu=\mu2, \kappa=\kappa2)

model = Model(
    kappa1 = Stochastic(
        () -> Gamma(),
    ),
    kappa2 = Stochastic(
        () -> Gamma(),
    ), 
    mu1 = Stochastic(
        () -> VonMises(0, 0.5),
    ),
    mu2 = Stochastic(
        () -> VonMises(pi, 0.5),
    ), 
    w = Stochastic(1,
        () -> Dirichlet(ones(2))
    ),
    y = Stochastic(1,
        (mu1, mu2, kappa1, kappa2, w) -> 
        MixtureModel(VonMises[VonMises(mu1, kappa1), VonMises(mu2, kappa2)], w),
    false),
)
scheme = [NUTS([:kappa1, :kappa2, :mu1, :mu2, :w])]
setsamplers!(model, scheme)

Initial values and sampling

inits = [
  Dict{Symbol, Any}(
        :y => data[:sample],
        :kappa1 => rand(Gamma(1, 1)),
        :kappa2 => rand(Gamma(1, 1)),
        :mu1 => rand(VonMises(0, 0.5)), 
        :mu2 => rand(VonMises(0, 0.5)), 
        :w => [0.5, 0.5]
  )
]
## MCMC(NUTS)
nuts_inference = mcmc(model, data, inits, 5000, burnin=1000, thin=2, chains=1)

returns

TypeError: in new, expected ScalarStochastic, got Float64

The error means that one of the type constructor got an object of unexpected datatype as parameter.

To get more help from here, you have to post the full call stack after the error message.

Usually, the function at the top of the call stack is the one in which the error happened, and there you have the source file and line where it happened.

1 Like

Thank you for your reply.
The followings are the full stack.

There seems to be many mistakes in my code, but still, I don’t understand the TypeError in the top.
I’m giving vonmises distribution a ScalarStochastic(\mu1, \mu2, \kappa1 ,\kappa2) as a argument, not a Float64.
Am I making some kind of radical misunderstaning?

TypeError: in new, expected ScalarStochastic, got Float64
Stacktrace:
[1] Type at C:\Users\username\.julia\packages\Distributions\OdJGZ\src\univariate\continuous\vonmises.jl:22 [inlined]
[2] #VonMises#105 at C:\Users\username\.julia\packages\Distributions\OdJGZ\src\univariate\continuous\vonmises.jl:29 [inlined]
[3] Type at C:\Users\username\.julia\packages\Distributions\OdJGZ\src\univariate\continuous\vonmises.jl:28 [inlined]
[4] (::getfield(Main, Symbol("##164#170")))(::ScalarStochastic, ::ScalarStochastic, ::ScalarStochastic, ::ScalarStochastic, ::ArrayStochastic{1}) at .\In[20]:21
[5] (::getfield(Main, Symbol("##181#182")))(::Model) at .\array.jl:0
[6] setinits!(::ArrayStochastic{1}, ::Model, ::Array{Float64,1}) at C:\Users\username\.julia\packages\Mamba\Jotzr\src\model\dependent.jl:173
[7] setinits!(::Model, ::Dict{Symbol,Any}) at C:\Users\username\.julia\packages\Mamba\Jotzr\src\model\initialization.jl:11
[8] setinits!(::Model, ::Array{Dict{Symbol,Any},1}) at C:\Users\username\.julia\packages\Mamba\Jotzr\src\model\initialization.jl:24
[9] #mcmc#23(::Int64, ::Int64, ::Int64, ::Bool, ::typeof(mcmc), ::Model, ::Dict{Symbol,Any}, ::Array{Dict{Symbol,Any},1}, ::Int64) at C:\Users\username\.julia\packages\Mamba\Jotzr\src\model\mcmc.jl:30
[10] (::getfield(Mamba, Symbol("#kw##mcmc")))(::NamedTuple{(:burnin, :thin, :chains),Tuple{Int64,Int64,Int64}}, ::typeof(mcmc), ::Model, ::Dict{Symbol,Any}, ::Array{Dict{Symbol,Any},1}, ::Int64) at .\none:0
[11] top-level scope at In[22]:1

Looks like some of your Von Mises constructors are called with the first argument being a ScalarStochastic and the second being a Float64, while the actual constructor expects the argument types to be the same.

The code that triggers the error is in the 21st line of your 20th Jupyter cell, which is impossible to decipher without the actual notebook.

Btw, it’s best to leave [VonMises(mu1, kappa1), VonMises(mu2, kappa2)] as it is or use VonMises{typeof(mu1)}[VonMises(mu1, kappa1), VonMises(mu2, kappa2)] to avoid an array with an abstract element type.

Thank you for your advice.
I changed my code.

21st line of my 20th cell was indicating this part.

20    y = Stochastic(1,
21        (mu1, mu2, kappa1, kappa2, w) -> 
22        MixtureModel([VonMises(mu1, kappa1), VonMises(mu2, kappa2)], w),
23    false),

I’m pretty sure that all of these arguments are ScalarStochastic because the codes below returns no error.
Giving two ScalarStochastic parameters per one von mises distribution will cause same TypeError.
This might be a bug.

# No error
    y = Stochastic(1,
        (mu1, mu2, w) -> 
        MixtureModel([VonMises(mu1, 1), VonMises(mu2, 1)], w),
    false),
# No error
    y = Stochastic(1,
        (kappa1, kappa2, w) -> 
        MixtureModel([VonMises(0, kappa1), VonMises(0, kappa2)], w),
    false),

I’m still stuck here.
Does anyone know the solution?

Would Turing or DynamicHMC work for your problem? In my experience, those packages have more thorough documentation and have more active communities.

2 Likes

Sorry for the late response. This appears to be a problem with Distributions package (the VonMises distribution) and parameter checking. I will look into it today and file a pull request if I can fix it.

1 Like

Thank you so much for your reply!
I will try other packages.