将在spaCy基于规则的模式匹配与匹配跨度的起始和结束字符一起返回匹配ID,但我没有看到任何东西,上面写着如何确定哪些跨度的部分由那名令牌的文档中匹配。
在正则表达式中,我可以在组周围放置括号来选择它们并让它们“选择”并脱离模式。spaCy 可以做到这一点吗?
例如,我有这样的文字(来自德古拉):
他们穿着高筒靴,裤子塞在里面,留着长长的黑发和浓密的黑胡须。
我定义了一个实验:
import spacy
from spacy.matcher import Matcher
def test_match(text, patterns):
nlp = spacy.load('en_core_web_sm')
matcher = Matcher(nlp.vocab)
matcher.add('Boots', None, patterns)
doc = nlp(text)
matches = matcher(doc)
for match in matches:
match_id, start, end = match
string_id = nlp.vocab.strings[match_id]
span = doc[start:end]
print(match, span.text)
text_a = "They wore high boots, with their trousers tucked into them, " \
"and had long black hair and heavy black moustaches."
patterns = [
{'POS': 'PRON'},
{'TAG': 'VBD'},
{'POS': 'ADJ'},
{'TAG': 'NNS'}
]
test_match(text_a, patterns)
Run Code Online (Sandbox Code Playgroud)
这输出:
(18231591219755621867, 0, 4) They wore high boots
Run Code Online (Sandbox Code Playgroud)
对于像这样的简单模式,连续四个标记,我可以假设标记 0 是代词,标记 1 是过去时动词等。但是对于带有数量修饰符的模式,它变得模棱两可。但是是否有可能让 spaCy 告诉我哪些令牌实际上与模式的组件匹配?
例如,将这个修改添加到上面的实验中,模式中有两个通配符,新版本的文本缺少形容词“high”:
(18231591219755621867, 0, 4) They wore high boots
Run Code Online (Sandbox Code Playgroud)
哪些输出:
(18231591219755621867, 0, 2) They wore
(18231591219755621867, 0, 3) They wore high
(18231591219755621867, 0, 4) They wore high boots
(18231591219755621867, 0, 2) They wore
(18231591219755621867, 0, 3) They wore boots
Run Code Online (Sandbox Code Playgroud)
在这两种输出情况下,不清楚最终标记中哪些是形容词,哪些是复数名词。我想我可以遍历跨度中的标记,然后手动匹配模式的搜索部分,但这绝对是重复的。既然我认为 spaCy 必须找到它们来匹配它们,它不能告诉我哪个是哪个?
小智 5
从 spaCy v3.06 开始,现在可以将匹配对齐信息作为匹配元组的一部分(api doc 链接)获取。
matches = matcher(doc, with_alignments=True)
Run Code Online (Sandbox Code Playgroud)
在您的示例中,它将生成以下输出:
(1618900948208871284, 0, 2, [0, 1]) They wore
(1618900948208871284, 0, 3, [0, 1, 2]) They wore high
(1618900948208871284, 0, 4, [0, 1, 2, 3]) They wore high boots
(1618900948208871284, 0, 2, [0, 1]) They wore
(1618900948208871284, 0, 3, [0, 1, 3]) They wore boots
Run Code Online (Sandbox Code Playgroud)