hmmmm 🤔
Yet another aptly-named Hidden-Markov Model library for Rust.
Important Note: This crate depends on the feature generic_const_exprs. For now, usage of this crate is limited to use with the nightly Rust channel.
Usage
Installation
States + Observations
To create a Hmm, we first need two enums corresponding to the
states and observations of the hidden Markov model. This can be done
by using the #[derive(State)] and #[derive(Observation)] proc macros in the hmmmm_derive crate:
Note that the attribute repr(u8) is required for both enums
definitions, as we need to have the enums be: a) as small as
possible for efficient computation and b) easily cast between
itself and u8 / usize. The derive macros will throw a compilation
error if this attribute is not present on the enum.
Probabilities
A Hmm requires 3 different probability matrices:
- Initial (state) probabilities -
[f64; N] - Transition probabilities -
[[f64; N]; N] - Emission probabilities -
[[f64; M]; N]
...where N is the number of possible states and O is the
number of possible observations.
These can be:
- Manualy declared, e.g.:
let pr_initial: = ; // [Healthy, Fever]
- Declared via the methods in
hmmmm::utils, e.g.:
let pr_initial: = pr_i;
Constructing the HMM
Now that we have our states, observations, and corresponding
probability matrices we can construct our Hmm:
let pr_initial: = ;
let pr_transition: = ;
let pr_emission: =
let hmm = new;
Algorithms
Viterbi
The Viterbi algorithm obtains the maximum a posteriori estimate (MAP) of the most likely sequence of hidden states given an input sequence of observations.
Input: the sequence of observations - &Vec<O>
Output: a tuple containing the log (base 2) probability of the MAP hidden state sequence and the corresponding hidden state sequence - (f64, Vec<S>)
Example:
/* Using the HMM `hmm` from the previous section */
let signal = vec!;
let = hmm.;
/*
pr = −6.04739805022
sequence = [Condition::Healthy, Condition::Healthy, Condition::Fever]
*/