Ruby写的向前算法

隐马尔科夫模型中有三个问题:

1) 估计问题:给定一个观察序列O=O1O2...OT和模型u = (A, B, π), 如何快速地计算出给定模型u情况下,观察序列O的概率,即P(O|u)

2) 序列问题: 给定观察序列O=O1O2...OT和模型u = (A, B, π), 如何快速有效地选择在一定意义下“最优”的状态序列Q=q1q2...qT,使得该状态序列“最好地解释”观察序列?

3) 训练问题或参数估计:给定一个观察序列O=O1O2...OT,如何根据最大似然估计来求模型的参数值?即如何调节模型u=(A, B, π)的参数,使得P(O|u)最大?

问题1是一个解码问题,前向算法可以解决该问题(forward procedure),也是动态规划法的一种应用。

关于前向算法的基础知识可以看下面的文章

http://www.cnblogs.com/tornadomeet/archive/2012/03/24/2415583.html

最后是ruby代码

 

class FowardAlgorithm

  def initialize(pi, trans_pro, emit_pro)

    @pi = pi

    @trans_pro = trans_pro

    @emit_pro = emit_pro

  end



  def alpha1(state, ob)

    @pi[state] * @emit_pro[state][ob]

  end



  def alpha(t, state)

    # t starts from 0, states starts from 9

    if t.equal? 0

      alpha1(state, @ob[0])

    else

      sum = (0...@trans_pro.size).inject(0.0) { |sum, i| sum += alpha(t-1, i) * @trans_pro[i][state] }

      sum * @emit_pro[state][@ob[t]]

    end

  end



  def p_rerial_n ob

    n = ob.size

    n -= 1

    @ob = ob

    # time & states

    res = 0.0

    0..@trans_pro.size.times { |i|

      #print "time #{n}, state #{i}"

      tmp = alpha n, i

      res += tmp

    }

    res

  end

end



def test

  pi = [0.2, 0.4, 0.4]

  trans_pro = [

      [0.5, 0.2, 0.3],

      [0.3, 0.5, 0.2],

      [0.2, 0.3, 0.5]

  ]



  emit_pro = [

      [0.5, 0.5],

      [0.4, 0.6],

      [0.7, 0.3]

  ]



  f = FowardAlgorithm.new pi, trans_pro, emit_pro

  puts f.p_rerial_n([0, 1, 0, 1])

end



if $PROGRAM_NAME == __FILE__

  test

end

 

你可能感兴趣的:(Ruby)