SpaCy文档和示例显示,PhraseMatcher类可用于匹配文档中的标记序列。必须提供匹配的序列词汇。
在我的应用程序中,我的文档是令牌和短语的集合。有不同类型的实体。数据是远程自然语言(文档是具有半随机顺序的关键字集)。我正在尝试找到多种类型的匹配。
例如:
yellow boots for kids
如何使用SpaCy的PhraseMatches找到颜色(例如黄色),产品类型(例如靴子)和年龄(例如孩子)的匹配?这是一个很好的用例吗?如果不同的实体匹配重叠(例如颜色在颜色列表和材料列表中匹配),是否可以生成所有唯一的案例?
我不能真正使用序列标记器,因为数据结构松散且含糊不清。我有一个实体列表(例如颜色,愤怒,产品类型)和相关的值列表。
一个想法是实例化多个PhraseMatcher对象,每个实体一个,分别进行匹配,然后合并结果。每个实体类型都将获得自己的词汇表。这听起来很简单但效率不高,尤其是合并部分。值列表相当大。在走这条路之前,我想知道这是一个好主意,还是有更简单的方法可以用SpaCy做到这一点。
答案 0 :(得分:19)
spaCy的PhraseMatcher
支持添加包含多个模式的多个规则,并为您添加的每个匹配器规则分配ID。如果两个规则重叠,则将返回两个匹配项。所以你可以这样做:
color_patterns = [nlp(text) for text in ('red', 'green', 'yellow')]
product_patterns = [nlp(text) for text in ('boots', 'coats', 'bag')]
material_patterns = [nlp(text) for text in ('silk', 'yellow fabric')]
matcher = PhraseMatcher(nlp.vocab)
matcher.add('COLOR', None, *color_patterns)
matcher.add('PRODUCT', None, *product_patterns)
matcher.add('MATERIAL', None, *material_patterns)
当您致电matcher
上的doc
时,spaCy将返回(match_id, start, end)
元组列表。因为spaCy将所有字符串存储为整数,所以你得到的match_id
也将是一个整数 - 但是你总是可以通过在词汇表StringStore
中查找它来获得字符串表示,即{{1} }:
nlp.vocab.strings
添加匹配器规则时,您还可以将on_match
callback function定义为doc = nlp("yellow fabric")
matches = matcher(doc)
for match_id, start, end in matches:
rule_id = nlp.vocab.strings[match_id] # get the unicode ID, i.e. 'COLOR'
span = doc[start : end] # get the matched slice of the doc
print(rule_id, span.text)
# COLOR yellow
# MATERIAL yellow fabric
的第二个参数。如果您想要触发特定操作,这通常很有用 - 例如,如果找到Matcher.add
匹配则执行一项操作,并为COLOR
匹配执行其他操作。
如果您想更优雅地解决这个问题,您可能还希望将匹配器与custom pipeline component或custom attributes结合起来。例如,您可以编写一个简单的组件,当您在文本上调用PRODUCT
,查找匹配项并设置nlp()
或Doc._.contains_product
属性时,该组件会自动运行。文档中有一些例子可以帮助您入门。