数字名词/数字名词的spacy匹配器

spacy matcher for number-noun / number number noun

您好,我尝试使用 spacy 来匹配单词 对于

这样的文本

1 杯 1 1/2 杯 1 1/2 英寸

为此,我创建了如下匹配器模式。

pattern1 = [{'POS':'NUM'},
           {'POS':'NUM','OP':'?'},{'POS':'NOUN'},];
# number number noun pattern

pattern2=[{'POS':'NUM'},{'POS':'NUM','OP':'?'},{"ORTH": "-",'OP':'?'},
           {'POS': 'NOUN'}];
# number after number but optional to cover both '2 inch' and '2 1/2 inch' 
# it should also cover '2 1/2-inch' so put 'ORTH':'-' but optional

然而,当我 运行 匹配器时, 它只有 returns 一种模式,即数字后跟名词,如下所示。

matcher.add('Measurepattern',None,pattern1)
matcher.add('Measurepattern',None,pattern2)

matches=matcher(test_token)

matches

for token,start,end in matches:
    print(test_token[start:end])

//2 teaspoons
//1 teaspoon
//1 cup

为什么会这样,我该如何解决?

谢谢

在 Spacy 2.3.2 中,1 1/2-inch 被标记为 ('1', 'NUM'), ('1/2-inch', 'NUM'),因此如果您不引入新的特定模式,将无法匹配您当前的模式。

这是一个例子:pattern3=[{'POS':'NUM'},{"TEXT": {"REGEX":"^\d+(?:/\d+)?-\w+$"}}];。正则表达式匹配一个标记,其文本以一个或多个数字开头,然后有一个可选序列 / 和一个或多个数字,然后有一个 -,然后是任何一个或多个单词字符(字母,数字或 _)。您可以将 \w 替换为 [^\W\d_] 以仅匹配字母。

import spacy
from spacy.matcher import Matcher

nlp = spacy.load("en_core_web_sm")
matcher = Matcher(nlp.vocab)

pattern1 = [{'POS':'NUM'}, {'POS':'NUM', 'OP':'?'}, {'POS':'NOUN'}];
pattern2=[{'POS':'NUM'},{'POS':'NUM','OP':'?'},{"ORTH": "-",'OP':'?'},{'POS': 'NOUN'}];
pattern3=[{'POS':'NUM'},{"TEXT": {"REGEX":"^\d+(?:/\d+)?-\w+$"}}];

matcher.add("HelloWorld", [pattern1, pattern2, pattern3])

doc = nlp("1 cups, 1 1/2 cups, 1 1/2-inch")
print([(t.text, t.pos_) for t in doc])
#[('1', 'NUM'), ('cups', 'NOUN'), (',', 'PUNCT'), ('1', 'NUM'), ('1/2', 'NUM'), ('cups', 'NOUN'), (',', 'PUNCT'), ('1', 'NUM'), ('1/2-inch', 'NUM')]

matches = matcher(doc)
spans = [doc[start:end] for _, start, end in matches]
print(spacy.util.filter_spans(spans))
## => [1 cups, 1 1/2 cups, 1 1/2-inch]