HanLP — 路径规划算法 - 求解最短路径 - 维特比(Viterbi)算法
维特比算法:从众多路径中,挑出最优的那条,他和隐马尔可夫没有强关联
中文分词任务
语料库 => 训练集
初始、转移、发射矩阵 => 训练过程
维特比算法,得到真正结果
训练的时候,是用不到维特比算法的,只有分词时才会使用
算法思想
维特比(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)算法的更多相关文章
- ZOJ 1456 Minimum Transport Cost(Floyd算法求解最短路径并输出最小字典序路径)
题目链接: https://vjudge.net/problem/ZOJ-1456 These are N cities in Spring country. Between each pair of ...
- Dijkstra(迪杰斯特拉)算法求解最短路径
过程 首先需要记录每个点到原点的距离,这个距离会在每一轮遍历的过程中刷新.每一个节点到原点的最短路径是其上一个节点(前驱节点)到原点的最短路径加上前驱节点到该节点的距离.以这个原则,经过N轮计算就能得 ...
- python利用kruskal求解最短路径的问题
python利用kruskal算法求解最短路径的问题,修改参数后可以直接使用 def kruskal(): """ kruskal 算法 ""&quo ...
- HMM Viterbi算法 详解
HMM:隐式马尔可夫链 HMM的典型介绍就是这个模型是一个五元组: 观测序列(observations):实际观测到的现象序列 隐含状态(states):所有的可能的隐含状态 初始概率(start ...
- Bellman-Ford & SPFA 算法——求解单源点最短路径问题
Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...
- 全局路径规划算法Dijkstra(迪杰斯特拉算法)- matlab
参考博客链接:https://www.cnblogs.com/kex1n/p/4178782.html Dijkstra是常用的全局路径规划算法,其本质上是一个最短路径寻优算法.算法的详细介绍参考上述 ...
- [python] A*算法基于栅格地图的全局路径规划
# 所有节点的g值并没有初始化为无穷大 # 当两个子节点的f值一样时,程序选择最先搜索到的一个作为父节点加入closed # 对相同数值的不同对待,导致不同版本的A*算法找到等长的不同路径 # 最后c ...
- PRM路径规划算法
路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法:如人工势场法.单元分解法.随机路标图(PRM)法.快速搜索树(RRT)法等.传统的人工势场.单元分解法需要对空间中的 ...
- 4003.基于Dijsktra算法的最短路径求解
基于Dijsktra算法的最短路径求解 发布时间: 2018年11月26日 10:14 时间限制: 1000ms 内存限制: 128M 有趣的最短路...火候欠佳,目前还很难快速盲打出来,需继 ...
- 基于Dijsktra算法的最短路径求解
基于Dijsktra算法的最短路径求解 描述 一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知.给定地图的一个起点城市和终点城市,利用Dijsktra算法求出起点到终点之间 ...
随机推荐
- 在VM虚拟机中安装FTP服务
自用的话,建议先关掉防火墙 systemctl stop firewalld #关闭防火墙 systemctl disable firewalld.service #设置开机禁用防火墙 systemc ...
- [Python急救站课程]九九乘法表打印
打印九九乘法表 for i in range(1, 10): for j in range(1, i + 1): print("{}*{}={:2} ".format(j, i, ...
- 一个java文件的JVM之旅
准备 我是小C同学编写得一个java文件,如何实现我的功能呢?需要去JVM(Java Virtual Machine)这个地方旅行. 变身 我高高兴兴的来到JVM,想要开始JVM之旅,它确说:&quo ...
- jap复制一条数据插入数据库,报:identifier of an instance of com.kxkd.shop.entity.goods.GoodsSpu was alt
因为修改了jpa实体id 可以先使用springframework的BeanUtils复制一个相同的对象 BeanUtils.copyProperties(source, target); //复制属 ...
- Soc的Bring Up流程
1.Bring Up流程 SOC (System on a Chip) bring-up是一个复杂的过程,涉及到硬件.固件和软件的集成和验证,以下是一个基于BROM,SPL,UBOOT和Linux的启 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-32-JavaScript的调用执行-下篇
1.简介 在实际工作中,我们需要对处理的元素进行高亮显示,或者有时候为了看清楚操作过程和步骤我们需要跟踪鼠标点击了哪些元素需要标记出来.虽然很少遇到,但是为了以后大家可以参考或者提供一种思路,今天宏哥 ...
- 小心C#中的只读结构体成员
示例 我们先来看一段结构体的代码 (基于 VS2022 + .NET 8.0) public struct MyStruct(int number) { public int Number = num ...
- EXCEL中逆向查找的十种方法
逆向查找在Excel中指的是根据某个数值或条件,查找该数值或条件所在的单元格位置.逆向查找可以帮助用户快速定位数据,对于数据分析和处理非常有用.下面将详细介绍在Excel中进行逆向查找的十种方法. 一 ...
- python原生数据类型(上)
# 查看数据 print('hello world') # 查看数据类型 type('hello world') hello world str 1 数据类型定义 1.1 不可变数据类型 # 数值 # ...
- [ABC246C] Coupon
Problem Statement There are $N$ items in a shop. For each $i = 1, 2, \ldots, N$, the price of the $i ...