实体识别中,或序列标注任务中的维特比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使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

Pytorch微调BERT实现命名实体识别

《Pytorch微调BERT实现命名实体识别》命名实体识别(NER)是自然语言处理(NLP)中的一项关键任务,它涉及识别和分类文本中的关键实体,BERT是一种强大的语言表示模型,在各种NLP任务中显著... 目录环境准备加载预训练BERT模型准备数据集标记与对齐微调 BERT最后总结环境准备在继续之前,确

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定