Aivaro
  • Оглавление
  • Вопросы
  • Практика
  • Вики
  • Материалы сообщества
  • Тесты
  • Поиск
✈Telegram @ai_varo
RUEN中文
…
Оглавление/Вопросы/#903

Что такое NER (Named Entity Recognition)? Как извлекать организации, даты и персоны из текста с помощью библиотеки DeepPavlov?

Краткий тезис

NER (Named Entity Recognition) — задача извлечения именованных сущностей (персоны, организации, локации, даты и т.д.) из неструктурированного текста. Для русского языка библиотека DeepPavlov предоставляет готовые предобученные модели на основе BERT и BiLSTM-CRF, позволяющие извлекать сущности с F1 > 95% на стандартных корпусах. Ключевой вызов — обработка омонимии (например, «Марс» как планета vs бренд) и вложенных сущностей.

| --- | --- | | PER (Person) | Иван Петров, А.С. Пушкин | Включает имена, фамилии, отчества | | ORG (Organization) | Яндекс, ООН, МГУ | Компании, госорганы, учреждения | | LOC (Location) | Москва, Сибирь, Байкал | Географические объекты | | GPE (Geo-Political Entity) | Россия, США | Страны, города как политические единицы | | DATE | 12 марта 2023 года, вчера | Абсолютные и относительные даты | | TIME | 15:30, полдень | Временные интервалы | | MONEY | 1000 рублей, $50 | Денежные суммы | | PRODUCT | iPhone 15, ChatGPT | Товары, продукты, сервисы |

Для русского языка дополнительно выделяют:

  • EVENT (Олимпиада-80, ЧМ-2018)
  • FAC (Кремль, Эрмитаж) — здания и сооружения

2. Подходы к NER

2.1 Rule-based (правила и словари)

  • Принцип: регулярные выражения + gazetteer (списки сущностей).
  • Пример: \b(г-н|господин)\s+[А-Я][а-я]+\b для персон.
  • Плюсы: прозрачность, не требует размеченных данных.
  • Минусы: низкая полнота (не покрывает вариации), хрупкость.

2.2 CRF (Conditional Random Fields)

  • Принцип: последовательная маркировка с учётом контекстных признаков (POS-теги, префиксы/суффиксы).
  • Инструменты: CRFsuite, sklearn-crfsuite.
  • F1: ~85-90% на русском (зависит от качества признаков).

2.3 BiLSTM-CRF

  • Архитектура: BiLSTM кодирует контекст, CRF слой моделирует зависимости между метками (например, B-PER не может следовать за I-ORG).
  • Эмбеддинги: FastText или BERT как вход.
  • F1: ~92-95% на Collection3 (русский NER-корпус).

2.4 BERT-based (Transformer)

  • Принцип: fine-tuning предобученной модели (RuBERT, SBERT) с head-слоем для токен-классификации.
  • Преимущества: контекстные эмбеддинги, обработка омонимии.
  • F1: ~96-98% на CoNLL-2003 (русская версия).

3. DeepPavlov: загрузка модели и пример кода

DeepPavlov — библиотека для NLP на русском и английском, включает предобученные NER-модели.

3.1 Установка и загрузка модели

pip install deeppavlov
python -m deeppavlov install ner_ontonotes_bert_mult

Доступные конфигурации:

  • ner_ontonotes_bert_mult — BERT-based (многоязычный, 18 типов сущностей)
  • ner_collection3_bert — RuBERT, обучен на Collection3 (русский)
  • ner_rus_bert — лёгкая версия для русского

3.2 Пример извлечения сущностей

from deeppavlov import build_model, configs

# Загрузка модели
ner_model = build_model(configs.ner.ner_ontonotes_bert_mult, download=True)

# Текст для анализа
text = "Вчера Иван Петров посетил офис Яндекса в Москве и обсудил проект на 5 млн рублей."

# Извлечение сущностей
entities = ner_model([text])

# Результат: список токенов и их меток
tokens, tags = entities[0]
print(list(zip(tokens, tags)))
# [('Вчера', 'B-DATE'), ('Иван', 'B-PERSON'), ('Петров', 'I-PERSON'),
#  ('посетил', 'O'), ('офис', 'O'), ('Яндекса', 'B-ORG'),
#  ('в', 'O'), ('Москве', 'B-GPE'), ('и', 'O'), ('обсудил', 'O'),
#  ('проект', 'O'), ('на', 'O'), ('5', 'B-MONEY'), ('млн', 'I-MONEY'),
#  ('рублей', 'I-MONEY'), ('.', 'O')]

3.3 Форматирование результатов

def extract_entities(tokens, tags):
    entities = []
    current_entity = None
    for token, tag in zip(tokens, tags):
        if tag.startswith('B-'):
            if current_entity:
                entities.append(current_entity)
            current_entity = {'type': tag[2:], 'text': token}
        elif tag.startswith('I-') and current_entity:
            current_entity['text'] += ' ' + token
        else:
            if current_entity:
                entities.append(current_entity)
                current_entity = None
    if current_entity:
        entities.append(current_entity)
    return entities

entities_list = extract_entities(tokens, tags)
for ent in entities_list:
    print(f"{ent['type']}: {ent['text']}")
# DATE: Вчера
# PERSON: Иван Петров
# ORG: Яндекса
# GPE: Москве
# MONEY: 5 млн рублей

4. Оценка качества NER

4.1 Метрики

Основная метрика — F1-score (гармоническое среднее точности и полноты):

МетрикаФормулаОписание
PrecisionTP / (TP + FP)Доля правильных сущностей среди найденных
RecallTP / (TP + FN)Доля найденных сущностей среди всех
F12 * P * R / (P + R)Сбалансированная метрика

4.2 Строгое vs свободное совпадение

  • Строгое (exact match): сущность считается правильной, если границы и тип совпадают полностью.
    • Пример: «Иван Петров» vs «Иван» — не совпадает.
  • Свободное (partial match): допускается частичное перекрытие.
    • Пример: «Иван Петров» vs «Иван» — частичное совпадение (тип верный, границы неполные).

На практике для бизнес-задач часто используют свободное совпадение, так как строгое занижает реальное качество (особенно для длинных сущностей).

4.3 Типичные ошибки на русском языке

ОшибкаПримерПричина
Омонимия«Марс» (планета vs шоколад)Контекстная неоднозначность
Вложенные сущности«МГУ им. Ломоносова» (ORG + PER)Модели не всегда выделяют вложенность
Аббревиатуры«ООН» (ORG) vs «он» (местоимение)Регистрозависимость
Даты в разных форматах«12.03.2023» vs «12 марта 2023 г.»Вариативность записи

5. Пет-проект для закрепления

Задача: Разработать Telegram-бота, который извлекает из сообщений пользователя организации, даты и персоны, и сохраняет их в структурированном виде (JSON).

Инструменты:

  • Python 3.10+
  • DeepPavlov (модель ner_collection3_bert)
  • python-telegram-bot (библиотека для Telegram API)
  • JSON для хранения результатов

Шаги:

  1. Установите зависимости: pip install deeppavlov python-telegram-bot
  2. Скачайте модель: python -m deeppavlov install ner_collection3_bert
  3. Напишите функцию extract_entities(text), возвращающую список сущностей с типом и текстом.
  4. Создайте Telegram-бота с обработчиком текстовых сообщений.
  5. Для каждого сообщения вызывайте NER-модель и отправляйте пользователю форматированный ответ.
  6. Добавьте команду /export для выгрузки всех извлечённых сущностей в JSON-файл.

Ожидаемый результат:

  • Бот корректно извлекает сущности из сообщений на русском языке.
  • Пользователь видит: «Найдены сущности: PERSON: Иван Петров, ORG: Яндекс, DATE: 12 марта».
  • При команде /export формируется файл entities.json с историей.

Связь с другими вопросами

ВопросТема
904Сравнение NER-моделей: spaCy vs DeepPavlov vs Stanza
905Извлечение отношений (RE) и связь с NER

Навигация

  • Предыдущий: 902
  • Следующий: 904
  • Индекс: 00. Индекс разборов za|904]]
  • Индекс: 00. Индекс разборов