Время прочтения: 3 мин.

Не так давно мы рассматривали способы доработки библиотеки для разбиения текста на предложения, теперь же поговорим о поиске дат в этих предложениях.

Поиск дат в тексте является весьма распространенной задачей, для решения которой уже существует множество решений. Библиотека «Natasha» является одним из таких решений, которая, к тому же изначально была написана для работы с русскоязычными текстами, что повышает ее приоритет в использовании. Однако, в связи с разнообразием форматов дат в документах, модуль позволяет найти не все интересующие нас даты без дополнительной настройки.

В этой статье мы рассмотрим способ доработки модуля поиска дат из библиотеки «Natasha».

Библиотека «Natasha» позволяет решать базовые задачи обработки естественного русского языка: сегментация на токены и предложения, предобученные эмбеддинги, анализ морфологии и синтаксиса, лемматизация, NER. Все решения показывают достойные результаты и быстро работают на CPU. Также «Natasha» позволяет выделять в тексте такие сущности, как: деньги, имена, адреса и даты.

Поиск дат осуществляется с использованием правил, построенных на эвристиках. Для работы с датами в библиотеке существует отдельный файл «date.py»:

Данный файл содержит объекты, описывающие следующие сущности:

  • «DAY» – дни недели;
  • «MONTH» – месяца года в числовой форме;
  • «MONTH_NAME» – месяца года в словесной форме;
  • «YEAR» – года в числовой форме;
  • «YEAR_SHORT» – сокращенные формы записи года.

На основании перечисленных сущностей формируются правила в формате «Yargy» парсера, по которым определяются даты. Например, данная часть кода

 позволяет находить даты следующего формата:

  • 21.10.2021;
  • 21.10.21;
  • 21.10.2021 год (г.);
  • 21.10.21 год (г.).

Таким образом, комбинируя сущности, описанные выше и добавляя различные разделители или логику, мы можем «научить» модуль искать даты в нужном нам формате.

Например, для того чтобы модуль научился искать даты формата «ДД-ММ-ГГГГ», можно дописать такое правило:

rule(
    DAY,
    '-',
    MONTH,
    '-',
    or_(
        YEAR,
        YEAR_SHORT
    ),
    YEAR_WORD.optional()
),

В итоге, после доработки этого файла, им можно заменить старый файл библиотеки и пользоваться уже доработанной версией модуля.

Однако, бывают ситуации, когда у нас нет возможности или желания заменять это файл при каждом обновлении библиотеки. В таком случае, мы можем создать свой класс для поиска дат, наследуясь от модуля библиотеки «Natasha».

from natasha import DatesExtractor

class NewDatesExtractor(DatesExtractor):

    def __init__(self, morph):
        from yargy import (
            rule,
            and_, or_
        )
        from yargy.interpretation import fact
        from yargy.predicates import (
            eq, gte, lte, length_eq,
            dictionary, normalized,
        )

        from natasha.grammars.date import YEAR, MONTH, MONTH_NAME, YEAR_WORD, YEAR_SHORT, DAY, Date
        from natasha.extractors import Extractor

        DATE = or_(
            ...
        )

        Extractor.__init__(self, DATE, morph)

Где в переменной «DATE» будет наш новый набор правил. Тогда далее по коду можно будет вызывать наш обновленный класс, который будет работать несмотря на обновления основной библиотеки «Natasha».