精华内容
下载资源
问答
  • 假设栅栏图的长为N,宽为D.维特比算法在每两层之间比较D*D次,保留到下一层最长路径,依次递归,所以算法复杂度为O(N*D*D) 暴力搜索的话是O(D^N)

    假设栅栏图的长为N,宽为D.维特比算法在每两层之间比较D*D次,保留到下一层最长路径,依次递归,所以算法复杂度为O(N*D*D)

    暴力搜索的话是O(D^N)

    展开全文
  • 维特比算法

    千次阅读 2018-06-12 13:21:51
    维特比算法维特比算法(Viterbi algorithm)是在一个用途非常广的算法,本科学通信的时候已经听过这个算法,最近在看 HMM(Hidden Markov model) 的时候也看到了这个算法。于是决定研究一下这个算法的原理及其具体...

    维特比算法

    维特比算法(Viterbi algorithm)是在一个用途非常广的算法,本科学通信的时候已经听过这个算法,最近在看 HMM(Hidden Markov model) 的时候也看到了这个算法。于是决定研究一下这个算法的原理及其具体实现,如果了解动态规划的同学应该很容易了解维特比算法,因为维特比算法的核心就是动态规划。

    对于 HMM 而言,其中一个重要的任务就是要找出最有可能产生其观测序列的隐含序列。一般来说,HMM问题可由下面五个元素描述

    1
    2
    3
    4
    5
    观测序列(observations):实际观测到的现象序列
    隐含状态(states):所有的可能的隐含状态
    初始概率(start_probability):每个隐含状态的初始概率
    转移概率(transition_probability):从一个隐含状态转移到另一个隐含状态的概率
    发射概率(emission_probability):某种隐含状态产生某种观测现象的概率

    下面以维基百科上的具体例子来说明

    想象一个乡村诊所。村民有着非常理想化的特性,要么健康要么发烧。他们只有问诊所的医生的才能知道是否发烧。 聪明的医生通过询问病人的感觉诊断他们是否发烧。村民只回答他们感觉正常、头晕或冷。
    假设一个病人每天来到诊所并告诉医生他的感觉。医生相信病人的健康状况如同一个离散马尔可夫链。病人的状态有两种“健康”和“发烧”,但医生不能直接观察到,这意味着状态对他是“隐含”的。每天病人会告诉医生自己有以下几种由他的健康状态决定的感觉的一种:正常、冷或头晕。这些是观察结果。 整个系统为一个隐马尔可夫模型(HMM)。
    医生知道村民的总体健康状况,还知道发烧和没发烧的病人通常会抱怨什么症状。 换句话说,医生知道隐马尔可夫模型的参数。则这些上面提到的五个元素表示如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    states = ('Healthy', 'Fever')

    observations = ('normal', 'cold', 'dizzy')

    start_probability = {'Healthy': 0.6, 'Fever': 0.4}

    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},
    }

    其对应的状态转移图如下所示

    状态转移图

    现在的问题是假设病人连续三天看医生,医生发现第一天他感觉正常,第二天感觉冷,第三天感觉头晕。 于是医生产生了一个问题:怎样的健康状态序列最能够解释这些观察结果。维特比算法解答了这个问题。

    首先直观地看这个问题,在HMM中,一个观测现象后面的对应的各个状态都有一个概率值,我们只需要选择概率值最大的那个状态即可,但是这个概率值是跟前面一个状态有关的(马尔科夫假设),因此不能独立考虑每个观测现象。

    为了从时间复杂度方面进行比较,现在将问题一般化:假设观测序列的长度为 m,隐含状态个数为 n。则有下面的隐含状态转移图(下图为了便于表示,将只画出n = 3 的图)。

    Viterbi 算法的状态图

    假如采用穷举法,穷举出所有可能的状态序列再比较他们的概率值,则时间复杂度是 O(nm)O(nm), 显然这样的时间复杂度是无法接受的,而通过维特比算法能把时间复杂度降到 O(mn2)O(m∗n2)

    从动态规划的问题去考虑这个问题,根据上图的定义,记 last_state 为上一个观测现象对应的各个隐含状态的概率,curr_state 为现在的观测现象对应的各个隐含状态的概率。则求解curr_state实际上只依赖于last_state。而他们的依赖关系可通过下面的 python 代码表示出来

    1
    2
    3
    4
    5
    for cs in states:
    curr_state[cs] = max(last_state[ls] *
    transition_probability[ls][cs] *
    emission_probability[cs][observation]
    for ls in states)

    计算过程利用了转移概率 transition_probability 和发射概率 emission_probability,选出那个最有可能产生当前状态 cs 的上一状态 ls

    除了上面的计算,同时要为每个隐含状态维护一个路径 path, path[s] 表示到达状态 s 前的最优状态序列。通过前面的计算选出那个最有可能产生当前状态 cs 的上一状态 ls后,往path[cs] 中插入 ls。则依照这种方法遍历完所有的观测序列后,只需要选择 curr_state 中概率值最大的那个 state 作为最终的隐含状态,同时从 path 中取出 path[state] 作为该最终隐含状态前面的状态序列。

    从上面的分析可知,观测序列只需要遍历一遍,时间复杂度为 O(m)O(m),而每次要计算当前各个状态最可能的前一状态,时间复杂度为 O(n2)O(n2),因此总体的时间复杂度为 O(mn2)O(m∗n2).

    假如在 NLP 中应用 HMM,则将词序列看做是观测到的现象,而词性、标签等信息看做是隐含状态,那么就可以通过维特比算法求解其隐含状态序列,而这也是 HMM 在分词,词性标注,命名实体识别中的应用。其关键往往是找出上面提到的初始概率(start_probability)、转移概率(transition_probability)、发射概率(emission_probability)。

    而在通信领域中,假如将收到的编码信息看作是观测序列,对应的解码信息为隐含状态,那么通过维特比算法也能够找出概率最大的解码信息。

    需要注意的是维特比算法适用于多步骤多选择的最优问题,类似于下面的网络,《数学之美》中将其叫做“篱笆网络(Lattice)”。每一步都有多个选择,并且保留了前面一步各个选择的最优解,通过回溯的方法找到最优选择路径。

    篱笆网络

    这里要强调的是 viterbi 算法可以用于解决 HMM 问题,但是也可以用于解决其他符合上面描述的问题。

    本文转载自:https://www.cnblogs.com/ylHe/p/6912017.html

    展开全文
  • 通俗理解维特比算法

    2018-10-22 19:32:34
    维特比算法说白了就是动态规划实现最短路径,只要知道“动态规划可以降低复杂度”这一点就能轻松理解维特比算法 维特比算法之所以重要,是因为凡是使用隐含马尔可夫模型描述的问题都可以用它来解码,包括今天的数字...

    转载自  通俗理解维特比算法

    本文假定读者有一定的隐马模型基础!或者大家可以参考这两篇文章。

    隐马尔科夫模型-基本模型与三个基本问题隐马尔科夫模型-前向算法

    维特比算法说白了就是动态规划实现最短路径,只要知道“动态规划可以降低复杂度”这一点就能轻松理解维特比算法

    维特比算法之所以重要,是因为凡是使用隐含马尔可夫模型描述的问题都可以用它来解码,包括今天的数字通信、语音识别、机器翻译、拼音转汉字、分词等。——《数学之美》

    下面我通过一个例子来解释讲解一下维特比算法!

     

    词性标注问题            

    首先介绍一下什么是词性标注问题,比如我们有一句已经分词好的句子。

    dog chase mouse

    那么我们就可以进行词性标注为:

    其中nn为名词,vv为动词。通过上面例子,我们就很容易看出词性标注的任务。

    那么我们来了一句话之后,比如我们的词性字典中有nn,vv,prp(代词),我们怎么能够找到dog

    chase mouse 所对应的词性标注呢,如果每一个单词有nn,vv,prp三种可能,那么将会有3*3*3=27种可能,我们如何去挑选呢?

    如下图:

     

    我们总共有27条路径,那么如何得到我们Dog chase mouse的最优路径呢?

    我们至少可以遍历每一条路径,求出各自的概率值,然后挑选最大的即可,比如我们求第一条路径的时候,可以这么表示:

    所求的路径对应如下图红色线条所示:

    求第27条路径的时候,我们可以这么表示:

     

    所求的路径对应如下图红色线条所示:

    那么我们从上面可以知道,要求一个句子的最优词性标注,我们至少可以遍历所有的路径,然后挑选概率值最大的那条路径即可!!!

     

    但是问题来了!            

    给定模型,求给定长度为T的观测序列(这里指的就是Dog Chase Mouse)的概率,直接计算法的思路是枚举所有的长度T(例子中是三个,Dog,Chase,Mouse总共三个单词)的状态序列,计算该状态序列与观测序列的联合概率(隐状态发射到观测),对所有的枚举项求和即可。

    在状态种类为N(例子中就是三个,NN,VV,PRP)的情况下,一共有 N^T种排列组合,每种组合计算联合概率的计算量为T,总的复杂度为0(TN^T),这并不可取。

    于是维特比算法隆重登场了!!

     

    维特比算法 

    好了,到现在为止,我们假定我们已经训练好了一个隐马尔可夫模型了(训练好的意思,也就是单词到词性的发射概率,词性与词性的转移概率都已经在训练数据中学习得到了),来了一句话,Dog Chase Mouse,我如何得到它的词性标注序列?

    首先先上一个维特比算法流程图:

    是不是非常晕,好吧,我下面争取按自己的话帮助大家理解一遍,再附上相应逻辑的代码!

    解释如下:

     

    实现代码如下:

    展开全文
  • 优点为:相比于一般的维特比算法,可以降低算法的运算复杂度与空间复杂度。使用者可以自行调节k值,来达到自己所要求的解的最优状况。 用以下例子进行说明 1. 题目 假设有这样一个问题,远在另一个城市上大学的小明...

    简介

    本文实现了维特比算法中选择前k个最优的路径算法。通常的维特比算法会算出到每一个节点的最优路径,计算复杂度比较高,本文选择前k个节点的最优路径进行计算到该节点的最优路径,计算次全局最优解。

    优点为:相比于一般的维特比算法,可以降低算法的运算复杂度与空间复杂度。使用者可以自行调节k值,来达到自己所要求的解的最优状况。

    用以下例子进行说明

    1. 题目

    假设有这样一个问题,远在另一个城市上大学的小明每天通过邮件向你汇报他今天做的事情是什么,这些事情可能是这四项之一:打球、访友、听歌、读书。那么在这种场景下,如何推测小明所在城市的天气情况。假设小明活动有如下规律:在晴天更可能打球,在阴天更可能访友,在雨天更可能的读书,在观测概率矩阵中显示为概率值大小。已知小明这三天的活动分别为:打球,听歌,读书。求小明所在城市这三天的天气状况。

    2. 已知情况

    隐含的天气状况 = {晴天,多云,雨天}
    可观察的活动 = {打球,访友,听歌,读书}
    起始的天气状况的概率分布 = {0.63,0.17,0.20}
    天气状况的转移概率分布为:

    竖向—>横向晴天多云雨天
    晴天0.50.3750.125
    多云0.250.1250.625
    雨天0.250.3750.375

    在不同天气下,小明不种活动的概率矩阵为:

    天气打球访友听歌读书
    晴天0.60.20.150.05
    多云0.250.250.250.25
    雨天0.050.100.350.5

    3.计算过程

    (1)计算第一天的概率

    P1 (晴天) = P(打球|晴天) * P(晴天|初始) = 0.6 * 0.63 = 0.378
    P1(多云) = P(打球|多云) * P(多云|初始) = 0.25 * 0.17 = 0.045
    P1(雨天) = P(打球|雨天) * P(雨天|初始) = 0.05* 0.20 = 0.010

    则P1(晴天)>P1(多云)>P1(雨天)=0.378>0.045>0.010

    与一般的维特比算法不同,我们在该阶段对数据进行删减,选择概率前k个状态(这里选择2)作为下一个状态转移的开始状态。即考虑下一个状态时,只考虑前一天为晴天和多云的状况。

    (2)计算第二天的概率

    P21(晴天) = P(听歌|晴天) * P(晴天|晴天) * P(晴天) = 0.15 * 0.5 * 0.378 = 0.02835
    P22(晴天) = P(听歌|晴天) * P(晴天|多云) * P(多云) = 0.15 * 0.25 * 0.045= 0.00169
    则 P2(晴天) = max{P21(晴天), P22(晴天)} = 0.02835

    P21(多云) = P(听歌|多云) * P(多云|晴天) * P(晴天) = 0.25 * 0.375 * 0.378 = 0.03543
    P22(多云) = P(听歌|多云) * P(多云|多云) * P(多云) = 0.25 * 0.125 * 0.045= 0.00141
    则 P2(多云) = max{P21(多云), P22(多云)} = 0.03543

    P21(雨天) = P(听歌|雨天) * P(雨天|晴天) * P(晴天) = 0.35 * 0.125 * 0.378 = 0.01654
    P22(雨天) = P(听歌|雨天) * P(雨天|多云) * P(多云) = 0.35 * 0.625 * 0.045= 0.00984
    则 P2(雨天) = max{P21(雨天), P22(雨天)} = 0.01654

    则P2(多云)>P2(晴天)>P2(雨天)=0.03543>0.02835>0.01654

    我们继续选择前k(2)个状态,即多云,晴天作为下一天的起始转移状态。

    (3)计算第三天的概率

    P31(晴天) = P(读书|晴天) * P(晴天|晴天) * P(晴天) = 0.05 * 0.5 * 0.02835 = 0.000708
    P32(晴天) = P(读书|晴天) * P(晴天|多云) * P(多云) = 0.05 * 0.25 * 0.03543= 0.004428
    则 P3(晴天) = max{P31(晴天), P32(晴天)} = 0.004428

    P31(多云) = P(读书|多云) * P(多云|晴天) * P(晴天) = 0.25 * 0.375 * 0.02835 = 0.002658
    P32(多云) = P(读书|多云) * P(多云|多云) * P(多云) = 0.25 * 0.125 * 0.03543 = 0.001107
    则 P3(多云) = max{P31(多云), P32(多云)} = 0.002658

    P31(雨天) = P(读书|雨天) * P(雨天|晴天) * P(晴天) = 0.5 * 0.125 * 0.02835 = 0.001772
    P32(雨天) = P(读书|雨天) * P(雨天|多云) * P(多云) = 0.5 * 0.625 * 0.03543 = 0.011072
    则 P3(雨天) = max{P31(雨天), P32(雨天)} = 0.011072

    则P3(雨天)>P3(晴天)>P3(多云)=0.011072>0.004428>0.002658

    综上所述,最后的判断小明所在城市这三天天气为:晴天 —> 多云 —> 雨天

    代码实现

    import numpy as np
    
    
    def viterbi(trainsition_probability, emission_probability, pi, obs_seq, k):
        # 转换为矩阵进行运算
        trainsition_probability = np.array(trainsition_probability)
        emission_probability = np.array(emission_probability)
        pi = np.array(pi)
        # 最后返回一个Row*Col的矩阵结果,第1行表示影藏状态,第2行表示概率
        Row = 2
        Col = len(obs_seq)
        # 定义要返回的矩阵
        f = np.zeros((Row, Col))
        # 定义基于前一状态k个最优计算该状态的概率
        result = np.zeros(np.array(trainsition_probability).shape[0])
        # 定义该状态的最优前k概率及位置,第一行为位置,第二行为概率
        tmp = np.zeros((2, k))
        # 定义选择k个最优的转移矩阵
        new_trainsition_probability = np.zeros((k, trainsition_probability.shape[1]))
        # 初始状态
        result = pi * emission_probability[:, obs_seq[0]]
        # 将初始状态下前k个最优按概率从大到小排序
        tmp[0, :] = result.argsort()[::-1][0:k]
        for i in range(0, k):
            tmp[1, i] = result[int(tmp[0, i])]
        f[:, 0] = tmp[:, 0]
        
        for t in range(1, Col):
            result = []
            # 重新设置该状态下的new_trainsition_probability
            for i in range(k):
                new_trainsition_probability[i, :] = trainsition_probability[int(tmp[0, i]), :] # 由于trainsition_probability中元素为浮点型,
                                                                                               # 需要转换为整型表示位置。 
            # 计算在前k个转态下,不同状态的概率
            for n in range(trainsition_probability.shape[1]):
                list_x = tmp[1, :] * new_trainsition_probability[:, n]
                # 获取最大概率
                result.append(np.max(list_x))
            result = np.array(result) * emission_probability[:, obs_seq[t]]
            # 将前k个最优按概率从大到小排序
            tmp[0, :] = np.array(result).argsort()[::-1][0:k]
            for i in range(0, k):
                tmp[1, i] = result[int(tmp[0, i])]
            f[:, t] = tmp[:, 0]
        return f
    
    
    if __name__ == '__main__':
        # 隐藏状态
        invisible = ['Sunny', 'Cloud', 'Rainy']
        # 初始状态
        pi = [0.63, 0.17, 0.20]
        # 转移矩阵
        trainsion_probility = [[0.5, 0.375, 0.125], [0.25, 0.125, 0.625], [0.25, 0.375, 0.375]]
        # 发射矩阵
        emission_probility = [[0.6, 0.2, 0.15, 0.05], [0.25, 0.25, 0.25, 0.25], [0.05, 0.10, 0.35, 0.5]]
        # 最后显示状态
        obs_seq = [0, 2, 3]
        # 设置k值
        k = 3
        # 最后返回一个Row*Col的矩阵结果
        F = viterbi(trainsion_probility, emission_probility, pi, obs_seq, k)
        print(F)
    
    

    程序输出的结果为:
    [[0. 1. 2. ]
    [0.378 0.0354375 0.01107422]]

    0表示晴天,1表示多云,2表示雨天,与所算的结果一致。

    参考自:

    https://blog.csdn.net/zhangduan8785/article/details/80443650
    https://blog.csdn.net/Luzichang/article/details/91365752

    展开全文
  • HMM之维特比算法

    千次阅读 2017-10-11 15:42:40
    HMM维特比算法及Python实现
  • 维特比算法说白了就是动态规划实现最短路径,就是说只要知道“动态规划可以降低复杂度”这一点就能轻松理解维特比算法维特比算法是一个特殊但应用最广的动态规划算法,利用动态规划,可以解决任何一个图中的...
  • 维特比算法(英语:Viterbi algorithm)是一种动态规划算法。它用于寻找最有可能产生观测事件序列的维特比路径——隐含状态序列,特别是在马尔可夫信息源上下文和隐马尔可夫模型中。 维特比算法利用动态规划,可以...
  • 维特比算法及python实现

    千次阅读 2018-10-14 23:19:34
    维特比算法(Viterbi) 维特比算法 维特比算法shiyizhong 动态规划算法用于最可能产生观测时间序列的-维特比路径-隐含状态序列,特别是在马尔可夫信息源上下文和隐马尔科夫模型中。术语“维特比路径”和“维特比...
  • 维特比算法说白了就是动态规划实现最短路径,只要知道“动态规划可以降低复杂度”这一点就能轻松理解维特比算法 维特比算法在机器学习中非常重要,在求解隐马尔科夫和条件随机场的预测问题中均用到了维特比算法。...
  • viterbi,维特比算法通俗理解

    千次阅读 2016-07-24 14:25:11
    维特比算法说白了就是动态规划实现最短路径,只要知道“动态规划可以降低复杂度”这一点就能轻松理解维特比算法 维特比算法是一个特殊但应用最广的动态规划算法,利用动态规划,可以解决任何一个图中的最短路径...
  • 维特比算法(Viterbi)

    万次阅读 2020-05-03 00:41:52
    维特比算法 (Viterbi algorithm) 是机器学习中应用非常广泛的动态规划算法,在求解隐马尔科夫、条件随机场的预测以及seq2seq模型概率计算等问题中均用到了该算法。实际上,维特比算法不仅是很多自然语言处理的解码...
  • 1、简介 维特比算法是一个特殊但应用最广的动态规划算法,它是针对篱笆网络的有向图(Lattice)的最短路径问题而提出的。凡是使用隐含马尔可夫模型描述的问题都可以用维特比算法来解码,包括今天的数字通信、...
  •  鉴于维特比算法可解决多步骤中每步多选择模型的最优选择问题,本文简要介绍了维特比算法的基本理论,并从源代码角度对维特比算法进行剖析,并对源码中涉及的要点进行了解读,以便能快速应用该算法解决自然语言处理...
  • 维特比算法基础

    2015-07-29 17:12:00
    维特比算法是一个特殊,但应用最广的动态规划算法。利用动态规划,可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图--篱笆网络(Lattice)的有向图最短路径问题而提出的。它之所以重要是因为,...
  • viterbi维特比算法

    2020-04-01 16:16:29
    维特比算法:使用动态规划,找出最短路径 以下以图的形式来解释: 图的节点按列组织,每列的节点数量可以不一样,每一列的节点只能和相邻列的节点相连,不能跨列相连,节点之间有着不同的距离,距离的值就不在图上...
  • 简述维特比算法(Viterbi Algorithm)

    千次阅读 2018-09-07 13:30:40
    维特比算法是一个特殊但应用最广的动态规划算法。利用动态规划,可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图——篱笆网络(Lattice)的有向图最短路径的问题而提出的。它之所以重要,是...
  • 维特比算法是一个特殊但应用最广的动态规划算法。利用动态规划,可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图-篱笆网了(Lattice)的有向图最短路径问题而提出来的。它之所以重要,是因为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,692
精华内容 676
关键字:

维特比算法复杂度