基于 Spacy 规则的匹配问题

Spacy Rule Based Matching Issue

我正在尝试从文本数据中提取短语。我目前正在使用 SpaCy 基于规则的匹配。在我看到“Hiv-1 dna quant”之前一切正常,这个短语没有被检测到。我使用的模式显示在下面的代码中。

matcher = Matcher(nlp.vocab)
pattern = [{'LOWER': 'hiv'}, {"IS_PUNCT": True}, {"TEXT": {"REGEX":"\d{1,2}"}},
         {'LOWER': 'dna'},
         {'LOWER': 'quant'}]
matcher.add("HelloWorld", [pattern])
data = "probe Hiv-1 dna amp probe Hiv-1 dna quant Hiv-2 dna dir probe Hiv-2 dna"
doc = nlp(data)
matches = matcher(doc)
for match_id, start, end in matches:
    string_id = nlp.vocab.strings[match_id]  # Get string representation
    span = doc[start:end]  # The matched span
    print(span.text)

我也试过下面的模式

pattern = [{"LOWER": "hiv"}, {"IS_PUNCT": True}, {"LOWER":"1"}, {"LOWER": "dna"}, {"LOWER":"quant"}]

但它没有检测到它。

还有其他方法吗?

当您遇到此类问题时,请首先确保您了解 Spacy 如何标记您的字符串。看:

>>> [t for t in doc]
[probe, Hiv-1, dna, amp, probe, Hiv-1, dna, quant, Hiv-2, dna, dir, probe, Hiv-2, dna]

因此,您的 Hiv-1 是单个标记。现在,您需要添加另一个模式来说明 {'LOWER': 'hiv'}, {"IS_PUNCT": True}, {"TEXT": {"REGEX":"\d{1,2}"}} 可以是单个标记这一事实。例如,它看起来像 {'LOWER': {"REGEX":"^hiv[\W_]\d{1,2}$"}},其中小写的标记文本必须匹配 ^hiv[\W_]\d{1,2}$ 正则表达式。

您可以使用

patterns = [
    [{'LOWER': 'hiv'}, {"IS_PUNCT": True}, {"TEXT": {"REGEX":"\d{1,2}"}}, {'LOWER': 'dna'}, {'LOWER': 'quant'}],
    [{'LOWER': {"REGEX":"^hiv[\W_]\d{1,2}$"}}, {'LOWER': 'dna'}, {'LOWER': 'quant'}]
]
matcher = Matcher(nlp.vocab)
matcher.add("HelloWorld", patterns)
doc = nlp(data)
print([doc[start:end].text for _, start,end in matcher(doc)])
# => ['Hiv-1 dna quant']

^hiv[\W_]\d{1,2}$ 正则表达式表示

  • ^ - 字符串的开头(此处为令牌)
  • hiv - hiv 文字
  • [\W_] - 任何非字母数字字符
  • \d{1,2} - 一位或两位数
  • $ - 字符串结尾(此处为标记)。

参见regex demo