Python Textacy pos_regex_matches против совпадений - PullRequest
0 голосов
/ 10 февраля 2020

Я пытаюсь найти глаголы в предложении с python для проблемы НЛП. Я нашел старый ответ здесь на stackoverflow, и он работает с устаревшими pos_regex_matches. Использование новой функции совпадений у меня довольно скучная проблема. Новая функция возвращает любое совпадение, а не только самое длинное совпадение (что делает pos_regex_matches).

pattern = r'<VERB>*<ADV>*<VERB>+<PART>*'
verb_pattern = [{"POS": "VERB", "OP": "*"},{"POS": "ADV", "OP": "*"},{"POS": "VERB", "OP": "+"},{"POS": "PART", "OP": "*"}]

t_list_1 = textacy.extract.pos_regex_matches(text, pattern)
t_list_2 = textacy.extract.matches(text, verb_pattern)

Как вы можете видеть, шаблон такой же, но один из функций совпадений в новом формате. Старый pos_regex_matches возвращает, например, was celebrating, в то время как новые совпадения возвращают и was и was celebrating. Кто-то сталкивался с такой же проблемой? Это проблема шаблона или текстового сообщения?

Заранее спасибо

1 Ответ

0 голосов
/ 01 апреля 2020

У меня такая же проблема. Хотя я не смог найти флаг, позволяющий жадному сопоставлению выражения возвращать самые длинные совпадения, а не вложенные части, я написал этот небольшой фрагмент кода, который вручную удаляет совпадения, которые не являются максимальными.

pattern = r'<VERB>*<ADV>*<VERB>+<PART>*'
verb_pattern = [{"POS": "VERB", "OP": "*"},{"POS": "ADV", "OP": "*"},{"POS": 
"VERB", "OP": "+"},{"POS": "PART", "OP": "*"}]

t_list_1 = textacy.extract.pos_regex_matches(text, pattern)
t_list_2 = textacy.extract.matches(text, verb_pattern)

# take the longest when overlapping
for i, el_i in enumerate(t_list_2):
    for j in range(i):
        el_j = t_list_2[j]
        if not el_j:
            continue
        if el_j.start <= el_i.start and el_j.end >= el_i.end:
            # el_i inside el_j
            t_list_2[i] = None
            break
        elif el_i.start <= el_j.start and el_i.end >= el_j.end:
            # el_j inside el_i
            t_list_2[j] = None
        elif el_i.end > el_j.start and el_i.start < el_j.end:
            raise ValueError('partial overlap?')
t_list_2 = [el for el in t_list_2 if el]
...