为什么 Spacy 不能识别标签中的所有命名实体?

Why Spacy doesn't recognise all named entities in the label?

我正在使用 Python 3.8 并使用 Spacy 2.3.5。我尝试使用 EntityRuler 为一组实体分配一个新标签 'TH-T-MARKER',然后将它们可视化。这是代码:

import spacy
from spacy import displacy
from spacy.pipeline import EntityRuler

nlp = spacy.load("en_core_web_sm")

# Strings of target markers
targettext = """'T-bet+', 'IFN-γ+', 'TNF-α+',
'GATA-3+', 'IL-4+',
'PU.1+', 'IL-9+', 'IL-4–', 'IL-17–', 'IFN-γ–',
'CCR4+', 'CCR6+', 'CCR10–', 'RORγt+', 'IL-17+',
'CCR10+', 'AHR+', 'IL-22+', 'IL-17–', 'IFN-γ–',
'CXCR5+', 'ICOS+', 'PD-1+', 'Bcl-6+', 'IL-21+',
'CD25+', 'IL-2 Rα+', 'CD127-', 'IL-7 Rα–', 'IL-7 Rα low', 'FoxP3+'"""

ruler = EntityRuler(nlp, overwrite_ents=True)

# List of target markers
tcell = [
'T-bet+', 'IFN-γ+', 'TNF-α+',
'GATA-3+', 'IL-4+',
'PU.1+', 'IL-9+', 'IL-4–', 'IL-17–', 'IFN-γ–',
'CCR4+', 'CCR6+', 'CCR10–', 'RORγt+', 'IL-17+',
'CCR10+', 'AHR+', 'IL-22+', 'IL-17–', 'IFN-γ–',
'CXCR5+', 'ICOS+', 'PD-1+', 'Bcl-6+', 'IL-21+',
'CD25+', 'IL-2 Rα+', 'CD127-', 'IL-7 Rα–', 'IL-7 Rα low', 'FoxP3+'
]

# create marker pattern
tcell_match = {
    'TEXT': {'IN': tcell}
}

# create entity pattern
tcell_pattern = {
    'label': 'TH-T-MARKER',
    'pattern': [tcell_match]
}

t_patterns = [tcell_pattern]


ruler.add_patterns(t_patterns)
# Add the Entity Ruler to the nlp pipeline
nlp.add_pipe(ruler)
LABELING_DATA = []
doc = nlp(targettext)

colors = {"TH-T-MARKER": "#5076BE"}
options = {"ents": ["TH-T-MARKER"], "colors": colors}
displacy.serve(doc, style='ent', options=options)

为了让问题更清楚,我只是将列表 'tcell' 中的所有实体复制并粘贴到 'targettext' 中。结果显示,在列表 'tcell' 中的所有实体中,只有实体 'RORγt+'、'AHR+'、'ICOS+' 和 'CD127-' 被正确分配了标签“TH -T-MARKER".

我想知道是否有办法让所有实体都被标记为“TH-T-MARKER”?另外我真的不明白为什么只有部分实体被正确标记,尤其是当目标文本只包含与模式 'tcell_pattern' 中的实体名称相同的字符串时。对这个问题的任何想法将不胜感激。谢谢!

您似乎在使用 spaCy v2?

这里的问题是,因为您使用了 {"TEXT":{"IN":{...}} 结构,所以您只匹配单个标记。因为您的目标中有标点符号,所以它可能被分成多个标记,因此不匹配。

EntityRuler 的优点之一是,如果您只是将模式交给您,就不必担心分词器的工作方式。以下是您可以如何做到这一点,在这种情况下,您的所有实体都匹配:

import spacy
from spacy import displacy
from spacy.pipeline import EntityRuler

nlp = spacy.load("en_core_web_sm")

# Strings of target markers
targettext = """'T-bet+', 'IFN-γ+', 'TNF-α+',
'GATA-3+', 'IL-4+',
'PU.1+', 'IL-9+', 'IL-4–', 'IL-17–', 'IFN-γ–',
'CCR4+', 'CCR6+', 'CCR10–', 'RORγt+', 'IL-17+',
'CCR10+', 'AHR+', 'IL-22+', 'IL-17–', 'IFN-γ–',
'CXCR5+', 'ICOS+', 'PD-1+', 'Bcl-6+', 'IL-21+',
'CD25+', 'IL-2 Rα+', 'CD127-', 'IL-7 Rα–', 'IL-7 Rα low', 'FoxP3+'"""

ruler = EntityRuler(nlp, overwrite_ents=True)

# List of target markers
tcell = [
'T-bet+', 'IFN-γ+', 'TNF-α+',
'GATA-3+', 'IL-4+',
'PU.1+', 'IL-9+', 'IL-4–', 'IL-17–', 'IFN-γ–',
'CCR4+', 'CCR6+', 'CCR10–', 'RORγt+', 'IL-17+',
'CCR10+', 'AHR+', 'IL-22+', 'IL-17–', 'IFN-γ–',
'CXCR5+', 'ICOS+', 'PD-1+', 'Bcl-6+', 'IL-21+',
'CD25+', 'IL-2 Rα+', 'CD127-', 'IL-7 Rα–', 'IL-7 Rα low', 'FoxP3+'
]

patterns = [{"label": "TH-T-MARKER", "pattern": tt} for tt in tcell]

ruler.add_patterns(patterns)
# Add the Entity Ruler to the nlp pipeline
nlp.add_pipe(ruler)
LABELING_DATA = []
doc = nlp(targettext)

colors = {"TH-T-MARKER": "#5076BE"}
options = {"ents": ["TH-T-MARKER"], "colors": colors}
displacy.serve(doc, style='ent', options=options)