Алгоритм "Вперед-Назад" — различия между версиями
 (→Псевдокод)  | 
				 (→Псевдокод)  | 
				||
| Строка 57: | Строка 57: | ||
== Псевдокод ==  | == Псевдокод ==  | ||
| − | <font color=  | + | <font color=darkgreen>  | 
  // fwd, bkw {{---}} матрицы размера |S|*T, которым во время работы присваиваются промежуточные результаты alpha и beta    |   // fwd, bkw {{---}} матрицы размера |S|*T, которым во время работы присваиваются промежуточные результаты alpha и beta    | ||
| − |   // probabilities {{---}} матрица размера |S|*T, в которую заносится ответ  | + |   // probabilities {{---}} матрица размера |S|*T, в которую заносится ответ  | 
| + |  // S - массив состояний, П - массив начальных вероятностей, O - последовательность наблюдений  </font>  | ||
| − | + |    '''fun''' alpha(s: '''int''', t: '''int'''): '''int'''  | |
       '''if''' (s, t) '''in''' fwd  |        '''if''' (s, t) '''in''' fwd  | ||
           '''return''' fwd[s, t]  |            '''return''' fwd[s, t]  | ||
| Строка 71: | Строка 72: | ||
       '''return''' fwd[s, t]  |        '''return''' fwd[s, t]  | ||
| − | + |    '''fun''' beta(s: '''int''', t: '''int'''): int  | |
       '''if''' (s, t) '''in''' bkw  |        '''if''' (s, t) '''in''' bkw  | ||
           '''return''' bkw[s, t]  |            '''return''' bkw[s, t]  | ||
| Строка 80: | Строка 81: | ||
       '''return''' bkw[s, t]  |        '''return''' bkw[s, t]  | ||
| − | + |    '''fun ''' forward_backward():  | |
       '''for''' s '''in''' S  |        '''for''' s '''in''' S  | ||
           fwd[s, 1] = emitProbability[s][observations[1]] * П[s]  |            fwd[s, 1] = emitProbability[s][observations[1]] * П[s]  | ||
| − |            bkw[s,   | + |            bkw[s, observations.length - 1] = 1  | 
       chainProbability = 0  |        chainProbability = 0  | ||
       '''for''' j '''in''' S  |        '''for''' j '''in''' S  | ||
Версия 13:37, 8 марта 2018
Пусть дана скрытая Марковская модель , где — состояния, — возможные события, — начальные вероятности, — матрица переходов, а — вероятность наблюдения события после перехода в состояние .
За шагов в этой модели получилась последовательность наблюдений .
Алгоритм "вперед-назад" позволяет найти в скрытой Марковской модели вероятность попадания в состояние на -ом шаге при последовательности наблюдений и (скрытой) последовательности состояний .
Содержание
Вычисление
Пусть в момент мы оказались в состоянии : . Назовем вероятность того, что при этом во время переходов образовалась последовательность наблюдений , а — вероятность того, что после этого состояния мы будем наблюдать последовательность наблюдений :
Нам требуется найти . Поскольку будущее Марковской цепи не зависит от прошлого, мы можем утверждать, что вероятность того, что мы будем наблюдать события не зависит от того, что в прошлом мы наблюдали последовательность , и, следовательно:
Проход вперед
Заметим, что в нужно считать равной , как вероятность получить первое событие из начального распределения.
Для следующих можно вычислить рекуррентно:
Итак, вероятность попасть в состояние на -ом шаге, учитывая, что после перехода произойдет событие будет равна вероятности быть в состоянии на -ом шаге, умноженной на вероятность перейти из состояния в , произведя событие для всех .
Проход назад
Аналогично, , так как произвольная цепочка наблюдений будет произведена, какими бы ни были состояния.
Предыдущие считаются рекуррентно:
Сглаживание вероятности
Итак, для произвольного состояния в произвольный шаг теперь известна вероятность того, что на пути к нему была произведена последовательность и вероятность того, что после него будет произведена последовательность . Чтобы найти вероятность того, что будет произведена цепочка событий, найти , нужно просуммировать произведение обеих вероятностей для всех состояний при произвольном шаге t: .
Теперь найдем вероятность того, что в момент цепь будет в состоянии :
Пример
Пусть ваша жизнь не удалась и вам пришлось работать охранником в холле офисного здания. Каждое утро вы наблюдали за тем, как один и тот же мужчина либо приносил, либо не приносил зонтик в зависимости от погоды. Увлекаясь статистикой, вы выяснили, что за день погода может поменяться с вероятностью ; если на улице идет дождь, то мужчина приносит зонтик с вероятностью , а если солнечно — то с вероятностью (пример справа).
Но вот вас переводят смотреть за камерами наблюдения: теперь вы не можете наблюдать за погодой, но каждый день видите того мужчину. За рабочую неделю вы заметили, что он не принес зонтик лишь в среду. С какой вероятностью во вторник шел дождь?
По вышесказанному, .
Итак, с вероятностью во вторник шел дождь.
Псевдокод
// fwd, bkw — матрицы размера |S|*T, которым во время работы присваиваются промежуточные результаты alpha и beta 
// probabilities — матрица размера |S|*T, в которую заносится ответ
// S - массив состояний, П - массив начальных вероятностей, O - последовательность наблюдений  
  
  fun alpha(s: int, t: int): int
     if (s, t) in fwd
         return fwd[s, t]
     f = 0
     for j in S
         f += alpha(j, t - 1) * transitionProbability[j][s]
     f *= emitProbability[s][observations[t]]
     fwd[s, t] = f
     return fwd[s, t]
     
  fun beta(s: int, t: int): int
     if (s, t) in bkw
         return bkw[s, t]
     b = 0
     for j in S
         b += beta(j, t + 1) * transitionProbability[s][j] * emitProbability[j][O[t + 1]]
     bkw[s, t] = b
     return bkw[s, t]
     
  fun  forward_backward():
     for s in S
         fwd[s, 1] = emitProbability[s][observations[1]] * П[s]
         bkw[s, observations.length - 1] = 1
     chainProbability = 0
     for j in S
         chainProbability += alpha(j, 1) * beta(j, 1)
     for s in S
         for t in [1, T]
             probabilities[s, t] = (alpha(s, t) * beta(s, t)) / chainProbability
