我们今天来看看知识图谱构建中实体识别环节上常遇到的ensemble投票问题。
最近在做命名实体识别(NER)相关的任务,在做一个集成的模型,涉及到多个模型结果融合的问题,需要用某种方法把多个模型预测出来的结果进行投票,得出最终的结果。
由于任务是flat的NER,所以在投票的过程中需要避免实体重叠的问题。
为了实现这个功能需要构造一个投票器类,本文主要讲讲这方面怎么实现,给出一个具体的思路,供大家参考。一、针对实体识别任务的投票器:数据格式假设所有k个模型预测出来的结果保存为list格式的result,result的长度即为k,每一个元素对应一个dict,记录模型的预测结果,dict的键为类别名称,值为所有检测为该类的实体。
二、针对实体识别任务的投票器:实现思路首先回顾一下一般的分类任务中,bagging的策略是如何进行的,最简单的规则就是少数服从多数的规则,例如10个模型中,如果有8个将它分为A类,两个分为B类,那么最终结果就判定为A类,但是在NER任务中,由于涉及到实体的区间(span),便没有办法只采用简单的投票法将实体标出,因为可能某一个位置附近确定出现有一个实体,但是还需要判断①这个位置的实体的起始位置,②这个位置的实体所属的类别。
例如,某句话中,模型1将“粉色海星派大星”识别为人物类,模型2将“海星派大星”识别为人物类,模型3将“粉色海星”识别为人物类,那最终投票的结果又该如何判定呢?
1、生成初始化
读取所有模型的结果results,遍历其中识别到的每一个实体(不论类型),将所有的开始和结束位置记录下来,生成一个初始化的计数‘字典’,计数‘字典’的键为这个位置,值为这个位置作为开始或者结束位置出现的次数。由于在python中dict对象在迭代中是不可变的,所以用一个list来模拟这个‘字典’,list的index模拟‘字典’的键,然后建立一个从index到位置的映射就可以了。
2、统计出现次数
再次读取results,对初始化计数‘字典’中出现的所有位置,记录这个位置在所有模型中作为所有类型的起始和结束位置出现过的次数(后来这个次数改成了加权,权重为每个模型的f1的值),填到‘字典’的值上,至此‘字典’的每个位置上对应的都是一个p*2的array,p是实体类别的数量。
3、寻找第一显著位
在上面生成的计数‘字典’中,寻找第一显著位置,如果大于‘显著阈值’就去匹配与它相对应的开始或结束位置。如果第一显著位置是start位,则向右去寻找这个实体的end位;如果是end位,则向左去寻找这个实体的start位。找到第一显著位置之后,将计数‘字典’的这个位置的数值置为0.
4、匹配第一显著位
以向右寻找end位为例,说明匹配规则。这个匹配位置应当满足:
(1)生成的span不能与已有的span重叠;
(2)匹配位置应当是所有该类型(与3中找到的第一显著位同类)中,最显著的位置;
(3)匹配位置的计数值满足‘显著阈值’。匹配成功后,将匹配位置在计数‘字典’中的计数值置为0,并将新生成的实体span添加到已有span中去。
5、循环
继续执行3和4两步,在剩下的位置中寻找第一显著位并匹配出实体,直到第一显著位的显著程度小于设定的显著阈值,则跳出循环。总结本文主要介绍了针对实体识别任务的多投票实现思路,其中有些思路可以借鉴,具体的代码,可以查看参考文献。参考文献1、https://blog.csdn.net/weixin_44826203/article/details/108347693