【问题标题】:Using PhraseMatcher in SpaCy to find multiple match types在 SpaCy 中使用 PhraseMatcher 查找多种匹配类型
【发布时间】:2017-12-04 17:32:49
【问题描述】:

SpaCy 文档和示例表明 PhraseMatcher 类可用于匹配文档中的标记序列。必须提供要匹配的序列词汇表。

在我的应用程序中,我的文档是标记和短语的集合。有不同类型的实体。数据是远程自然语言(文档是一组具有半随机顺序的关键字)。我正在尝试查找多种类型的匹配项。

例如:

yellow boots for kids

如何使用 SpaCy 的 PhraseMatches 找到颜色(例如黄色)、产品类型(例如靴子)和年龄(例如儿童)的匹配项?这是一个很好的用例吗?如果不同的实体匹配重叠(例如颜色列表和材料列表中的颜色匹配),是否可以产生所有独特的情况?

我不能真正使用序列标记器,因为数据结构松散并且充满歧义。我有一个实体列表(例如颜色、年龄、产品类型)和相关的值列表。

一个想法是实例化多个 PhraseMatcher 对象,每个实体一个,分别进行匹配,然后合并结果。每个实体类型都会有自己的词汇表。这听起来很简单,但效率不高,尤其是合并部分。值列表相当大。在走这条路之前,我想知道这是否是一个好主意,或者也许有更简单的方法可以用 SpaCy 做到这一点。

【问题讨论】:

    标签: python nlp spacy


    【解决方案1】:

    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 componentcustom attributes 结合使用。例如,您可以编写一个简单的组件,该组件在您对文本调用 nlp()、查找匹配项并设置 Doc._.contains_productToken._.is_color 属性时自动运行。文档中有一些示例可以帮助您入门。

    【讨论】:

    • 太棒了!回答我的问题,然后一些!
    • 看起来在最近的版本 (>=2.2.2) 中,匹配器返回的 match_id 不再是 int,而是与 add() 调用中提供的字符串相同。
    • 根据最新的文档,您可能希望将[nlp(text) for text innlp.make_doc(text) for text in 交换。 Ines 肯定知道这一点,因为她可能编写了该文档:),这一定是她回答后的改进。见spacy.io/usage/rule-based-matching中的高效短语匹配“
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多