python spacy在窗口中寻找两个(或更多)单词

时间:2019-07-01 14:26:05

标签: python nlp spacy matcher

我正在尝试识别文本中的概念。通常,我认为当两个或多个单词彼此相对接近时,一个概念就会出现在文本中。 例如,一个概念就是任何一个词 森林自然 距离少于4个字 着火燃烧过热

我正在学习spacy,到目前为止,我可以像这样使用匹配器:

import spacy
from spacy.matcher import Matcher
nlp = spacy.load("en_core_web_sm")
matcher = Matcher(nlp.vocab)
matcher.add("HelloWorld", None, [{"LOWER": "hello"}, {"IS_PUNCT": True}, {"LOWER": "world"}],[{"LOWER": "hello"}, {"LOWER": "world"}])

hello world hello,world (或上述示例中的 tree firing )匹配

我正在寻找一种解决方案,可以在5个字的窗口内匹配 Hello World

我调查了: https://spacy.io/usage/rule-based-matching

及其那里的运算符进行了描述,但是我无法将这种字窗口方法置于“ spacy”语法中。

此外,我也无法将其概括为更多的单词。

有些想法? 谢谢

2 个答案:

答案 0 :(得分:1)

对于具有K个单词的窗口(其中K相对较小),可以在单词之间添加K-2个可选的通配符。 通配符的意思是“任何符号”,用Spacy术语来说,这只是一个空字典。 可选表示令牌可能存在或不存在,并且在Spacy中被编码为{"OP": "?"}

因此,您可以将匹配器写为

import spacy
from spacy.matcher import Matcher
nlp = spacy.load("en_core_web_sm")
matcher = Matcher(nlp.vocab)
matcher.add("HelloWorld", None, [{"LOWER": "hello"}, {"OP": "?"},  {"OP": "?"}, {"OP": "?"}, {"LOWER": "world"}])

表示您要寻找“ hello”,然后是0到3个任何类型的令牌,然后是“ world”。例如,对于

doc = nlp(u"Hello brave new world")
for match_id, start, end in matcher(doc):
    string_id = nlp.vocab.strings[match_id]
    span = doc[start:end]
    print(match_id, string_id, start, end, span.text)

它将打印您

15578876784678163569 HelloWorld 0 4 Hello brave new world

如果还要匹配其他顺序(世界???你好),则需要在匹配器中添加第二个对称模式。

答案 1 :(得分:1)

我对spaC还是比较陌生,但是我认为以下模式适用于'hello'和'world'之间由ASCII字符组成的任意数量的令牌:

[{"LOWER": "hello"}, {'IS_ASCII': True, 'OP': '*'}, {"LOWER": "world"}]

我使用爆炸的rule-based match explorer测试了它,并且可以正常工作。重叠的比赛只会返回一场比赛(例如,“你好,我的意思是你好,世界”)。