You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在同一spaCy nlp对象中使用多个NER管道?

解决spaCy自定义NER与标准NER管道共存的问题

直接在标准模型中添加自定义NER管道会导致实体叠加甚至识别异常,原因是两个NER组件会独立将识别结果添加到doc.ents,无自动去重或冲突处理;若使用Transformer类标准模型,共享的Transformer输出还可能引发识别逻辑混乱,导致大量错误实体被标注。

以下是几种可行的解决方案:

方案1:自定义组件合并两个NER的识别结果

创建自定义管道,分别调用两个模型获取对应实体,合并时过滤重叠实体,避免冲突:

import spacy
from spacy.tokens import Doc

def merge_ner(doc, custom_nlp, main_nlp):
    # 用自定义模型提取DRUG类型实体
    custom_doc = custom_nlp(doc.text)
    custom_ents = [ent for ent in custom_doc.ents if ent.label_ == "DRUG"]
    
    # 用标准模型提取非重叠的其他类型实体
    main_doc = main_nlp(doc.text)
    main_ents = []
    for ent in main_doc.ents:
        overlap = False
        for cust_ent in custom_ents:
            if ent.start <= cust_ent.end and cust_ent.start <= ent.end:
                overlap = True
                break
        if not overlap:
            main_ents.append(ent)
    
    # 合并并排序实体,生成新的Doc对象
    combined_ents = sorted(custom_ents + main_ents, key=lambda x: x.start)
    new_doc = Doc(main_nlp.vocab, words=[t.text for t in doc], spaces=[t.whitespace_ for t in doc])
    new_doc.ents = combined_ents
    return new_doc

# 加载模型
custom_nlp = spacy.load('my_trained_model/model-best/')
main_nlp = spacy.load('en_core_web_trf')

# 测试
text = 'Chantix is a drug developed by Pfizer for people who want to quit smoking.'
doc = merge_ner(main_nlp.make_doc(text), custom_nlp, main_nlp)
print(doc.ents)
# 预期输出:(Chantix, DRUG), (Pfizer, ORG), (people, PERSON)

方案2:添加过滤组件移除冲突实体

如果仅需要替换标准模型中与自定义实体冲突的类型(比如将PRODUCT替换为DRUG),可在管道末尾添加过滤组件,移除冲突实体类型:

import spacy

def filter_conflicting_ents(doc):
    # 移除PRODUCT类型实体,保留DRUG及其他标准实体
    filtered_ents = [ent for ent in doc.ents if ent.label_ != "PRODUCT"]
    doc.ents = filtered_ents
    return doc

custom_nlp = spacy.load('my_trained_model/model-best/')
main_nlp = spacy.load('en_core_web_trf')

# 将自定义NER添加到标准NER之前
main_nlp.add_pipe('ner', source=custom_nlp, name='custom_ner', before='ner')
# 添加过滤组件到管道最后
main_nlp.add_pipe(filter_conflicting_ents, last=True)

# 测试
doc = main_nlp('Chantix is a drug')
print(doc.ents)
# 预期输出:(Chantix, DRUG)

方案3:合并模型权重并微调(进阶)

若需要更稳定的效果,可将自定义NER的标签添加到标准模型的NER组件中,基于标准模型继续微调,让单个NER组件同时识别所有需要的实体类型。这种方式需要重新训练,但能避免多管道冲突问题。

内容的提问来源于stack exchange,提问作者Tiago Teodoro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:07:50