Что есть NER сервисы и как их применяют в бизнесе от А до Я (практика)
Введение
Крайне важный кейс для бизнеса — автоматизация бизнес процессов, где раньше можно было только использовать, например, оператора или клиентского менеджера, а сейчас им на помощь и замену чат-боты, голосовые ассистенты и вот и настало время, когда без машинного обучения и NLP уже никуда. Предлагаю рассмотреть NER сервисы и если обратиться к wikipedia:
Named-entity recognition (NER) (also known as (named) entity identification, entity chunking, and entity extraction) is a subtask of information extraction that seeks to locate and classify named entities mentioned in unstructured text into pre-defined categories such as person names, organizations, locations, medical codes, time expressions, quantities, monetary values, percentages, etc.
Что есть Named Entity Recognition или NER: логика и принцип работы
Т. е. Named Entity Recognition (NER) — это задача в области обработки естественного языка (NLP), направленная на выделение и классификацию именованных сущностей в тексте, таких как имена людей, названия организаций, даты, местоположения, суммы денег и другие типы специфических объектов. NER является важным компонентом многих NLP-приложений, таких как извлечение информации, анализ тональности, вопросно-ответные системы и многие другие, как раз наше направление чат-боты, голосовые ассистенты, смс, телефонные разговоры.
Основные подходы:
1. Подход на основе правил (Rule-Based Approach). В этом подходе создаются наборы правил, которые определяют, какие последовательности слов в тексте могут быть именованными сущностями. Эти правила могут основываться на регулярных выражениях, шаблонах или лингвистических признаках. Примеры библиотек: spaCy (с поддержкой настраиваемых правил), NLTK.
2. Подход на основе машинного обучения (Machine Learning-Based Approach). В этом подходе используются алгоритмы машинного обучения, такие как CRF (Conditional Random Fields), LSTM (Long Short-Term Memory) и BERT (Bidirectional Encoder Representations from Transformers), чтобы обучить модель распознавать именованные сущности. Модель обучается на размеченных данных, где сущности помечены в тексте. Примеры библиотек: spaCy (с обучаемыми моделями), Stanford NER, Flair.
3. Совмещенный подход (Hybrid Approach). Этот подход объединяет правила и машинное обучение для улучшения точности NER. Можно сначала применить правила для выделения сущностей, а затем пропустить текст через модель машинного обучения для уточнения результатов.
А теперь немного о логике работы NER:
1. Токенизация текста, т. е. текст разбивается на отдельные слова или токены;
2. Выделение признаков — каждому токену назначаются признаки, которые описывают его окружение и контекст, такие как предыдущие и следующие слова, части речи и другие лингвистические характеристики;
3. Применение модели — модель анализирует признаки каждого токена и определяет, является ли он именованной сущностью или нет;
4. Объединение результатов — результаты анализа токенов объединяются, чтобы сформировать именованные сущности, и им назначаются соответствующие метки классов, такие как «PER« (для персон) или »ORG» (для организаций) ;
5. Постобработка — дополнительная обработка для уточнения результатов или исправления ошибок;
Библиотеки для NER предоставляют готовые решения для выделения именованных сущностей и могут быть адаптированы под конкретные задачи и типы данных, как например кейсы, описанные в начале статьи. Выбор конкретной библиотеки зависит от требований проекта, языка и доступных данных для обучения, конечно если используется машинное обучение.
О моей команде
Моя команда разрабатывает сложные решения и сервисы в BigData для бизнеса с профильным направлением графового анализа и геоанализа данных, также мы предлагаем и ML сервисы (Machine learning): один из которых для разметки аудио, текста и изображений (назовем его «Маркер»), а другие за NER-направление. Хотя совсем недавно я переключился на другой проект, но об этом в следующих статьях.
Примеры NER сервисов
Наверное ты спросишь, а есть ли разница между обработкой сообщений чат-ботов, смс или телефонных разговоров? Да, но она крайне небольшая, если чат бот и смс — текстовая информация, то телефонный разговор — аудио, которое требуется перекодировать в текст, т. е. сделать расшифровку, а потом уже натравить на текст NER сервисы. Данный вид сервисов важен, так как позволяет автоматизировать часть процессов колл-центров и клиентских менеджеров, а также помочь с проверкой того что услышал, чтобы потом не возникало разногласий. Итого, NER сервисы это не просто применение готовых библиотек, а кастомизированый сервис, который содержит дополнительную логику под определеную бизнес задачу и помогают автоматически извлекать не только сущности, такие как имена клиентов, но и номера счетов, условия предложений, суммы перевода и т. п.
Практика
Предлагаю продемонстрировать пример такого сервиса с применением библиотек, ставших классическими в мире NLP. Каждая библиотека обладает своими недостатками и преимуществами, но предлагаю не фокусироваться сейчас на этом, а рассмотреть пример из практики, но максимально облегченный.
Возьмём фразу и сделаем набор кода, который нам поможет проанализировать и получить нужные нам сущности и параметры:
"Добрый день, я, Сидоров Иван Иванович. Прошу перевести сто тысяч рублей Якову Петру Игнатьевичу"
Как обработать данную фразу?
Сценарий:
- Собираем массив ФИО, где ФИО совпадающее с ФИО счета — платильщик, а второй элемент ФИО — получателя.
- Определяем тип запроса: перевести, оплатить, пополнить баланс и т. п
- Находим сумма и её валюту, которую нужно перевести между счетами.
Код для извлечения ФИО
Попробуем немного описать логику кода приведенного выше:
- Импортирует библиотеку spacy, которая используется для обработки текста и с помощью предварительно обученной модели spacy для русского языка (ru_core_news_sm).
- Определяем функцию extract_names(text), которая принимает текст в качестве входного аргумента. Функция выполняет следующие действия: загружает модель ru_core_news_sm, обрабатывает текст с созданием объект Doc, после чего, создает пустой список names для хранения найденных ФИО, проходим по сущностям (ent) в тексте и, если сущность имеет метку «PER» (персона), добавляет её в список names и возвращаем список names, содержащий найденные ФИО.
- Определяет функцию lemmatize_text(text), которая принимает текст в качестве входного аргумента. Функция выполняет следующие действия: загружает модель для русского языка (аналогично прошлой функции), обрабатывает текст с помощью этой модели, создавая объект Doc, лемматизирует токены и объединяет в строку, разделенную пробелами, далее возвращает лемматизированный текст.
- Извлекаем ФИО из исходного текста с помощью функции extract_names(text) и сохраняет результат в переменную found_names.
- Использует цикл for, чтобы пройти по списку found_names и выводить ФИО по два элемента на каждой итерации. Каждая пара ФИО сначала конкатенируется с помощью пробела, затем проходит через функцию lemmatize_text для лемматизации, и наконец выводится на экран.
Таким образом, этот код выполняет извлечение ФИО из текста, лемматизацию ФИО и вывод лемматизированных ФИО по два на каждой итерации.
С ФИО тут просто, так как мы объявляем массив и потом сопоставляем, а вот с фразами типа: «перевести«, "отправь", »скинь» — немного сложнее, нужно в любом случае держать какой то объём допустимых слов-команд. В данном случае я не говорю по крайне ресурсоёмкие современные нейросети на подобии chat gpt, которые способны анализировать текст и ей подобные, будем пользоваться простыми и прозрачными библиотеками, которые не забанит ИБ (знающие поймут).
Код для выявления типа запроса клиента
В этом примере мы используем библиотеку pymystem3 для лемматизации слов. Функция find_word_in_text принимает текст и слово, которое нужно найти, и возвращает True, если слово присутствует в тексте, и False, если нет. А теперь ещё раз, что мы сделали в блоке выше: приводим текст к нижнему регистру для удобства обработки, затем мы используем Mystem для лемматизации текста. После этого мы проверяем, присутствует ли исходное слово в лемматизированном тексте. Если да, функция возвращает, то как и написано выше — True.
Ну что, в принципе мы прошлись целиком по фразе и выявили всё что нам потребовалось… А нет, забыли про главное — деньги! Сколько перевести то?
Код для преобразования чисел в в виде цифр
Код выше, использует библиотеку ru_word2number, которая предоставляет функциональность для преобразования чисел, записанных словами на русском языке, в числовой формат. Давай разберем логику работы этого кода:
- Импорт библиотеки ru_word2number:pythonCopy codefrom ru_word2number import w2n Этой строкой кода мы импортируем функцию word_to_num из библиотеки ru_word2number, которая позволяет преобразовать текст, содержащий числа, записанные словами на русском языке, в числовой формат.
- Задаем переменную — codetext_russian — с уже знакомым текстом. Здесь задается текст, в котором содержатся числа, записанные словами на русском языке. Этот текст будет подвергнут обработке, и числа будут преобразованы в числовой формат.
- Преобразование текста происходит с помощью функции word_to_num из библиотеки ru_word2number. Результат преобразования сохраняется в переменной number_russian.
Таким образом, мы обработали текст с числами, записанными словами на русском языке и преобразовали в числовой формат.
Код для поиска валюты платежа
Данный код выполняет поиск наименований валют на русском языке (у каждой библиотеки, лемматизатора или модели есть ограничение по языкам) в заданном тексте и лемматизирует их с использованием библиотеки pymorphy2. Логика кода следующая:
- Задается текст, в котором мы хотитим найти наименования валют.
- Инициализируется лемматизатор с помощью pymorphy2.MorphAnalyzer().
- Создается регулярное выражение currency_pattern, которое ищет наименования валют. Это регулярное выражение ищет следующие слова: «доллар«, "долларов", "евро", "рубль", "рубля", »рублей», игнорируя регистр (флаг re.ignorecase). В данной реализации ограничение — 3 валюты.
- С использованием re. findall, производится поиск всех совпадений с регулярным выражением currency_pattern в заданном тексте. Результат поиска сохраняется в переменной currencies_found.
- Далее, для каждого найденного наименования валюты из списка currencies_found, выполняется лемматизация с использованием morph. parse(word) [0]. normal_form. Это преобразует слово в его нормальную (лемматизированную) форму с учетом разных склонений и форм на русском языке. Лемматизированные формы сохраняются в переменной lemmatized_currencies.
- Найденные наименования валют и их лемматизированные формы выводятся на экран.
Таким образом, код находит и лемматизирует наименования валют в тексте, что позволяет вам работать с ними в единой форме, игнорируя различные склонения и формы.
Резюме
Итого мы вычленили ФИО отправителя и получателя, сумму и валюту, а также ключевое слово для определения сценария действий. Код написан на основе простых функций без учёта оптимальности. Написать подобный код не так сложно, а вот польза от этого кода колоссальная, так как помогает автоматизировать процесс и не заставлять клиентов ждать.
Приложение, если будет интересно
А теперь пример прямо с сайта библиотеки deeppavlov
P. S. надеюсь количество опечаток было минимальным
Ресурсы на публикакации