ml2020 Pythonlab04
ml2020 Pythonlab04
A Markov chain (model) describes a stochastic process where the assumed probability of future
state(s) depends only on the current process state and not on any the states that preceded it
Let's get into a simple example. Assume you want to model the future probability that your dog is
in one of three states given its current state. To do this we need to specify the state space, the
initial probabilities, and the transition probabilities.
Imagine you have a very lazy fat dog, so we define the state space as sleeping, eating, or
pooping. We will set the initial probabilities to 35%, 35%, and 30% respectively.
import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
The next step is to define the transition probabilities. They are simply the probabilities of staying
in the same state or moving to a different state given the current state.
print(q_df)
q = q_df.values
print('\n', q, q.shape, '\n')
print(q_df.sum(axis=1))
In our toy example the dog's possible states are the nodes and the edges are the lines that
connect the nodes. The transition probabilities are the weights. They represent the probability of
transitioning to a state given the current state. we need to create a dictionary object that holds our
edges and their weights.
def _get_markov_edges(Q):
edges = {}
for col in Q.columns:
for idx in Q.index:
edges[(idx,col)] = Q.loc[idx,col]
return edges
edges_wts = _get_markov_edges(q_df)
pprint(edges_wts)
Now create nodes, edges and their transition probabilities
# create graph object
G = nx.MultiDiGraph()
Consider a situation where your dog is acting strangely and you wanted to model the probability
that your dog's behavior is due to sickness or simply quirky
This is where it gets a little more interesting. Now we create the emission or
observation probability matrix. This matrix is size M × O where M is the number of hidden states
and O is the number of possible observable states. The emission matrix tells us the probability
the dog is in one of the hidden states, given the current, observable state.
Let's keep the same observable states from the previous example. The dog can be either
sleeping, eating, or pooping.
observable_states = states
print(b_df)
b = b_df.values
print('\n', b, b.shape, '\n')
print(b_df.sum(axis=1))
Now we create the graph edges and the graph object.
# create graph edges and weights
hide_edges_wts = _get_markov_edges(a_df)
pprint(hide_edges_wts)
emit_edges_wts = _get_markov_edges(b_df)
pprint(emit_edges_wts)
# create graph object
G = nx.MultiDiGraph()
print(f'Edges:')
pprint(G.edges(data=True))
The hidden Markov graph is a little more complex but the principles are the same. For example,
you would expect that if your dog is eating there is a high probability that it is healthy (60%) and
a very low probability that the dog is sick (10%).
Now, what if you needed to discern the health of your dog over time given a sequence of
observations? (
# observation sequence of dog's behaviors
# observations are encoded numerically
Now try Viterbi algorithm on above concept. Some details of Viterbi algorithm are described
below:
The Viterbi algorithm is a dynamic programming algorithm for finding the most likely sequence of
hidden states—called the Viterbi path—that results in a sequence of observed events, especially
in the context of markov information sources and hidden markov models (HMM).
Using the Viterbi algorithm, you can identify the most likely sequence of hidden states given the
sequence of observations (describe in labsheet).
Pseudocode of Viterbi algorithm