维特比算法(Viterbi)

 


import numpy as np


state_transfer = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])  # 状态转移矩阵
observe_prob = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])  # 观测概率矩阵
initial = np.array([0.2, 0.4, 0.4])  # 初始状态概率向量
observes = ['红', '白']  # 所有可能的观测集合
states = [0, 1, 2]  # 所有可能的状态集合
observe_seq = ['红', '白', '红']  # 观测序列


def argmax(path_value, state_transfer, states, state, m):  # 在t时刻状态为i的所有单个路径(i1,i2,...,it)中概率最大的路径第t-1个结点
    max_index = -1
    max_value = -1
    for statej in states:
        if path_value[m-1][statej] * state_transfer[statej][state] > max_value:
            max_value = path_value[m-1][statej] * state_transfer[statej][state]
            max_index = statej

    return max_index


def argmax2(path_value_len):
    max_index = -1
    max_value = -1
    for i in range(len(path_value_len)):
        if path_value_len[i] > max_value:
            max_value = path_value_len[i]
            max_index = i

    return max_index


def viterbi(state_transfer, states, observe_prob, initial, observe_seq):
    path_value = np.zeros(shape=(3, 3))  # 存储在t时刻状态为i的所有单个路径(i1,i2,...it)中概率最大值(t=0,1,2, i=0,1,2)
    path_node = np.zeros(shape=(3, 3), dtype=int) # 存储在t时刻状态为i的所有单个路径(i1,i2,...,it)中概率最大的路径第t-1个结点

    for m in range(len(observe_seq)):
        if m == 0:  #初始化
            for state in states:
                path_value[m][state] = initial[state] * observe_prob[state][observes.index(observe_seq[m])] #在t时刻状态为i的所有单个路径(i1,i2,...it)中概率最大值(t=0,1,2, i=0,1,2)

            path_node[m] = [-1, -1, -1]

        else:
            for state in states:  # 递推
                path_value[m][state] = max([path_value[m-1][statej] * state_transfer[statej][state] for statej in states]) \
                                       * observe_prob[state][observes.index(observe_seq[m])] # 在t时刻状态为i的所有单个路径(i1,i2,...it)中概率最大值(t=0,1,2, i=0,1,2)

                path_node[m][state] = argmax(path_value, state_transfer, states, state, m)  # 在t时刻状态为i的所有单个路径(i1,i2,...,it)中概率最大的路径第t-1个结点

    max_path_value = max(path_value[len(observe_seq)-1])
    path = []

    i_t = argmax2(path_value[len(observe_seq)-1]) #最优路径第t时刻状态
    path.append(i_t)

    for k in range(len(observe_seq)-1, -1, -1):  # 最优路径回溯
        i_t = path_node[k][i_t]
        path.append(i_t)

    print(list(reversed(path))[1:]) # 输出最优路径
    print(max_path_value)


if __name__ == '__main__':
    viterbi(state_transfer, states, observe_prob, initial, observe_seq)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值