维特比算法:从众多路径中,挑出最优的那条,他和隐马尔可夫没有强关联


中文分词任务

语料库 => 训练集

初始、转移、发射矩阵 => 训练过程

维特比算法,得到真正结果

训练的时候,是用不到维特比算法的,只有分词时才会使用

算法思想

维特比(Viterbi)算法属于一种动态规划算法,目标在于寻找最优路径。

用动态规划来解决隐马尔可夫的预测问题,即用动态规划求概率最大路径(最优路径)。这时一条路径对应着一个状态序列



选中一条最优的路径,把节点标注出来,根据标注的节点状态序列就可以得到分词的结果了

维特比算法

从众多路径中,迅速选出最优路径

核心思想:边计算边删除,舍弃那些概率比较小的路径。

初始矩阵,人眼知道,有2个是0,ME不可能出现,但计算机不知道,也不确定某条路径就是最做优的,武断的选择B,有可能后面的概率就是0了

所以初始矩阵的4条路径,都是候选路径,

如果从B出发的话,有4条路径经过B,并且有一条最优,假设3是最优的,保存最优路径3,其它的全部删除



同理,到达M点。也是有4条路径,假设2是最优的,就把其它几条删除

从天到的

到 B 有四条,到 M 也有4条



每到达一个字都只会有4条路径,在4条路径中,选择最优的,则可得到状态序列分词结束

每个状态下连线很多,结果只有4条

代码

Viterbi.java

package com.vipsoft.viterbi;

/**
* 维特比算法
* @author hankcs
*/
public class Viterbi
{
/**
* 求解HMM模型
* @param obs 观测序列
* @param states 隐状态
* @param start_p 初始概率(隐状态)
* @param trans_p 转移概率(隐状态)
* @param emit_p 发射概率 (隐状态表现为显状态的概率)
* @return 最可能的序列
*/
public static int[] compute(int[] obs, int[] states, double[] start_p, double[][] trans_p, double[][] emit_p)
{
double[][] V = new double[obs.length][states.length];
int[][] path = new int[states.length][obs.length]; for (int y : states)
{
V[0][y] = start_p[y] * emit_p[y][obs[0]];
path[y][0] = y;
} for (int t = 1; t < obs.length; ++t)
{
int[][] newpath = new int[states.length][obs.length]; for (int y : states)
{
double prob = -1;
int state;
for (int y0 : states)
{
double nprob = V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]];
if (nprob > prob)
{
prob = nprob;
state = y0;
// 记录最大概率
V[t][y] = prob;
// 记录路径
System.arraycopy(path[state], 0, newpath[y], 0, t);
newpath[y][t] = y;
}
}
} path = newpath;
} double prob = -1;
int state = 0;
for (int y : states)
{
if (V[obs.length - 1][y] > prob)
{
prob = V[obs.length - 1][y];
state = y;
}
} return path[state];
}
}

WeatherExample.java

package com.vipsoft.viterbi;

import static com.vipsoft.viterbi.DoctorExample.Feel.cold;
import static com.vipsoft.viterbi.DoctorExample.Feel.dizzy;
import static com.vipsoft.viterbi.DoctorExample.Feel.normal;
import static com.vipsoft.viterbi.DoctorExample.Status.Fever;
import static com.vipsoft.viterbi.DoctorExample.Status.Healthy; public class DoctorExample
{
enum Status
{
Healthy,
Fever,
}
enum Feel
{
normal,
cold,
dizzy,
}
static int[] states = new int[]{Healthy.ordinal(), Fever.ordinal()};
static int[] observations = new int[]{normal.ordinal(), cold.ordinal(), dizzy.ordinal()};
static double[] start_probability = new double[]{0.6, 0.4};
static double[][] transititon_probability = new double[][]{
{0.7, 0.3},
{0.4, 0.6},
};
static double[][] emission_probability = new double[][]{
{0.5, 0.4, 0.1},
{0.1, 0.3, 0.6},
}; public static void main(String[] args)
{
int[] result = Viterbi.compute(observations, states, start_probability, transititon_probability, emission_probability);
for (int r : result)
{
System.out.print(Status.values()[r] + " ");
}
System.out.println();
}
}

https://github.com/hankcs/Viterbi

https://www.zhihu.com/question/20136144

HanLP — 路径规划算法 - 求解最短路径 - 维特比(Viterbi)算法的更多相关文章

  1. ZOJ 1456 Minimum Transport Cost(Floyd算法求解最短路径并输出最小字典序路径)

    题目链接: https://vjudge.net/problem/ZOJ-1456 These are N cities in Spring country. Between each pair of ...

  2. Dijkstra(迪杰斯特拉)算法求解最短路径

    过程 首先需要记录每个点到原点的距离,这个距离会在每一轮遍历的过程中刷新.每一个节点到原点的最短路径是其上一个节点(前驱节点)到原点的最短路径加上前驱节点到该节点的距离.以这个原则,经过N轮计算就能得 ...

  3. python利用kruskal求解最短路径的问题

    python利用kruskal算法求解最短路径的问题,修改参数后可以直接使用 def kruskal(): """ kruskal 算法 ""&quo ...

  4. HMM Viterbi算法 详解

    HMM:隐式马尔可夫链   HMM的典型介绍就是这个模型是一个五元组: 观测序列(observations):实际观测到的现象序列 隐含状态(states):所有的可能的隐含状态 初始概率(start ...

  5. Bellman-Ford & SPFA 算法——求解单源点最短路径问题

    Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...

  6. 全局路径规划算法Dijkstra(迪杰斯特拉算法)- matlab

    参考博客链接:https://www.cnblogs.com/kex1n/p/4178782.html Dijkstra是常用的全局路径规划算法,其本质上是一个最短路径寻优算法.算法的详细介绍参考上述 ...

  7. [python] A*算法基于栅格地图的全局路径规划

    # 所有节点的g值并没有初始化为无穷大 # 当两个子节点的f值一样时,程序选择最先搜索到的一个作为父节点加入closed # 对相同数值的不同对待,导致不同版本的A*算法找到等长的不同路径 # 最后c ...

  8. PRM路径规划算法

    路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法:如人工势场法.单元分解法.随机路标图(PRM)法.快速搜索树(RRT)法等.传统的人工势场.单元分解法需要对空间中的 ...

  9. 4003.基于Dijsktra算法的最短路径求解

    基于Dijsktra算法的最短路径求解 发布时间: 2018年11月26日 10:14   时间限制: 1000ms   内存限制: 128M 有趣的最短路...火候欠佳,目前还很难快速盲打出来,需继 ...

  10. 基于Dijsktra算法的最短路径求解

    基于Dijsktra算法的最短路径求解   描述 一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知.给定地图的一个起点城市和终点城市,利用Dijsktra算法求出起点到终点之间 ...

随机推荐

  1. 一文读懂强化学习:RL全面解析与Pytorch实战

    在本篇文章中,我们全面而深入地探讨了强化学习(Reinforcement Learning)的基础概念.主流算法和实战步骤.从马尔可夫决策过程(MDP)到高级算法如PPO,文章旨在为读者提供一套全面的 ...

  2. OpenGL 模型加载详解

    1. Assimp 目前为止,我们已经可以绘制一个物体,并添加不同的光照效果了.但是我们的顶点数据太过简单,只能绘制简单的立方体.但是房子汽车这种不规则的形状我们的顶点数据就很难定制了.索性,这部分并 ...

  3. JavaScript高级程序设计笔记08 对象、类与面向对象编程

    对象.类与面向对象编程 对象 一组属性的无序集合 属性 类型 数据属性 value.writable 访问器属性 getter.setter至少有一 定义 .操作符:默认可配置.可枚举.可写(数据属性 ...

  4. Android app兼容低版本Java环境

    原文地址: Android app兼容低版本Java环境 - Stars-One的杂货小窝 起因是修复一个Bug遇到的问题,找到了一个可以让app兼容低版本java的方法 众所周知,Android版本 ...

  5. 轻松应对复杂集成场景!用友U8API开发适配

    在企业上云的大趋势下,U8+ 全面转向互联网方向,深入融合云应用,一站式提供财务.营销.制造.采购.设计.协同.人力等领域的"端 + 云"服务,并通过软硬一体化.产业链协同的策略全 ...

  6. IDEA提示无法解析resourse中的方法getResourceAsStream

    一.解决方案 1.错误展示: InputStream inputStream = Resources.getResourceAsStream(resource); 2.报错展示: 报错原因:这是因为找 ...

  7. Go笔记(3)-3种go语言的键盘输入详解

    go语言的键盘输入详解 go语言中有三种输入函数,分别是: fmt.Scanf() 可以按照指定的格式进行输入 fmt.Scanln() 通过指针将值赋值给变量 fmt.Scan() (1)fmt.S ...

  8. [ARC156D] Xor Sum 5

    Problem Statement You are given a sequence of $N$ non-negative integers $A=(A_1,A_2,\dots,A_N)$ and ...

  9. Hnswlib 介绍与入门使用

    Hnswlib是一个强大的近邻搜索(ANN)库, 官方介绍 Header-only C++ HNSW implementation with python bindings, insertions a ...

  10. vue-test ------class绑定

    <template> <p :class="{'active':isActive}">Class样式绑定</p> <p :class=&q ...