基于 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。
我正在尝试从文本数据中提取短语。我目前正在使用 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。