eng*_*019 10 nlp named-entity-recognition spacy ner
无论如何,SpaCy 是否可以用其标签替换 SpaCy NER 检测到的实体?例如: 我在玩我的 Apple Macbook 时正在吃一个苹果。
我已经用 SpaCy 训练了 NER 模型来检测“水果”实体,并且该模型成功地将第一个“苹果”检测为“水果”,而不是第二个“苹果”。
我想通过用标签替换每个实体来对我的数据进行后处理,所以我想用“水果”替换第一个“苹果”。句子将是“我在玩我的 Apple Macbook 时正在吃水果。 ”
如果我只是使用正则表达式,它也会用“FRUITS”替换第二个“Apple”,这是不正确的。有什么聪明的方法可以做到这一点吗?
谢谢!
DBa*_*ker 16
实体标签是令牌的一个属性(见这里)
import spacy
from spacy import displacy
nlp = spacy.load('en_core_web_lg')
s = "His friend Nicolas is here."
doc = nlp(s)
print([t.text if not t.ent_type_ else t.ent_type_ for t in doc])
# ['His', 'friend', 'PERSON', 'is', 'here', '.']
print(" ".join([t.text if not t.ent_type_ else t.ent_type_ for t in doc]) )
# His friend PERSON is here .
Run Code Online (Sandbox Code Playgroud)
编辑:
为了处理实体可以跨越多个单词的情况,可以使用以下代码:
s = "His friend Nicolas J. Smith is here with Bart Simpon and Fred."
doc = nlp(s)
newString = s
for e in reversed(doc.ents): #reversed to not modify the offsets of other entities when substituting
start = e.start_char
end = start + len(e.text)
newString = newString[:start] + e.label_ + newString[end:]
print(newString)
#His friend PERSON is here with PERSON and PERSON.
Run Code Online (Sandbox Code Playgroud)
更新:
Jinhua Wang 提醒我注意,现在有一种更内置、更简单的方法可以使用 merge_entities 管道来执行此操作。看下面金华的回答。
当实体可以跨越多个单词时,对上面的 @DBaker 解决方案进行更优雅的修改:
import spacy
from spacy import displacy
nlp = spacy.load('en_core_web_lg')
nlp.add_pipe("merge_entities")
s = "His friend Nicolas J. Smith is here with Bart Simpon and Fred."
doc = nlp(s)
print([t.text if not t.ent_type_ else t.ent_type_ for t in doc])
# ['His', 'friend', 'PERSON', 'is', 'here', 'with', 'PERSON', 'and', 'PERSON', '.']
print(" ".join([t.text if not t.ent_type_ else t.ent_type_ for t in doc]) )
# His friend PERSON is here with PERSON and PERSON .
Run Code Online (Sandbox Code Playgroud)
您可以在此处查看 Spacy 的文档。它使用内置的 Pipeline 来完成工作,并对多处理有良好的支持。我相信这是官方支持的用标签替换实体的方式。