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)
当您在doc 上调用matcher 时,spaCy 将返回(match_id, start, end) 元组列表。因为 spaCy 将所有字符串存储为整数,所以您返回的 match_id 也将是一个整数 - 但您始终可以通过在词汇表的 StringStore 中查找字符串表示形式,即 nlp.vocab.strings:
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
添加匹配器规则时,还可以将on_match callback function 定义为Matcher.add 的第二个参数。如果您想触发特定操作,这通常很有用 - 例如,如果找到 COLOR 匹配,则执行一件事,而对于 PRODUCT 匹配,则执行其他操作。
如果您想更优雅地解决这个问题,您可能还想考虑将匹配器与custom pipeline component 或custom attributes 结合使用。例如,您可以编写一个简单的组件,该组件在您对文本调用 nlp()、查找匹配项并设置 Doc._.contains_product 或 Token._.is_color 属性时自动运行。文档中有一些示例可以帮助您入门。