使用以下匹配器规则:
{'label': 'R-1',
'pattern': [{'TEXT': 'MyLabel'}, {'TEXT': ':', 'OP': '?'}],
'greedy': 'LONGEST', }
文字:“MyLabel:一些价值”
我得到两个匹配:“MyLabel”和“MyLabel:”
对我来说,这非常令人惊讶 - 我原本以为“MyLabel:”上会出现一场比赛。 添加新的贪婪标志没有任何区别。
SpaCy 版本 3.7.5
我会说,您使用 SpaCy
Matcher
观察到的行为是预期的,并且它不是错误。当您使用 {'TEXT': ':', 'OP': '?'}
模式时,OP: '?'
运算符意味着冒号是可选的,因此匹配器将生成较短和较长的匹配,如您所见。
{'TEXT': 'MyLabel'}, {'TEXT': ':', 'OP': '?'}
。'MyLabel: Some Value'
。因此对于这个模式,SpaCy 将尝试匹配:
'MyLabel'
(因为冒号是可选的)。'MyLabel:'
(因为可以包含冒号)。因此,您将得到两个匹配项:
'MyLabel'
和 'MyLabel:'
。
这是预期行为还是错误?
OP: '?'
运算符允许选择性地匹配冒号,从而导致多个匹配。我该如何确定第二场比赛确实只是第一场比赛的子集?
pip show spacy
Name: spacy
Version: 3.7.5
Summary: Industrial-strength Natural Language Processing (NLP) in Python
Home-page: https://spacy.io
Author: Explosion
Author-email: [email protected]
License: MIT
Location: /home/adesoji/Downloads/visis-backend-assessment-Adesoji/visisenv/lib/python3.11/site-packages
Requires: catalogue, cymem, jinja2, langcodes, murmurhash, numpy, packaging, preshed, pydantic, requests, setuptools, spacy-legacy, spacy-loggers, srsly, thinc, tqdm, typer, wasabi, weasel
Required-by: en-core-web-sm
现在代码示例:
import spacy
from spacy.matcher import Matcher
nlp = spacy.load("en_core_web_sm")
doc = nlp("MyLabel: Some Value")
matcher = Matcher(nlp.vocab)
pattern = [{'TEXT': 'MyLabel'}, {'TEXT': ':', 'OP': '?'}]
matcher.add("R-1", [pattern])
matches = matcher(doc)
for match_id, start, end in matches:
span = doc[start:end]
print(f"Match: {span.text}, Start: {start}, End: {end}")
# Now, we Determine if one match is a subset of another
matches.sort(key=lambda x: (x[1], -x[2])) # Sort by start index, then by end index descending
filtered_matches = []
last_end = -1
for match_id, start, end in matches:
if start >= last_end: # This is for Avoiding adding subsets
filtered_matches.append((match_id, start, end))
last_end = end
for match_id, start, end in filtered_matches:
span = doc[start:end]
print(f"Filtered Match: {span.text}")
现在,此代码将过滤掉较短的匹配项,您的输出将是
Match: MyLabel, Start: 0, End: 1
Match: MyLabel:, Start: 0, End: 2
Filtered Match: MyLabel: , you can see MYLabel: with the colon symbol there
如果您想确保只返回最长的匹配项,您可以更改定义模式的方式:
pattern = [{'TEXT': 'MyLabel'}, {'TEXT': ':', 'OP': '?', 'greedy': 'LONGEST'}]
请注意,
greedy
标志不会改变匹配本身的行为,而是会影响在某些自定义设置中处理重叠的方式。
OP: '?'
运算符,您所看到的行为是设计使然的。