如何使用spaCy从文章中定位与指定客体对应的特定归属主体
多人物场景下客体归属主体识别实现方案
核心思路
结合spaCy自带的命名实体识别(NER)、依存句法分析能力,再加少量兜底规则即可实现需求,不需要额外引入其他工具。
具体实现步骤
1. 自定义实体识别训练/配置
首先基于spaCy的NER模块扩展自定义实体类型:
- 保留默认的
PERSON实体,用于识别文本中的所有人名 - 新增业务需要的客体实体类型,比如
PHONE_NUMBER(手机号)、CNIC(证件号)、ADDRESS(地址)
可以通过标注少量业务样本微调spaCy的NER模型,也可以先用Matcher模块写正则规则匹配固定格式的客体(比如11位手机号、固定分段格式的CNIC),先把文本中所有的人名和目标客体实体都提取并标记好位置。
2. 依存句法匹配归属关系
这是核心匹配逻辑,利用spaCy的依存句法分析拿到词与词的修饰关联:
- 先定位到待查询的客体实体的核心词
- 沿着依存树向上查找该核心词的支配动词,再找该动词对应的主语(
nsubj依存关系),该主语就是客体的归属主体 - 如果存在并列主语(比如多个姓名用and连接),可以通过
conj依存关系把所有并列的人名都提取出来
3. 兜底规则覆盖异常场景
如果文本存在句法不规范的情况,依存分析无法抓到直接关联,就加两个通用兜底规则:
- 同句优先:仅优先匹配和客体实体在同一个句子内的人名
- 就近原则:优先取客体实体之前距离最近的人名实体
示例代码
import spacy # 加载spaCy预训练模型,可替换为你微调后支持自定义实体识别的模型 nlp = spacy.load("en_core_web_md") def get_attribution_subject(text, target_obj_type, target_obj_value=None): doc = nlp(text) # 定位目标客体实体 target_obj = None for ent in doc.ents: if ent.label_ == target_obj_type: if target_obj_value and ent.text != target_obj_value: continue target_obj = ent break if not target_obj: return [] # 沿着依存树查找关联主语 current_token = target_obj.root while current_token.dep_ != "ROOT": # 查找当前词的主语子节点 for child in current_token.children: if child.dep_ == "nsubj" and child.ent_type_ == "PERSON": # 收集所有并列主语 subjects = [child.text] for conj_child in child.conjuncts: if conj_child.ent_type_ == "PERSON": subjects.append(conj_child.text) return subjects current_token = current_token.head # 兜底取最近的人名 in_sent_persons = [ent for ent in doc.ents if ent.label_ == "PERSON" and ent.sent == target_obj.sent and ent.end < target_obj.start] if in_sent_persons: return [in_sent_persons[-1].text] return [] # 测试示例,你提前完成自定义实体识别配置后即可直接调用 # 示例1返回["Imran Raza"],示例2返回["Imran Raza"],示例3返回["Imran Raza", "Ghulam Jafari"]
内容的提问来源于stack exchange,提问作者azhar
相关产品推荐
相关产品推荐

