[ANN] HiddenMarkovModels.jl: when did HMMs get so fast?

Happy to be guided, and I appreciate the offer. What do I do?

2 Likes

The typical steps are:

  • fork
  • branch
  • edit
  • PR
  • if necessary, review/edit until ready
  • merge

This post is a pretty great walk through - it’s written for making PRs against Julia itself, so not all of it is relevant, but all of the git steps are the same regardless of what repository you’re contributing to.

Good luck, and thanks for putting in the effort to make our community better! Please don’t hesitate to ask more questions if you get stuck - it’s worth our time (and it just feels good) to help newcomers contribute :blush:

3 Likes

Thanks for the advice! We had actually moved the PR tutorial to a conversation via DM in order to avoid spamming this thread. As a result, @adannenberg made their very first open source contribution :tada:

3 Likes

Blushing…

6 Likes

On the contrary, that’s how we all start! A small PR to a documentation, then a bugfix here and there, and soon you’re in way over your head maintaining too many packages and having a blast at the next JuliaCon :slight_smile:

9 Likes

Amazing effort and congratulations on such a big package! I was wondering if HiddenMarkovModels.jl supports the case of modeling the the transition probabilities as a function of covariates from a multinomial logit model? The control section presents Markov switching regression which is something different, but the time dependency section (and the fact that you worked on ControlledHMMs.jl before) got my hopes up that it might be possible with the current state of affairs?

1 Like

Yes, both the transition probabilities and the emission probabilities are allowed to depend on exogenous controls / covariates. Did you encounter any difficulties trying it?

I tried fitting some simple models without covariates yesterday (different initalizations, 2 states) but unfortunately they error out due to numeric instability. Using ‘hmmTMB’ in R I was able to fit the models, but data initialization and everything afterwards is rather slow. Given the size of my data and (un)feasibility of computing HMMs I might have to turn to some less demanding models, but I know where to come back to when I want to fit HMMs again and there are of course still things I could do that you described in the Debugging section of the docs. Thanks for asking!

(BTW: I just left the R package for reference in case you want / can learn something about they achieve (more? better?) numerical stability.)

ArgumentError: isfinite(logL[k]) must hold. Got
logL[k] => NaN

This is something that can be handled by either particle filters, or by a “multiple-model filter”. The “Interacting Multiple Model” filter is one such filter, where each discrete mode is represented by a Kalman filter (or any nonlinear variant thereof), and the switching between them is modeled as a HMM with a transition-probability matrix.

Here’s an implementation of IMM and a tutorial. Here’s the same tutorial, but using a particle filter instead.

3 Likes

Do you have an MWE? Often the numerical instability is due to model specification and can be fixed with simple tweaks, like a small prior on a Gaussian variance to prevent it from going to zero. My package is as un-opinionated as possible and leaves all of these tweaks to the reader, whereas some R packages might be more beginner-friendly and make these assumptions for you.
See this docs page for debugging

1 Like

Amazing Package ! Thank you very much for this.

I’m just trying to figure out what’s wrong with baum_welch() & the Binomial()andBeta()` distributions.

I got :

suffstats is not implemented for (Distributions.Binomial{Float64}, Vector{Int64}, SubArray{Float64, 1, Matrix{Float64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}).

Same thing with Beta respectively.

Example :

init = [0.6, 0.4]
trans = [0.6 0.4 ; 0.7 0.3]
dists = [Binomial(10, 0.1), Binomial(10, 0.7)]
hmm = HMM(init, trans, dists)

init_guess = [0.5, 0.5]
trans_guess = [0.5 0.5; 0.5 0.5]
dists_guess = [Binomial(10, 0.4), Binomial(10, 0.5)]
hmm_guess = HMM(init_guess, trans_guess, dists_guess)

_, long_obs_seq = rand(hmm, 200)

hmm_est, loglikelihood_evolution = baum_welch(hmm_guess, long_obs_seq)

Sorry if the solution is obvious.

1 Like

Hi @tblk, welcome to the forum!

Implementations of Distributions.fit_mle are not consistent across all distributions:

  • some don’t have the method at all (like Beta)
  • some have a slightly different syntax (like Binomial, for which you must specify the number of trials n separately)

To deal with this heterogeneity, you can override HiddenMarkovModels.fit_in_sequence! for the distributions you care about, and plug it into the MLE estimation method of your choosing. Note that it is technically type piracy, so the better approach would be to define your own custom distribution with its fitting mechanism.

Thanks a lot ! Second option. Hopfully the doc is very clear.

If the doc is not clear enough, feel free to open an issue!