实体识别中,或序列标注任务中的维特比Viterbi解码

2024-05-26 15:18

本文主要是介绍实体识别中,或序列标注任务中的维特比Viterbi解码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

看懂这个算法,首先要了解序列标注任务     QQ522414928 可以在线交流

 

大体做一个解释,首先需要4个矩阵,当然这些矩阵是取完np.log后的结果,

分别是:初始strat→第一个字符状态的概率矩阵,转移概率矩阵,发射概率矩阵,最后一个字符状态→end结束的概率矩阵,

这些概率矩阵可以是通过统计得到,或者是LSTM+crf这种训练迭代得到。 

zero_log 指的是在统计中发射概率没有的情况下用这个很小的值来代替,lstm+crf中应该不会出现不存在的发射概率。

 

然后看代码

一个矩阵V:里面保存的是每个时间步上的每个状态对应的概率

一个字典path:里面保存的是  {当前标签:他之前所经过的路径}     

 

然后最佳路径的计算经过三个部分:初试概率矩阵到第一个字符状态那部分,序列中字符状态转移和发射那部分,最后一个字符状态到end那部分

里边的发射分数和转移分数都使用加法计算是因为   发射矩阵和转移矩阵都经过了log取对数运算

 

def start_calcute(self,sentence):'''通过viterbi算法计算结果:param sentence: "小明硕士毕业于中国科学院计算所":return: "S...E"'''zero = -3.14e+100zero_log = np.log(-3.14e+100)init_state = self.prob_dict["PiVector_prob"]trans_prob = self.prob_dict["TransProbMatrix_prob"]emit_prob = self.prob_dict["EmitProbMartix_prob"]end_prob = self.prob_dict["EndProbMatrix_prob"]V = [{}] #其中的字典保存 每个时间步上的每个状态对应的概率path = {}#初始概率for y in self.state_list:V[0][y] = init_state[y] + emit_prob[y].get(sentence[0],zero_log)path[y] = [y]#从第二次到最后一个时间步for t in range(1,len(sentence)):V.append({})newpath = {}for y in self.state_list: #遍历所有的当前状态temp_state_prob_list = []for y0 in self.state_list: #遍历所有的前一次状态cur_prob = V[t-1][y0]+trans_prob[y0][y]+emit_prob[y].get(sentence[t],zero_log)temp_state_prob_list.append([cur_prob,y0])#取最大值,作为当前时间步的概率prob,state =  sorted(temp_state_prob_list,key=lambda x:x[0],reverse=True)[0]#保存当前时间步,当前状态的概率V[t][y] = prob#保存当前的状态到newpath中newpath[y] = path[state] + [y]#让path为新建的newpathpath = newpath#输出的最后一个结果只会是S(表示单个字)或者E(表示结束符)(prob, state) = max([(V[len(sentence)][y]+end_prob[y], y) for y in ["S","E"]])return (prob, path[state])

  

这篇关于实体识别中,或序列标注任务中的维特比Viterbi解码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1004829

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Java 中编码与解码的具体实现方法

《Java中编码与解码的具体实现方法》在Java中,字符编码与解码是处理数据的重要组成部分,正确的编码和解码可以确保字符数据在存储、传输、读取时不会出现乱码,本文将详细介绍Java中字符编码与解码的... 目录Java 中编码与解码的实现详解1. 什么是字符编码与解码?1.1 字符编码(Encoding)1

Python Flask实现定时任务的不同方法详解

《PythonFlask实现定时任务的不同方法详解》在Flask中实现定时任务,最常用的方法是使用APScheduler库,本文将提供一个完整的解决方案,有需要的小伙伴可以跟随小编一起学习一下... 目录完js整实现方案代码解释1. 依赖安装2. 核心组件3. 任务类型4. 任务管理5. 持久化存储生产环境

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景