将 REGEX 实体添加到 SpaCy 的匹配器

问题描述 投票:0回答:2

我正在尝试将正则表达式定义的实体添加到 SpaCy 的 NER 管道中。理想情况下,我应该能够使用从具有定义的实体类型的 json 文件加载的任何正则表达式。作为一个例子,我正在尝试执行下面的代码。

下面的代码显示了我正在尝试做的事情,遵循 Spacy 关于使用正则表达式的自定义属性的讨论中给出的示例。我尝试以各种方式调用“set_extension”方法(到 Doc、Span、Token),但无济于事。我什至不确定我应该将它们设置为什么。

    nlp = spacy.load("en_core_web_lg")
    matcher = Matcher(nlp.vocab)
    pattern = [{"_": {"country": {"REGEX": "^[Uu](\.?|nited) ?[Ss](\.|tates)$"}}}]
    matcher.add("US", None, pattern)
    doc = nlp(u"I'm from the United States.")
    matches = matcher(doc)
    for match_id, start, end in matches:
        string_id = nlp.vocab.strings[match_id]
       span = doc[start:end]
       print(match_id, string_id, start, end, span.text)

我希望

match_id, string_id 3 4 United States
能够被打印出来。

相反,我得到了

AttributeError:  [E046] Can't retrieve unregistered extension attribute 'country'.  Did you forget to call the 'set_extension' method?

regex spacy
2个回答
5
投票

这里有关于扩展属性的文档:https://spacy.io/usage/processing-pipelines#custom-components-attributes

基本上,您必须将这个

country
变量定义为扩展属性,如下所示:

Token.set_extension("country", default="")

但是,在您引用的代码中,您实际上从未将

_.country
属性设置为任何标记(或范围),因此它们仍然处于默认值,并且匹配器将永远无法在它们上进行匹配。您引用的行:

pattern = [{"_": {"country": {"REGEX": "^[Uu](\.?|nited) ?[Ss](\.?|tates)$"}}}]

尝试匹配美国正则表达式在自定义属性值上,而不是在文档文本上,如您所期望的(我认为)。

一种解决方案是直接在文本上运行 reg-exps:

nlp = spacy.load("en_core_web_lg")
matcher = Matcher(nlp.vocab)
pattern = [{"TEXT": {"REGEX": "^[Uu](\.?|nited)$"}},
           {"TEXT": {"REGEX": "^[Ss](\.?|tates)$"}}]
matcher.add("US", None, pattern)
doc = nlp(u"I'm from the United States.")
matches = matcher(doc)
for match_id, start, end in matches:
    string_id = nlp.vocab.strings[match_id]
    span = doc[start:end]
    print(match_id, string_id, start, end, span.text)

哪个输出

15397641858402276818 美国 4 6 美国

然后您可以使用这些匹配来例如在 Span 或 Token 上设置自定义属性(在本例中为 Span,因为您的匹配可能涉及多个 token)


0
投票

正如如何将标准正则表达式与 SpaCy 的 Matcher 或 PhraseMatcher 结合使用,同时允许正则表达式中存在空格,检查令牌的答案无法与任何嵌入空格的正则表达式一起使用。

换句话说,标记生成器将数据拆分为标记,以便正则表达式不再匹配任何嵌入的空格,这为您提供了两种解决方法:

  1. 您可以尝试在自己的标记化上运行正则表达式。通过句子而不是单词进行标记。然后检查您的正则表达式模式。再次将该输出作为全文放入 spaCy 管道中。您甚至可以尝试在标记化之前将其添加为管道中的一个步骤。

  2. 另一种解决方法可能是检查在所有标记的主循环内链接在一起的相邻单词(链接回之前的其他两个单词)是否与最多三个单词的模式匹配(=最多两个嵌入空格) )。如果找到某些内容,请使用您在字典中针对所需标记映射的标记覆盖所有三个匹配项。运行后,如果需要,您可以仅用一场比赛替换此类比赛。您还可以找到另一种没有映射表的方法来做到这一点,这只是第一个想法,您甚至可以在循环期间更改已经在运行的匹配。

由于正则表达式在大文本上变得很慢,因此在对其运行正则表达式之前,您应该至少按句子进行标记,并且我猜想使用单词标记和向后检查循环的解决方法“2”比对文本进行正则表达式检查更容易和更快句子标记,因为管道将保持原样。三次向后检查循环不会花费太多速度。我没有对此进行测试,因为我发现将带有空格的正则表达式重写为不带空格的正则表达式列表更容易,请参阅堆栈溢出命名实体识别(NER)spaCy模型或它周围的实体标尺之类的任何代码是否可以捕获我的新内容进一步的日期模式也作为 DATE 实体?.

© www.soinside.com 2019 - 2024. All rights reserved.