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算法求出起点到终点之间 ...
随机推荐
- Redis宕机恢复
AOF(Append Only File) Redis持久化:AOF日志 用 AOF 方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,Redis 就会恢复得很缓慢,影响到正常 ...
- 开源模型 Zephyr-7B 发布——跨越三大洲的合作
最近我们刚刚发布了新的开源模型 Zephry-7B,这个模型的诞生离不开全球三大洲开源社区的协作 ️. 我们的 CSO Thomas 录了一个视频介绍了它的起源故事: 就在几个月前,巴黎的一个新团队发 ...
- HarmonyOS 实战项目
引言 本章将介绍如何在 HarmonyOS 上进行实际项目开发.我们将从项目需求分析开始,逐步完成项目的设计.开发.测试和上线过程. 目录 项目需求分析 项目设计 项目开发 项目测试 项目上线 总结 ...
- (Good topic)四因数 (leetcode 181周赛T2)
四因数难度中等1收藏分享切换为英文关注反馈给你一个整数数组 nums,请你返回该数组中恰有四个因数的这些整数的各因数之和. 如果数组中不存在满足题意的整数,则返回 0 . 示例: 输入:nums ...
- python中四种方法提升数据处理的速度
在数据科学计算.机器学习.以及深度学习领域,Python 是最受欢迎的语言.Python 在数据科学领域,有非常丰富的包可以选择,numpy.scipy.pandas.scikit-learn.mat ...
- Linux驱动开发笔记(五):驱动连接用户层与内核层的文件操作集原理和Demo
前言 驱动写好后,用户层使用系统函数调用操作相关驱动从而实现与系统内核的关联,本篇主要就是理解清楚驱动如何让用户编程来实现与内核的交互. 杂项设备文件操作集 cd /usr/src/linux ...
- 上传代码到github和删除.git
在本地建立目录,将想上传的代码放到该文件夹中 git init ###初始化 git add . ###将本地项目工作区的所有文件添加到暂存区 git commit -m "excu&quo ...
- 利用Jdk动态代理模拟MyBatis的Mapper功能
本文将先介绍jdk动态代理的基本用法,并对其原理和注意事项予以说明.之后将以两个最常见的应用场景为例,进行代码实操.这两个应用场景分别是拦截器和声明性接口,它们在许多开发框架中广泛使用.比如在spri ...
- 2023-12-13:用go语言,密码是一串长度为n的小写字母,一则关于密码的线索纸条, 首先将字母a到z编号为0到25编号, 纸条上共有n个整数ai,其中a1表示密码里第一个字母的编号, 若i>1的
2023-12-13:用go语言,密码是一串长度为n的小写字母,一则关于密码的线索纸条, 首先将字母a到z编号为0到25编号, 纸条上共有n个整数ai,其中a1表示密码里第一个字母的编号, 若i> ...
- 零基础 从 yolo8 入门计算机视觉超简单:物体识别、图像分类、轨迹追踪、姿势识别
目录 安装 Ultralytics 训练 模型验证 预测 & 识别 导出 追踪 图像分割提取 分类 姿势识别 轨迹生成 Ultralytics YOLOv8 是备受好评的实时目标检测和图像分割 ...