Ejemplo n.º 1
0
    def populate_backward(self):
        """Populate backward likelihoods for all states/times"""

        # initialise with exit probabilities
        self.backward[:, -1] = self.state_transitions[1:len(self.states) + 1,
                                                      -1]

        # below iterator skips first observation
        # (will be used when finalising P(O|model))
        # iterate backwards through observations (time) [::-1] <- reverses list
        for t, observation in list(enumerate(self.observations[1:]))[::-1]:

            # print(t, observation)
            for state_index in range(len(self.states)):

                state_number = state_index + 1
                # ^ for easier reading (arrays 0-indexed, _number 1-indexed)

                other_index = self.get_other_state_index(state_index)
                other_number = other_index + 1  # for 1 indexing

                # observation for transitions from the same state
                this_state_gaussian = gaussian(
                    observation, self.states[state_index].mean,
                    self.states[state_index].std_dev)
                # observation for transitions from the other state
                other_state_gaussian = gaussian(
                    observation, self.states[other_index].mean,
                    self.states[other_index].std_dev)

                # a * b * beta
                this_from_this = self.state_transitions[
                    state_number,
                    state_number] * this_state_gaussian * self.backward[
                        state_index, t + 1]
                other_from_this = self.state_transitions[
                    state_number,
                    other_number] * other_state_gaussian * self.backward[
                        other_index, t + 1]

                self.backward[state_index,
                              t] = this_from_this + other_from_this

        return self.backward
Ejemplo n.º 2
0
    def populate_forward(self):
        """Populate forward likelihoods for all states/times"""

        for t, observation in enumerate(self.observations):
            # iterate through observations (time)

            for state_index, state in enumerate(self.states):
                # both states at each step

                state_number = state_index + 1
                # ^ for easier reading (arrays 0-indexed, _number 1-indexed)

                if t == 0:  # calcualte initial, 0 = first row = initial
                    self.forward[state_index, t] = self.state_transitions[
                        0, state_number] * gaussian(observation, state.mean,
                                                    state.std_dev)
                else:
                    # each state for each time has two paths leading to it,
                    # the same state (this) and the other state (other)

                    other_index = self.get_other_state_index(state_index)
                    other_number = other_index + 1  # for 1 indexing

                    # previous value * prob of changing from previous state to current
                    this_to_this = self.forward[state_index, t -
                                                1] * self.state_transitions[
                                                    state_number, state_number]
                    other_to_this = self.forward[
                        other_index, t -
                        1] * self.state_transitions[other_number, state_number]

                    self.forward[
                        state_index,
                        t] = (this_to_this + other_to_this) * gaussian(
                            observation, state.mean, state.std_dev)

        return self.forward
Ejemplo n.º 3
0
    def calculate_p_obs_backward(self):
        """Calculate, store and return P(O|model) going backwards"""

        sum = 0
        for state_index, initial_likelihood in enumerate(self.backward[:, 0]):

            pi = self.state_transitions[0, state_index + 1]
            b = gaussian(self.observations[0], self.states[state_index].mean,
                         self.states[state_index].std_dev)
            beta = initial_likelihood

            sum += pi * b * beta

        self.p_obs_backward = sum
        return sum
Ejemplo n.º 4
0
    def transition_likelihood(self, from_index, to_index, t):
        """Get specific transition likelihood given state index either side and the timestep"""
        #from_index = i, from equations in the notes
        #to_index = j, from equations in the notes

        if t == 0:
            print("no transition likelihood for t == 0")

        forward = self.forward[from_index, t - 1]
        transition = self.state_transitions[from_index + 1, to_index + 1]
        emission = gaussian(self.observations[t], self.states[to_index].mean,
                            self.states[to_index].std_dev)
        backward = self.backward[to_index, t]

        return (forward * transition * emission *
                backward) / self.observation_likelihood
Ejemplo n.º 5
0
from markov import MarkovModel
from markovlog import LogMarkovModel

fig_dpi = 200
fig_export = False

x = np.linspace(-4, 8, 300)  # x values for figures
x_label = "Observation Space"
y_label = "Probability Density"

# %% [markdown]
# State Probability Functions (1)
# ===================

# %%
state_1_y = [gaussian(i, state1.mean, state1.std_dev) for i in x]
state_2_y = [gaussian(i, state2.mean, state2.std_dev) for i in x]

plt.plot(x, state_1_y, c='r', label="State 1")
plt.plot(x, state_2_y, c='b', label="State 2")

plt.legend()
plt.title("State Probability Density Functions")

plt.xlabel(x_label)
plt.ylabel(y_label)
plt.grid(linestyle="--")

fig = matplotlib.pyplot.gcf()
fig.set_dpi(fig_dpi)
fig.set_tight_layout(True)