数字名词/数字名词的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]
您好,我尝试使用 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]