class Rubykov::HiddenMarkovModel

Public Class Methods

new(states, observations, start_probability, transition_probabilities, emission_probabilities) click to toggle source
# File lib/rubykov/hidden_markov_model.rb, line 3
def initialize(states, observations, start_probability, transition_probabilities, emission_probabilities)
  @states = states
  @observations = observations
  @start_probability = start_probability
  @transition_probabilities = transition_probabilities
  @observation_probabilities = emission_probabilities
end

Public Instance Methods

most_likely_state_sequence(observation_sequence) click to toggle source
# File lib/rubykov/hidden_markov_model.rb, line 11
def most_likely_state_sequence(observation_sequence)
  max_probabilities(observation_sequence).map(&:first)
end
most_likely_state_sequence_probability(observation_sequence) click to toggle source
# File lib/rubykov/hidden_markov_model.rb, line 15
def most_likely_state_sequence_probability(observation_sequence)
  max_probabilities(observation_sequence).last.last
end

Private Instance Methods

compute_viterbi_probabilities(observations) click to toggle source
# File lib/rubykov/hidden_markov_model.rb, line 27
def compute_viterbi_probabilities(observations)
  state_max_probabilities = []

  observations.each_with_index do |observation, index|
    state_max_probabilities[index] = {}
    @states.each do |state|
      state_max_probabilities[index][state] = 0
      state_max_probabilities.first[state] = @start_probability[state] * @observation_probabilities[state][observations.first]
    end
  end

  observations[1..-1].each_with_index do |observation, index|
    @states.each do |state|
      max_probability = state_max_probabilities[index].map { |previous_state, previous_probability| @transition_probabilities[previous_state][state] * previous_probability }.max
      state_max_probabilities[index+1][state] = @observation_probabilities[state][observation] * max_probability
    end
  end

  state_max_probabilities
end
max_probabilities(observation_sequence) click to toggle source
# File lib/rubykov/hidden_markov_model.rb, line 21
def max_probabilities(observation_sequence)
  compute_viterbi_probabilities(observation_sequence.map(&:to_sym)).map do |probability|
    probability.max_by { |k,v| v }
  end
end
sample(probability_distribution) click to toggle source
# File lib/rubykov/hidden_markov_model.rb, line 48
def sample(probability_distribution)
  random_value = rand

  probability_ranges = probability_distribution.inject([0]) do |memo, p|
    memo << p.last + memo.last
  end

  probability_distribution[probability_ranges.rindex { |x| x <= random_value }].first
end