spaCy设置doc.ents时出现重叠实体冲突报错如何解决
报错原因
给spaCy的doc.ents属性赋值实体标注时,存在跨度重叠的实体会直接触发报错,本次冲突的两个实体为:
- 跨度位置
(4708, 4717),实体标签Companies worked at - 跨度位置
(4681, 4717),实体标签Degreedoc.ents的底层设计不支持实体重叠,要求单个token只能归属一个实体,只要两个实体的覆盖范围存在交集,赋值时就会抛出冲突提示。
解决方法
根据业务是否需要保留重叠实体,二选一处理即可:
不需要保留重叠实体
先对待写入的实体列表做冲突过滤,确保所有实体的覆盖范围没有交集后再赋值给doc.ents。通常可以提前给实体设置优先级,出现重叠时保留高优先级实体,丢弃低优先级的冲突实体。
参考实现代码:
from spacy.tokens import Span # 按优先级从高到低排列待写入的实体,优先级可根据业务规则自定义 raw_ents = [ Span(doc, 4681, 4717, label="Degree"), Span(doc, 4708, 4717, label="Companies worked at") ] used_pos = set() valid_ents = [] for ent in raw_ents: ent_range = range(ent.start, ent.end) # 只要当前实体覆盖的位置没有被之前的高优先级实体占用,就保留 if not any(pos in used_pos for pos in ent_range): valid_ents.append(ent) used_pos.update(ent_range) doc.ents = valid_ents
需要保留重叠实体
如果业务场景要求同时保留重叠的多个实体,不要使用doc.ents存储标注,改用doc.spans接口即可,该接口原生支持跨度重叠,不会触发冲突校验。
参考实现代码:
from spacy.tokens import Span # spans支持自定义分组key,可按标注场景设置不同的分组名 doc.spans["overlap_entities"] = [ Span(doc, 4681, 4717, label="Degree"), Span(doc, 4708, 4717, label="Companies worked at") ]
提示:存入
doc.spans的标注不会自动同步到doc.ents,后续读取标注时需要从对应分组key下获取数据。
内容的提问来源于stack exchange,提问作者Pawan
相关产品推荐
相关产品推荐

