python Spacy并不是在寻找一个特定的模式

xj3cbfub  于 6个月前  发布在  Python
关注(0)|答案(1)|浏览(74)

鉴于这句话:

txt = "Os edifícios multifamiliares devem ser providos de proteção contra descargas atmosféricas, atendendo ao estabelecido na ABNT NBR 5419 e demais Normas Brasileiras aplicáveis, nos casos previstos na legislação vigente."

nlp = spacy.load("pt_core_news_md")
doc = nlp(txt)

字符串
这本字典有模式和标签:

patterns= [
{"label": "COMPONENTE", "pattern": [
        [{"POS": "NOUN"},{"POS": "ADP"},{"POS": "NOUN"},{"POS": "ADJ"}],
        [{"POS": "NOUN"},{"POS": "ADP"},{"POS": "ADJ"}],
        [{"POS": "NOUN"},{"POS": "ADP"},{"POS": "NOUN"}], #<<< the problem
        [{"POS": "NOUN", "DEP":"nsubj"},{"POS": "ADJ"},{"POS": "ADJ"}],
        [{"POS": "NOUN", "DEP":"nsubj"}],
        [{"POS": "NOUN"},{"POS": "ADJ"}]
    ]}


我尝试使用此功能在整个句子中搜索,而不是重复下一个模式搜索的单词:

from spacy.matcher import Matcher
from spacy.tokens import Span

def buscar_padroes_sequencialmente(doc, patterns):
    resultados = []
    tokens_processados = set()

    for pat in patterns:
        label = pat["label"]
        matcher = Matcher(doc.vocab)
        
        for i, padrao_atual in enumerate(pat["pattern"]):
            matcher.add(f"{label}", [padrao_atual])

        for padrao_id, inicio, fim in matcher(doc):
            rótulo = matcher.vocab.strings[padrao_id]

            # Verify is any token was processed before
            if any(token.i in tokens_processados for token in doc[inicio:fim]):
                continue

            # Add pattern tokens to the variable tokens_processados
            tokens_processados.update(token.i for token in doc[inicio:fim])

            # tokens to span
            span = Span(doc, inicio, fim, label=rótulo)
            resultados.append((rótulo, span))

    return resultados


当我使用函数并打印结果时:

resultados = buscar_padroes_sequencialmente(doc, patterns)

print("Frase:", txt)
for i, (rotulo, span) in enumerate(resultados, start=1):
    
    pos_tokens = [token.pos_ for token in span]

    print(f"OSemantic {i}:", span.text, f'({rotulo})')
    print("POStoken:", pos_tokens)
    print()


我期待得到一些结果,但具体来说:

OSemantic 4: proteção contra descargas atmosféricas (COMPONENTE)
POStoken: ['NOUN', 'ADP', 'NOUN', 'ADJ']


但我得到了这个

OSemantic 4: proteção contra descargas (COMPONENTE)
POStoken: ['NOUN', 'ADP', 'NOUN']


因此,代码无法找到模式下span的最后一个标记

[{"POS": "NOUN"},{"POS": "ADP"},{"POS": "NOUN"},{"POS": "ADJ"}]


如果我改变模式的顺序也不会发生什么。只有当我删除模式[{"POS": "NOUN"},{"POS": "ADP"},{"POS": "NOUN"}],那么是的,它可以搜索其他的。

zpqajqem

zpqajqem1#

我设法在Matcher.add文档中找到了答案。我测试了插入可选参数“greedy”,它接收两个选项“FIRST”或“LONGEST”。
奇怪的是,当我使用“FIRST”选项时,它会搜索在句子中找到的第一个模式,考虑到问题是根据模式的顺序搜索对应关系,这不会解决我的问题.
但是,使用“LONGEST”选项,它总是搜索最长的模式,这在某种程度上解决了我的问题,因为它首先搜索短语中最长的匹配。
下面是代码和答案:

matcher.add(f"{label}", [padrao_atual], greedy = "")

字符串

相关问题