The Viterbi algorithm can solve the most likely state sequence problem of the Hidden Markov Model.
On Wikipedia, a python example is provided for the Viterbi algorithm. The original Article address is as follows:
Http://zh.wikipedia.org/wiki/%E7%BB%B4%E7%89%B9%E6%AF%94%E7% AE %97%E6%B3%95
Since we are learning Ruby recently, we have migrated this algorithm from Python to Ruby. the syntax of these two languages is very close, so it is not difficult to move forward, I hope you can understand the basic theory of the Viterbi algorithm before using the code.
##
#encoding: utf-8
puts ‘This is Viterbi’
$ states = [: Healthy,: Fever]
#puts "length: # {$ states.length}"
$ obervastions = [: normal,: cold,: dizzy]
$ start_probability = {Healthy: 0.6, Fever: 0.4}
# puts $ start_probability [$ states [0]]
$ transition_probability = {
Healthy: {Healthy: 0.7, Fever: 0.3},
Fever: {Healthy: 0.4, Fever: 0.6},
}
$ emission_probability = {
Healthy: {normal: 0.5, cold: 0.4, dizzy: 0.1},
Fever: {normal: 0.1, cold: 0.3, dizzy: 0.6}
}
def print_dptable (v)
puts ‘‘
for i in 0..v.length
puts "% 7d"% i
end
for y in v [0] .keys
puts "% 5s"% y
for t in 0 ... v.length
puts "% .7s"% ("% f"% v [t] [y])
end
end
end
def viterbi (obs, states, start_p, trans_p, emit_p)
v = [{}]
path = {}
# Initialize base cases (t == 0)
states.each {| y |
v [0] [y] = start_p [y] * emit_p [y] [obs [0]]
path [y] = [y]
}
# Run Viterbi for t> 0
for t in 1 ... obs.length
v << {}
newpath = {}
for y in states
prob, state = states.map {| y0 |
[v [t-1] [y0] * trans_p [y0] [y] * emit_p [y] [obs [t]], y0]} .max
v [t] [y] = prob
newpath [y] = path [state] + [y]
end
# Do n‘t need to remember the old paths
path = newpath
end
print_dptable v
prob, state = states.map {| y | [v [obs.size-1] [y], y]} .max
return prob, path [state]
end
def example
viterbi $ obervastions,
$ states,
$ start_probability,
$ transition_probability,
$ emission_probability
end
puts example