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


中文分词任务

语料库 => 训练集

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

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

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

算法思想

维特比(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. Python 正则表达式(RegEx)指南

    正则表达式(RegEx)是一系列字符,形成了一个搜索模式.RegEx 可用于检查字符串是否包含指定的搜索模式. RegEx 模块 Python 中有一个内置的包叫做 re,它可以用于处理正则表达式.导 ...

  2. STM32F407 MCO输出的配置问题

    当前使用IDE: RT-Thread Studio 版本: 2.1.0 构建ID: 202103221400 配置如下: int MCO1_GPIO_INIT(void) { GPIO_InitTyp ...

  3. KMeans算法全面解析与应用案例

    本文深入探讨了KMeans聚类算法的核心原理.实际应用.优缺点以及在文本聚类中的特殊用途,为您在聚类分析和自然语言处理方面提供有价值的见解和指导. 关注TechLead,分享AI全维度知识.作者拥有1 ...

  4. 大白话说Python+Flask入门(一)

    写在前面 技术这东西就得用,不用就会忘,之前写博客感觉就是给自己记笔记用,还有大部分,估计睡在语雀里都落灰了,哈哈! 在Python领域,我觉得我还是算个小白吧,会写讲不明白,所以我决定想做一件事,先 ...

  5. L3-009 长城

    #include <bits/stdc++.h> using namespace std; using pii = pair<int, int>; using ll = lon ...

  6. Vue03-组件化

    01. 组件化思想 当我们面对一个复杂问题的时候,常见的.高效的做法就是对复杂问题进行拆分, 将复杂问题拆分成一个个小的.简单的问题, 逐一解决小问题,再将处理好的小问题整合到一起, 如此解决复杂问题 ...

  7. termux+anlinux+Rvnc viewer来使安卓手机(平板)变成linux服务器

    第一步,先安装termux和anlinux,在此之前先安装一个vpn 下面是termux的官网(官网是没有内嵌任何广告的): termux/termux-app: Termux - a termina ...

  8. vertx的学习总结2

    一.什么是verticle verticle是vertx的基本单元,其作用就是封装用于处理事件的技术功能单元  (如果不能理解,到后面的实战就可以理解了) 二.写一个verticle 1. 引入依赖( ...

  9. [AGC038E] Gachapon

    Problem Statement Snuke found a random number generator. It generates an integer between $0$ and $N- ...

  10. 【Linux API 揭秘】container_of函数详解

    [Linux API 揭秘]container_of函数详解 Linux Version:6.6 Author:Donge Github:linux-api-insides 1.container_o ...