# librosa.sequence.viterbi

librosa.sequence.viterbi(prob, transition, *, p_init=None, return_logp=False)[source]

Viterbi decoding from observation likelihoods.

Given a sequence of observation likelihoods `prob[s, t]`, indicating the conditional likelihood of seeing the observation at time `t` from state `s`, and a transition matrix `transition[i, j]` which encodes the conditional probability of moving from state `i` to state `j`, the Viterbi algorithm [1] computes the most likely sequence of states from the observations.

Parameters:
probnp.ndarray [shape=(…, n_states, n_steps), non-negative]

`prob[..., s, t]` is the probability of observation at time `t` being generated by state `s`.

transitionnp.ndarray [shape=(n_states, n_states), non-negative]

`transition[i, j]` is the probability of a transition from i->j. Each row must sum to 1.

p_initnp.ndarray [shape=(n_states,)]

Optional: initial state distribution. If not provided, a uniform distribution is assumed.

return_logpbool

If `True`, return the log-likelihood of the state sequence.

Returns:
Either `states` or `(states, logp)`:
statesnp.ndarray [shape=(…, n_steps,)]

The most likely state sequence. If `prob` contains multiple channels of input, then each channel is decoded independently.

logpscalar [float] or np.ndarray

If `return_logp=True`, the log probability of `states` given the observations.

`viterbi_discriminative`

Viterbi decoding from state likelihoods

Examples

In this example, we have two states `healthy` and `fever`, with initial probabilities 60% and 40%.

We have three observation possibilities: `normal`, `cold`, and `dizzy`, whose probabilities given each state are:

`healthy => {normal: 50%, cold: 40%, dizzy: 10%}` and `fever => {normal: 10%, cold: 30%, dizzy: 60%}`

Finally, we have transition probabilities:

`healthy => healthy (70%)` and `fever => fever (60%)`.

Over three days, we observe the sequence `[normal, cold, dizzy]`, and wish to know the maximum likelihood assignment of states for the corresponding days, which we compute with the Viterbi algorithm below.

```>>> p_init = np.array([0.6, 0.4])
>>> p_emit = np.array([[0.5, 0.4, 0.1],
...                    [0.1, 0.3, 0.6]])
>>> p_trans = np.array([[0.7, 0.3], [0.4, 0.6]])
>>> path, logp = librosa.sequence.viterbi(p_emit, p_trans, p_init=p_init,
...                                       return_logp=True)
>>> print(logp, path)
-4.19173690823075 [0 0 1]
```