python spacy 在 window 中寻找两个(或更多)单词
python spacy looking for two (or more) words in a window
我正在尝试识别文本中的概念。我经常认为,当两个或多个单词彼此相对接近时,一个概念就会出现在文本中。
例如,一个概念可以是任何一个词
森林、树木、自然
在距离小于 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上面提到的例子)
我正在寻找一种解决方案,该解决方案可以在 window 为 5 的范围内产生单词 Hello 和 World 的匹配项单词。
我查看了:
https://spacy.io/usage/rule-based-matching
和那里描述的运算符,但我无法将这个词-window 方法放入 "spacy" 语法中。
此外,我也无法将其推广到更多单词。
一些想法?
谢谢
对于一个有K个词的window,其中K比较小,你可以在你的词之间添加K-2个可选的通配符。 Wildcard 表示 "any symbol",在 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
如果您还想匹配其他订单 (world ? ? ? hello),则需要将第二个对称模式添加到匹配器中。
我对 spaCy 比较陌生,但我认为以下模式应该适用于 'hello' 和 'world' 之间由 ASCII 字符组成的任意数量的标记:
[{"LOWER": "hello"}, {'IS_ASCII': True, 'OP': '*'}, {"LOWER": "world"}]
我使用 Explosion 的 rule-based match explorer 对其进行了测试并且它有效。重叠匹配将 return 只有一个匹配(例如,“hello and I do mean hello world')。
我正在尝试识别文本中的概念。我经常认为,当两个或多个单词彼此相对接近时,一个概念就会出现在文本中。 例如,一个概念可以是任何一个词 森林、树木、自然 在距离小于 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上面提到的例子)
我正在寻找一种解决方案,该解决方案可以在 window 为 5 的范围内产生单词 Hello 和 World 的匹配项单词。
我查看了: https://spacy.io/usage/rule-based-matching
和那里描述的运算符,但我无法将这个词-window 方法放入 "spacy" 语法中。
此外,我也无法将其推广到更多单词。
一些想法? 谢谢
对于一个有K个词的window,其中K比较小,你可以在你的词之间添加K-2个可选的通配符。 Wildcard 表示 "any symbol",在 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
如果您还想匹配其他订单 (world ? ? ? hello),则需要将第二个对称模式添加到匹配器中。
我对 spaCy 比较陌生,但我认为以下模式应该适用于 'hello' 和 'world' 之间由 ASCII 字符组成的任意数量的标记:
[{"LOWER": "hello"}, {'IS_ASCII': True, 'OP': '*'}, {"LOWER": "world"}]
我使用 Explosion 的 rule-based match explorer 对其进行了测试并且它有效。重叠匹配将 return 只有一个匹配(例如,“hello and I do mean hello world')。