精华内容
下载资源
问答
  • 维特比算法的目的: 寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states...本文通过分析维特比算法例子,来学习该算法 定义HMM的五个重要元素, # 隐藏序列 S states = ("Rainy", "Sunn...

    维特比算法的目的:

    寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states)


    关于原理的讲解可以参考下面两篇文章,讲的比较清楚
    小白给小白详解维特比算法1.
    小白给小白详解维特比算法2.


    本文通过分析维特比算法的例子,来学习该算法

    1. 定义HMM的五个重要元素,
    # 隐藏序列 S
    states = ("Rainy", "Sunny")
    
    # 观测序列 K
    observations = ('walk', 'shop', 'clean')
    
    # 初始概率 π
    start_probability = {'Rainy': 0.6, "Sunny": 0.4}
    
    # 转移概率 A
    transition_probability = {
        'Rainy': {"Rainy": 0.7, "Sunny": 0.3},
        "Sunny": {"Rainy": 0.4, "Sunny": 0.6}
    }
    
    # 发射概率  B
    emission_probability = {
        "Rainy": {"walk": 0.1, "shop": 0.4, "clean": 0.5},
        "Sunny": {"walk": 0.6, "shop": 0.3, "clean": 0.1},
    }
    
    

    2.定义初始化状态

        # 路径概率表 V[时间][隐状态] = 概率
        V = [{}]
        # 一个中间变量,代表当前状态是哪个隐状态
        path = {}
        # 初始化初始状态 t=0
        for y in states:
            V[0][y] = start_p[y] * emit_p[y][obs[0]]
            path[y] = [y]
    

    V[时间][天气] = 概率
    观测序列(observations)得到的结果 观测对象第一天是散步
    计算第一天的天气:
    V[第一天][天晴] = 初始概率[天晴] * 发射概率[散步] = 0.4 * 0.6 = 0.24
    V[第一天][下雨] = 初始概率[下雨] * 发射概率[散步] = 0.6 * 0.1 = 0.06
    计算结果可见,第一天天晴的概率比较大。
    此时初始的路径 path = {}


    1. 后面天气的情况都是根据前一天天气概率×转移概率×发射概率得到
    def vierbi(obs, states, start_p, trans_p, emit_p):
        """
        :param obs:     观察序列    K
        :param states:  隐藏状态    S
        :param start_p: 初始概率    π
        :param trans_p: 转移概率    A
        :param emit_p:  发射概率    B
        :return:
        """
        # 路径概率表 V[时间][隐状态] = 概率
        V = [{}]
        # 一个中间变量,代表当前状态是哪个隐状态
        path = {}
        # 初始化初始状态 t=0
        for y in states:
            V[0][y] = start_p[y] * emit_p[y][obs[0]]
            path[y] = [y]
    
        # 对t>0 跑一遍维特比算法
        for t in range(1, len(obs)):
            V.append({})
            newpath = {}
    
            for y in states:
                # 概率 隐状态 =  前状态是y0的概率 * y0转移到y的概率 * y表现为当前状态的概率
                (prob, state) = max([(V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]], y0) for y0 in states])
    
                # 记录最大概率
                V[t][y] = prob
                # 记录路径
                newpath[y] = path[state] + [y]
    
            # 不需要保存旧路径
            path = newpath
    
        print_dptable(V)
        (prob, state) = max([(V[len(obs) - 1][y], y) for y in states])
        return prob, path[state]
    

    第二天: 由观测序列可得 observations[1] = ‘购物’
    ① 首先看计算第二天下雨的概率

    • V[第二天][下雨] = V[第一天][下雨] * 转移概率[下雨][下雨] * 发射概率[下雨][购物] = 0.06 * 0.7 * 0.4 = 0.0168
    • V[第二天][下雨] = V[第一天][天晴] * 转移概率[天晴][下雨] * 发射概率[下雨][购物] = 0.24 * 0.4 * 0.4 = 0.0384
      同样在这里取最大概率
      V[第二天][下雨] = 0.0384
      得到的新路径 newpath[下雨] = [晴天,下雨]

    ②然后计算第二天天晴的概率

    • V[第二天][天晴] = V[第一天][下雨] * 转移概率[下雨][天晴] * 发射概率[天晴][购物] = 0.06 * 0.3 * 0.3 = 0.0054
    • V[第二天][天晴] = V[第一天][天晴] * 转移概率[天晴][天晴] * 发射概率[天晴][购物] = 0.24 * 0.6 * 0.3 = 0.0432
      V[第二天][天晴] = 0.0432
      得到的新路径 newpath[晴天] = [晴天,晴天]

    第二天计算完成之后得到前两天的路径
    paht={雨天:[晴天,下雨],晴天:[晴天,晴天]}

    以同样的方式得到第三天的结果
    observations[1] = 打扫

    • V[第三天][下雨] = V[第二天][下雨] * 转移概率[下雨][下雨] * 发射概率[下雨][打扫] = 0.0384 * 0.7 * 0.5 = 0.01344
    • V[第三天][下雨] = V[第二天][天晴] * 转移概率[天晴][下雨] * 发射概率[下雨][打扫] = 0.0432 * 0.4 * 0.5 = 0.00864
      V[第三天][下雨] = 0.01344
      newpath[下雨] = [晴天,下雨,下雨]
    • V[第三天][天晴] = V[第二天][下雨] * 转移概率[下雨][天晴] * 发射概率[天晴][打扫] = 0.0384* 0.3 * 0.1 = 0.001152
    • V[第三天][天晴] = V[第二天][天晴] * 转移概率[天晴][天晴] * 发射概率[天晴][打扫] = 0.0432 * 0.6 * 0.1 = 0.002592
      V[第三天][天晴] = 0.002592
      newpath[晴天] = [晴天,晴天,晴天]
      把得到的newpath赋值给path

    最后通过找出V[第三天]中天气最大的那个概率得到天气的情况
    因此第三天的天气为V[第三天][下雨] = 0.01344
    由此可反推得到路径path[下雨] = [晴天,下雨,下雨]

    图形表示如下,第二天之后的天气概率计算后取最大值,根据第三天天气的最大概率再反推天气的路径

    在这里插入图片描述

    上面就是维特比算法实现的详解,下面是完整代码。

    # -*- coding:utf-8 -*-
    # @Time     :2019/5/27 15:30
    # @author   :ding
    # @filename :vertibi.py
    
    """
    维特比算法的实现
    HMM 五个重要元素
    S 隐藏序列的集合
    K 输出状态或观测状态的集合
    π对应隐藏状态的的初始概率
    A 隐藏状态的转移概率 是一个N*M的概率矩阵
    B 影厂状态到观测状态的混淆矩阵,是一个N*M的发射概率的矩阵
    """
    
    # 隐藏序列 S
    states = ("Rainy", "Sunny")
    
    # 观测序列 K
    observations = ('walk', 'shop', 'clean')
    
    # 初始概率 π
    start_probability = {'Rainy': 0.6, "Sunny": 0.4}
    
    # 转移概率 A
    transition_probability = {
        'Rainy': {"Rainy": 0.7, "Sunny": 0.3},
        "Sunny": {"Rainy": 0.4, "Sunny": 0.6}
    }
    
    # 发射概率  B
    emission_probability = {
        "Rainy": {"walk": 0.1, "shop": 0.4, "clean": 0.5},
        "Sunny": {"walk": 0.6, "shop": 0.3, "clean": 0.1},
    }
    
    
    def print_dptable(V):
        print("     ")
        for i in range(len(V)): print("%7d" % i, end="")
        print()
        for y in V[0].keys():
            print("%.5s: " % y, end=" ")
            for t in range(len(V)):
                print("%.7s" % V[t][y], end=" ")
            print()
    
    
    def vierbi(obs, states, start_p, trans_p, emit_p):
        """
    
        :param obs:     观察序列    K
        :param states:  隐藏状态    S
        :param start_p: 初始概率    π
        :param trans_p: 转移概率    A
        :param emit_p:  发射概率    B
        :return:
        """
        # 路径概率表 V[时间][隐状态] = 概率
        V = [{}]
        # 一个中间变量,代表当前状态是哪个隐状态
        path = {}
        # 初始化初始状态 t=0
        for y in states:
            V[0][y] = start_p[y] * emit_p[y][obs[0]]
            path[y] = [y]
    
        # 对t>0 跑一遍维特比算法
        for t in range(1, len(obs)):
            V.append({})
            newpath = {}
    
            for y in states:
                # 概率 隐状态 =  前状态是y0的概率 * y0转移到y的概率 * y表现为当前状态的概率
                (prob, state) = max([(V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]], y0) for y0 in states])
    
                # 记录最大概率
                V[t][y] = prob
                # 记录路径
                newpath[y] = path[state] + [y]
    
            # 不需要保存旧路径
            path = newpath
    
        print_dptable(V)
        (prob, state) = max([(V[len(obs) - 1][y], y) for y in states])
        return prob, path[state]
    
    
    def test():
        return vierbi(observations,
                      states,
                      start_probability,
                      transition_probability,
                      emission_probability
                      )
    
    
    print(test())
    
    

    打印结果如下
    输出


    维特比算法在NLP方面有很多的应用

    • 词性标注:给定一个词的序列,找出最可能的词性序列
    • 分词:给定一个字的序列,找出最可能的标签序列,可利用BMES这些标签来分词B(开头)M(中间词)E(结尾)S(单个词)
    • 明明实体识别:给定一个词的序列,找出最可能的标签序列

    本文讲的可能不是很清楚,有不对的地方,还请不吝指教。

    展开全文
  • 维特比算法说白了就是动态规划实现最短路径,只要知道...——《数学之美》下面我通过一个例子来解释讲解一下维特比算法!词性标注问题首先介绍一下什么是词性标注问题,比如我们有一句已经分词好的句子。dog chase ...

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

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

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

    词性标注问题

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

    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)的情况下,一共有

    种排列组合,每种组合计算联合概率的计算量为T,总的复杂度为

    ,这并不可取。

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

    维特比算法

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

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

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

    解释如下:

    # We implement the viterbi decoding algorithm.

    def viterbi(words, hmm):

    '''Viterbi algorihtm.Parameters----------words: list(str)The list of wordshmm: HMMThe hmm modelReturn------result: list(str)The POS-tag for each word.'''

    # unpack the length of words, and number of postags

    N, T = len(words), len(hmm.postags)

    # allocate the decode matrix

    score = [[-float('inf') for j in range(T)] for i in range(N)]

    path = [[-1 for j in range(T)] for i in range(N)]

    for i, word in enumerate(words):

    if i == 0:

    for j, tag in enumerate(hmm.postags):

    score[i][j] = hmm.emit(words, i, tag)

    else:

    for j, tag in enumerate(hmm.postags):

    best, best_t = -1e20, -1

    temp = 0

    # Your code here, enumerate all the previous tag

    for j2,tag2 in enumerate(hmm.postags):

    if best < hmm.trans(tag2,tag)*score[i-1][j2]:

    best = hmm.trans(tag2,tag)*score[i-1][j2]

    best_t = j2

    best*=hmm.emit(words,i,tag)

    score[i][j] = best

    path[i][j] = best_t

    #

    best, best_t = -1e20, -1

    for j, tag in enumerate(hmm.postags):

    if best < score[len(words)- 1][j]:

    best = score[len(words)- 1][j]

    best_t = j

    result = [best_t]

    best, best_t = -1e20, -1

    best_t = result[0]

    for i in range(len(words)-1, 0, -1):

    # Your code here, back trace to recover the full viterbi decode path

    result.append(path[i][best_t])

    best_t = result[-1] #result[-1]代表的是挑选最后一个

    # convert POStag indexing to POStag str

    result = [hmm.postags[t] for t in reversed(result)]

    return result

    致谢:

    郭江师兄

    展开全文
  • 维特比算法

    2019-09-05 15:20:44
    以下四篇文章对维特比算法进行非常好的讲解和代码实现,总结一点:维特比算法是从前往后计算当前可能状态对应下一时刻可能状态的所有...viterbi-algorithm 维特比算法例子解析 Python词性标注HMM+viterbi实现 ...

    以下四篇文章对维特比算法进行非常好的讲解和代码实现,总结一点:维特比算法是从前往后计算当前可能状态对应下一时刻可能状态的所有概率,直到最终状态,再从最终状态的概率中选取最大的状态,最后从后往前这递推回去。
    用维特比如何词性标注:思路很简单,我们输入的句子作为观测状态,而它们的词性作为隐状态,求解隐状态就是求解对应的每个词的词性;
    用维特比如何分词:基于上面的词性标注得到每个词的词性或者状态
    STATES={‘B’,‘M’,‘E’,‘S’},再根据一定的准则就可以把词与词分开。可以参看这篇文章

    小白给小白详解维特比算法(一)
    小白给小白详解维特比算法(二)
    viterbi-algorithm 维特比算法的例子解析
    Python词性标注HMM+viterbi实现

    展开全文
  • 这是统计学习方法中的一道题目,下面是维特比算法的代码实现: 1 import numpy as np 2 3 A = np.array([(0.5, 0.2, 0.3), (0.3, 0.5, 0.2), (0.2, 0.3, 0.5)]) 4 B = np.array([(0.5, 0.5), (0.4, 0.6),...

    这是统计学习方法中的一道题目,下面是维特比算法的代码实现:

     1 import numpy as np
     2 
     3 A = np.array([(0.5, 0.2, 0.3), (0.3, 0.5, 0.2), (0.2, 0.3, 0.5)])
     4 B = np.array([(0.5, 0.5), (0.4, 0.6), (0.7, 0.3)])
     5 P = np.array([(0.2, 0.4, 0.4)])
     6 o = np.array([(0, 1, 0)])
     7 
     8 T = 3
     9 n = np.zeros((T, T))
    10 m = np.zeros((T, T))
    11 ans_t = np.zeros(T)
    12 
    13 for i in range(3):   #i代表第几步
    14     for t in range(T):  #t代表状态
    15         if i == 0:  #初始状态的处理
    16             n[i][t] = P[i][t] * B[t][o[0][i]]
    17         else:
    18             for pre_t in range(T):
    19                 n[i][t] = max(n[i][t], n[i-1][pre_t] * A[pre_t][t])
    20             n[i][t] = n[i][t] * B[t][o[0][i]]
    21             m[i][t] = np.array([n[i-1][j] * A[j, t] for j in range(T)]).argmax()
    22 
    23 ans_t[T-1] = n[T-1, :].argmax() + 1
    24 for t in range(T-2, -1, -1):
    25      ans_t[t] = m[t+1][int(ans_t[t+1]) - 1] + 1
    26 
    27 print(ans_t)

     

    转载于:https://www.cnblogs.com/zyb993963526/p/9087036.html

    展开全文
  • //维特比算法,维基百科例子的C++实现 #include #include #include using namespace std; int main() { //状态空间 string state_1("Healthy"); string state_2("Fever"); //观察空间 string ...
  • HMM的维特比算法的一个实际例子

    千次阅读 2018-11-26 20:32:16
    HMM的维特比算法的一个实际例子 标签(空格分隔): 自然语言处理 用一个分词的HMM的例子做个解释 任务: 将“我来到苏州”分词 理想结果 【“我”,“来到”,“苏州”】 定义参数 要定义的参数主要有:状态参数、...
  • 维特比算法改进即python实现简介用以下例子进行说明1. 题目2. 已知情况3.计算过程代码实现 简介 本文实现了维特比算法中选择前k个最优的路径算法。通常的维特比算法会算出到每一个节点的最优路径,计算复杂度比较高...
  • 文章目录命名实体识别学习-从基础算法开始(01)-维特比算法Day1: 维特比算法HMM的小例子题目背景将问题抽象为一个HMMPython实现维特比算法手算维特比过程:伪代码:代码前期准备总结 代码地址:...
  • 维特比算法代码

    千次阅读 2018-06-10 12:51:20
    本文主要写一个关于维特比算法的代码,具体理论请参考一文搞懂HMM(隐马尔可夫模型):   HMM(隐马尔可夫模型)是用来描述隐含未知参数的统计模型,举一个经典的例子:一个东京的朋友每天根据天气{下雨,天晴}...
  • 实现1:有观测序列,发射概率,状态转移矩阵返回最佳路径 # --*--coding:utf-8--*-- import numpy as np # 隐状态 hidden_state=['sunny','rainy'] # 观测序列 observation=['walk','shop','clean'] ...
  • 5分钟理解维特比算法

    2019-08-17 10:32:13
    安德鲁·维特比老人家发明了... 下面我们用简单的例子(而不是深奥的数学公式)来理解维特比算法。 标题 图1中有若干个节点,S是起点,D0是终点,节点之间的连线是通道,每条通道的路程各不相同,现在问从起点...
  • 我们知道HMM需要解决三个问题,其中的decoding问题需要用维特比算法,那么什么是维特比呢?维特比算法是一种动态规划算法,在学xgboost的时候我们使用了一个技巧,t+1时刻的预测值为t时刻的预测值加上t+1时刻的预测...
  • 20180504完成此博客1.维特比算法简介 维特比算法实际是用动态规划解隐马尔可夫模型预测...举个例子下面用一个例子来说明维特比算法的数学计算的详细过程,更形象来理解维特比算法。4.上面例子的Python实现代码(end)...
  •  仍然需要说明的是,本节不是这个系列的翻译,而是作为维特比算法这一章的补充,将UMDHMM这个C语言版本的HMM工具包中的维特比算法程序展示给大家,并运行包中所附带的例子。关于UMDHMM这个工具包的介绍,大家可以...
  • 维特比算法详解

    2016-10-27 21:46:59
    HMM(隐马尔可夫模型)是用来描述隐含未知参数的统计模型,举一个经典的例子:一个东京的朋友每天根据天气{下雨,天晴}决定当天的活动{公园散步,购物,清理房间}中的一种,我每天只能在twitter上看到她发的推“啊,我...
  • 参考github-通用维特比算法的Java实现 一文搞懂HMM(隐马尔可夫模型)没啥新意,就是不熟悉算法,在网上找了个参考的例子,用Python实现了下算法,用于学习并理解此算法。维特比算法测试假设的问题 经典例子:一个...
  • HMM的前向算法和维特比算法已将在上一个博客讲过了,这节给出python的实现,例子是以李航老师《统计学习方法》上的算法和例题进行实现。 import numpy as np class HMM: def forward(self,Q,V,A,B,O,PI): "...
  • 通俗易懂维特比算法

    2019-04-20 11:26:16
    作者:athemeroy ...篱笆网络(Lattice)的最短路径问题 这个问题长什么样子?...已知下图的篱笆网络,每个节点之间的数字表示相邻节点之间的距离,举个例子来说,如果我走A→B1→C2→D1→EA→B1→C2...
  • HMM之维特比算法

    2017-05-24 18:59:42
    HMM(隐马尔可夫模型)是用来描述隐含未知参数的统计模型,举一个经典的例子:一个朋友每天根据天气{下雨,天晴}决定当天的活动{公园散步,购物,清理房间}中的一种,我每天只能在twitter上看到她发的推“啊,我前天...
  • 简介: viterbi算法其实就是多步骤每步多选择模型的最优选择问题,其在每一步的所有选择都保存了前续所有...用以下例子加以说明: 1.题目背景: 从前有个村儿,村里的人的身体情况只有两种可能:健康或者发烧。...
  • wikipedia上关于维特比算法,提供了一个python的例子,原文地址如下 http://zh.wikipedia.org/wiki/%E7%BB%B4%E7%89%B9%E6%AF%94%E7%AE%97%E6%B3%95 鉴于最近正在学习ruby,就把这个算法从python迁移到ruby,这两个...
  • 继上篇贝叶斯(http://www.cnblogs.com/zhiranok/archive/2012/09/22/native_bayes.html)后,一直想完成隐马尔科夫这篇,一是一直没有时间完成python的示例实现代码,二是想找一个区别于天气的隐马尔科夫例子。...
  • 寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states) 对于一个特殊的隐马尔科夫模型(HMM)及一个相应的观察序列...考虑天气的例子,我们知道一个描述天气和海藻状态的 HMM,而且我们还有一...
  • Viterbi 算法的定义 定义变量δt(i):表示时刻t状态为i的所有路径中的概率最大值,公式如下: 过程: 上面的符号之前都已经见过,这里不再解释,下面为了更好地理解这几步,我们来举个例子。 ...
  • 仍沿用上一节中HMM模型盒子和球的例子,已知盒子与球的模型及取3次球以后球的颜色观测序列{红,白,红},需推测三次取球可能对应的盒子序列(隐藏状态序列),...

空空如也

空空如也

1 2 3 4
收藏数 64
精华内容 25
关键字:

维特比算法例子