热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

维特比算法的java实现_原创:维特比算法

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

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

ebc77569fac4d43e657071d27d27c509.png

f45afdb063eb3a3cb841e5c454f2ba4c.png

ae1f02d54c868b8bfb2d6fe82732204f.png

今天用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

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,:]),:]



推荐阅读
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • (三)多表代码生成的实现方法
    本文介绍了一种实现多表代码生成的方法,使用了java代码和org.jeecg框架中的相关类和接口。通过设置主表配置,可以生成父子表的数据模型。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
author-avatar
克乄浪木守
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有