看了宗成庆博士的《统计自然语言处理(中文信息处理)》的第六章,对维特比算法有着非常精辟的讲解。把其中的讲解上传上来,个人感觉比较正统。

今天用Java实现了这个算法,也可以转换为C代码:

package com.nlp.hmm.algorithm.viterbi;

/**

* 维特比算法

*

* @author XueQiang Tong

* @date 2017/04/25

*/

public class Viterbi {

/**

* @param obs

* 观察输出序列

* @param state

* 状态序列(隐式)

* @param start_p

* 初始概率

* @param trans_p

* 状态转换概率

* @param emit_p

* 发射概率

* @return 返回最优状态路径(这个路径具有最好的解释能力)

*/

public static int[] compute(int obs[], int state[], double[] start_p, double[][] trans_p, double[][] emit_p) {

double v[][] = new double[obs.length][state.length];// viterbi值矩阵

int path[][] = new int[state.length][obs.length];// 存储路径

// 1.初始化时间序列为0的节点( t=0)

for (int s : state) {

v[obs[0]][s] = start_p[s] * emit_p[s][obs[0]];

path[s][obs[0]] = s;

}

// 2.开始递归计算viterbi矩阵(从t=1开始)

for (int t = 1; t < obs.length; ++t) {

int newpath[][] = new int[state.length][obs.length];// 每次迭代时,定义一个新的存储path,因为每个时间序列的path都依赖于

// 上个序列的path

// 对该时间序列上的每个state节点进行迭代,每个节点都与上个序列的所有state交互

for (int s : state) {

double maxValue = -1.0;

int label = -1;

for (int s0 : state) {// 寻找出备选路径

double viterbiValue = v[t - 1][s0] * trans_p[s0][s] * emit_p[s][obs[t]];

if (viterbiValue > maxValue) {

maxValue = viterbiValue;

label = s0;

// 记录最大概率

v[t][s] = maxValue;

// 记录路径

System.arraycopy(path[label], 0, newpath[s], 0, t);

newpath[s][t] = s;

}

}

}

path = newpath;

}

// 找出最后一个时间序列上的viterbi值最大的state,从而找出最优路径

double maxValue = -1.0;

int label = -1;

for (int s : state) {

if (v[obs.length - 1][s] > maxValue) {

maxValue = v[obs.length - 1][s];

label = s;

}

}

return path[label];

}

}

测试文件:

1 packagecom.nlp.hmm.algorithm.viterbi;2

3

4 public classViterbiTest {5

6 public static voidmain(String[] args) {7 int[] obs = {0,1,2};//0--walk,1--shop,2--clean

8 int[] states = {0,1};//0--rainy,1--sunny

9 double[] start_p = {0.6,0.4};//0.6--rainy,0.4--sunny

10 double[][] trans_p = new double[states.length][states.length];//0--rainy,1--sunny

11 trans_p[0][0] = 0.7;12 trans_p[0][1] = 0.3;13 trans_p[1][0] = 0.4;14 trans_p[1][1] = 0.6;15 double[][] emit_p = new double[states.length][obs.length];//dimension1:rainy 0,sunny 1;dimension2:walk 0 shop 1 clean 2

16 emit_p[0][0] = 0.1;17 emit_p[0][1] = 0.4;18 emit_p[0][2] = 0.5;19 emit_p[1][0] = 0.6;20 emit_p[1][1] = 0.3;21 emit_p[1][2] = 0.1;22 int []path =Viterbi.compute(obs, states, start_p, trans_p, emit_p);23 for (intpa:path){24 System.out.print(pa+" ");25 }26 }27

28 }

输出结果为1,0,0,就是sunny,rainy,rainy。对比了一下,结果没问题,逻辑也没问题。维特比算法和前向搜索算法有着共同点,两者解决的hmm问题不一样。

下面是本人的python实现代码:

import numpy as np

def viterbi(obs,state,start_prob,transition_prob,emit_prob):

vit = np.array(np.zeros(shape = [len(obs),len(state)],dtype = np.float64))

path = np.array(np.zeros(shape = [len(state),len(obs)],dtype = np.int32))

#初始化

for i in range(len(state)):

vit[0,i] = start_prob[i] * emit_prob[i][0]

path[i][0] = state[i]

for t in range(1,len(obs)):

newPath = np.zeros_like(path)

v = np.dot(np.reshape(vit[t-1],[len(state),1]),np.reshape(emit_prob[:,t],[1,len(state)])) * transition_prob

vi = np.max(v,axis = 0)

vit[t,:] = vi[:]

pa = np.argmax(v,axis = 0)

for i in range(len(pa)):

label = pa[i]

newPath[i,:] = path[label,:]

newPath[i][t] = state[i]

path = newPath

return path[np.argmax(vit[len(obs)-1,:]),:]

维特比算法的java实现_原创:维特比算法相关推荐

  1. 人工蜂群算法的java代码_求人工蜂群算法的c程序源代码``````谢谢各位大神了``````...

    展开全部 /* ABC algorithm coded using C programming language */ /* Artificial Bee Colony (ABC) is one of ...

  2. 维特比算法的java实现_维特比算法通俗明白

    维特比算法说白了就是动态规划实现最短路径,只要知道"动态规划可以降低复杂度"这一点就能轻松理解维特比算法维特比算法是一个特殊但应用最广的动态规划算法,利用动态规划,可以解决任何一个 ...

  3. 冒泡排序java代码_看动画学算法之:排序冒泡排序

    点击上方的蓝字关注我吧 程序那些事 简介 排序可能是所有的算法中最最基础和最最常用的了.排序是一个非常经典的问题,它以一定的顺序对一个数组(或一个列表)中的项进行重新排序. 排序算法有很多种,每个都有 ...

  4. 蚁群算法java实现_简单蚁群算法 + JAVA实现蚁群算法

    一 引言 蚁群算法(ant colony optimization,ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型技术.它由Marco Dorigo于1992年在他的博士论文中引入,其灵 ...

  5. java令牌_基于令牌桶算法的Java限流实现

    项目需要使用限流措施,查阅后主要使用令牌桶算法实现,为了更灵活的实现限流,就自己实现了一个简单的基于令牌桶算法的限流实现. 令牌桶算法描述 令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以 ...

  6. 蚁群优化算法的JAVA实现_优化算法|蚁群算法的理解及实现

    蚁群算法 1. 蚁群算法基本原理 蚁群算法(Ant Colony Algorithm, ACA)由Marco Dorigo于1992年提出. 蚁群原理: 蚁群算法的基本原理来源于自然界觅食的最短路径原 ...

  7. java快排算法解读,java 快排的思路与算法

    java 快排的思路与算法 有时候面试的时候的会问道Arrays.sort()是怎么实现的,我以前根本不知道是什么东西,最近点进去看了一下.直接吓傻, //看到这个时候还是比较淡定的,可怕的事情来了. ...

  8. 什么是算法算法有些什么特性_反正是什么算法

    什么是算法算法有些什么特性 What you need to know about the simple concept that powers the modern world. 您需要了解为现代世 ...

  9. 二分法算法复杂度简化_让我们简化算法的复杂性!

    二分法算法复杂度简化 by Shruti Tanwar 通过Shruti Tanwar 让我们简化算法的复杂性! (Let's simplify algorithm complexities!) It ...

最新文章

  1. dos 下启动mysql时,报服务器找不到错误
  2. access violation reading 0x0000000000000020
  3. IE下实现全屏两方法
  4. StrategyPattern--策略模式java实现
  5. 量子计算101:浅谈其需求、前景和现实
  6. 【Java代码】未分页数据根据参数进行分页(粘贴可用)
  7. 用碧海潮声制作的宋体(雅黑宋体)替换Windows7原生的火柴棍式的宋体
  8. css用一张大图片来设置背景的技术真相
  9. java刚进公司做什么?
  10. WEB前端开发工程师 学习第二天 边框
  11. linux入门和简单应用举例
  12. 基于单片机的智能温度监测系统设计(电路图+程序)
  13. java 解析yml文件
  14. 一文搞懂无刷电机和有刷电机
  15. 刨根究底字符编码之—UTF-16编码方式
  16. 译文:dBA和dBC的不同
  17. HTML5 开发工具
  18. 区块链技术在食品供应链领域的应用
  19. oracle转换全角函数,Oracle全角変換
  20. spring的 init-method和 destory-method方法

热门文章

  1. 双路cpu比单路强多少_双路cpu比单路强多少
  2. 计算机网络的数据处理模式,协同计算机数据处理方法的研究.pdf
  3. 中国专利数据库(85-22)
  4. GET日志服务如何使用让你获得建立DT时代海量日志处理能力
  5. 第三讲:https免费证书获取
  6. 智慧养老解决方案的优点和不足
  7. 《屋檐三境》——梦天岚
  8. 张玲专家:传承中医精髓,严谨辨证治疗
  9. E. Product Oriented Recurrence(codeforces R566 div2)
  10. oracle的基本概念