使用flair做NER任务时输出字符串额外插入空格如何修复
问题根源
空格问题由flair默认分词逻辑导致:Sentence类会自动对输入文本做subword分词,会把邮箱地址里的@、域名前后拆成独立token,直接将Sentence对象转字符串输出时,会在拆分的token之间自动插入空格。
修复方案
不要直接把Sentence对象转成字符串做替换,而是基于原输入字符串 + NER实体的起止位置做替换,完全跳过flair分词后的格式影响,修改后的代码如下:
from flair.data import Sentence from flair.models import SequenceTagger tagger = SequenceTagger.load("flair/ner-english-ontonotes-large") line = 'Herman Melvilles email is mobydick123@gmail.com ;-)' sentence = Sentence(line) tagger.predict(sentence) # 按实体起始位置倒序替换,避免替换后位置偏移 entities = sorted(sentence.get_spans('ner'), key=lambda x: x.start_position, reverse=True) result = line for entry in entities: if entry.tag == 'PERSON': # 直接用实体在原字符串的起止位置替换 result = result[:entry.start_position] + "[PERSON_NAME]" + result[entry.end_position:] print(result)
该方案的优势:
- 倒序替换可避免先替换前面的实体后,后续实体的位置出现偏移导致替换错位
- 直接基于原文本的位置做替换,完全不受flair内部分词加空格的逻辑影响,输出格式和原输入完全一致,只会替换识别到的人名部分
- 删掉了原有冗余的正则匹配逻辑,直接用flair提供的
start_position、end_position、tag属性获取实体信息,稳定性更高
内容的提问来源于stack exchange,提问作者albusdemens
相关产品推荐
相关产品推荐

