Spacy逐token标注IOB文件效果差的原因及优化方案咨询
问题根因确认
你猜测的原因完全正确,效果远低于官方评估结果的核心问题就是逐token输入模型处理,完全丢失了上下文语义信息。spaCy的NER模型依赖整句的上下文特征做实体类型和IOB标记判断,单个token输入时没有上下文支撑,无法得到正确的识别结果。
优化方案(保留原有分词规则)
spaCy支持直接用自定义分词结果构造Doc对象,不会触发默认分词逻辑,既可以完整保留你原有的分词规则和黄金标注对齐,又能整句输入模型利用上下文信息,识别效果和官方评估脚本结果完全一致。
优化后代码
import csv import spacy from spacy.tokens import Doc # 加载训练好的模型 nlp = spacy.load("/content/drive/MyDrive/Spacy/model/model-best") with open('/content/drive/MyDrive/Spacy/Test/annotated_tuebadz_spacy.tsv', 'w+', encoding='utf-8') as tsvfile: wrt = csv.writer(tsvfile, delimiter='\t') for sent in sent_list: # 用自定义分词列表直接构造Doc,完全对齐原有分词规则 doc = Doc(nlp.vocab, words=sent) # 整句送入NER pipeline处理,利用全句上下文特征 doc = nlp.get_pipe("ner")(doc) # 遍历输出每个token的标注结果 for token in doc: if token.ent_iob_ == "O": label = token.ent_iob_ + token.ent_type_ else: label = f"{token.ent_iob_}-{token.ent_type_}" print(token.text, label) wrt.writerow((token.text, label))
其他说明
- 如果你的模型pipeline包含除NER外的其他组件(如词性标注、句法分析),可以将
doc = nlp.get_pipe("ner")(doc)替换为doc = nlp(doc),效果一致 - 输出结果的token顺序、内容和你原始的sent_list完全一致,不会出现分词拆分、合并的情况,可直接和黄金标注做对齐评估
内容的提问来源于stack exchange,提问作者CanDo7777
相关产品推荐
相关产品推荐

