Создайте и распространите простое приложение НЛП с помощью Python

Введение

Предварительная обработка — один из самых важных шагов в приложениях машинного обучения/науки о данных. В реальном мире большинство наборов данных грязные, содержат пропущенные значения и полны неправильных столбцов, таких как строки, даты и другие типы нечисловых признаков.

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

В приложениях NLP (обработка естественного языка) предварительная обработка является еще более важным шагом, поскольку тексты, естественно, являются нечисловыми, неструктурированными и беспорядочными данными. Из-за этого предварительная обработка текста обычно включает в себя общие шаги, такие как очистка (удаление специальных символов, знаков препинания, стоп-слов и т. д.) и нормализация (приведение текста к нижнему регистру, выделение корней и лемматизация).

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

В этом посте простой API предварительной обработки текста создается на Python с использованием библиотеки FastAPI. В этом примере мы будем использовать RegEx (регулярные выражения) для нормализации текстового «шума», но представленные концепции можно легко распространить на более сложные приложения.

Обзор ReGex в Python

Regex — это структурированная строка, созданная для выражения универсального текстового шаблона, используемого для поиска терминов в тексте. «Regex — очень мощный инструмент в приложениях НЛП, и он определенно заслуживает внимания, но в этом посте не будут рассматриваться все детали его реализации, а только функциональные возможности.

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

Адрес электронной почты — хороший пример распространенного шаблона. Все они имеют символ «@» и заканчиваются точкой, например, [email protected] или [email protected]. Регулярное выражение позволяет нам описать этот шаблон структурированным однозначным способом. Для этого примера это будет примерно так:

r"\w+\@\w+(?:\.\w+)+"

Это регулярное выражение не идеально, но оно будет работать в большинстве случаев.

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

Выход:

> ['[email protected]', '[email protected]']

Но как это может помочь с предварительной обработкой текста?

Модуль regex может быть полезен при нормализации текста с помощью функции замены. Эта функция позволяет нам найти шаблон и заменить его некоторым предопределенным текстом. Таким образом, мы можем представить концепцию в тексте более осмысленным уникальным способом (что может еще больше повысить производительность модели машинного обучения).

Выход:

This is a valid email address:  <EMAIL>  
This is another valid email address:  <EMAIL>  
This is not: antunes@@abc.br

Что такое микросервис?

Микрослужба – это небольшое приложение, отвечающее за очень специфическую задачу в системе. Он работает независимо и изолирован от других приложений, а также самодостаточен в ресурсах.

После запуска микросервис можно использовать с помощью вызовов API на его открытых конечных точках. Мы будем использовать FastAPI, веб-фреймворк Python для простой реализации API с минимальным кодом, для создания конечных точек наших микросервисов.

Этот пост также не будет углубляться во все детали API и HTTP-запросов, но предлагаемое приложение очень простое и должно быть понятным.

СОВЕТ: Docker — важный инструмент в разработке программного обеспечения, тесно связанный с концепцией микросервиса, поэтому его стоит проверить.

Выполнение

Настройка среды

Первое, что нужно сделать, это создать изолированную среду Python только с необходимыми зависимостями. Вы можете использовать Anaconda или PyEnv.

После создания среды установите следующие пакеты:

fastapi
uvicorn[standard]
requests

uvicorn[standard]: локальный сервер для размещения запросов API
:библиотека Python для выполнения HTTP-запросов
fastapi: пакет FastAPI

Создание нашей первой конечной точки API

Мы взаимодействуем с API, отправляя запросы на его открытые конечные точки. В контексте веб-API конечные точки отображаются в URL-адресах.

Приложение/лицо, использующее службу API, называется клиентом и может взаимодействовать с конечной точкой с помощью HTTP-запросов, таких как GET, POST или PUT. Каждый из этих запросов имеет предопределенное поведение. Например, GET можно использовать для извлечения элемента из базы данных, а POST — для вставки.

Следующий пример был основан на официальной странице FastAPI.
Создайте файл main.py со следующим кодом:

Затем в терминале запустите:

uvicorn main:app --reload

Аргумент «перезагрузка» используется только для разработки, не используйте его для производства.

Откройте браузер по адресу https://127.0.0.1:8000/, и вы должны увидеть следующий ответ:

{"Hello":"World"}

Поздравляем, вы создали свой первый API!

Итак, давайте разбираться, что происходит.

  • Переменная app ссылается на приложение API, которое будет запущено;
  • «uvicorn main:app --reload» запускает сервер, используя переменную app из файла main.
  • По умолчанию API работает на localhost с портом=8000 (https://127.0.0.1:8000). Это корень, то есть все конечные точки будут путями от него, например https://127.0.0.1:8000/do/something/
  • декоратор app.get("/")связывает путь "/" с функцией read_root при выполнении запроса GET.
    Это означает, что при выполнении запроса GET по адресу https://127.0.0.1:8000/ (обратите внимание на «/» в конце) вызывается функция read_root и возвращается отправляется обратно в качестве ответа.
  • Когда ваш браузер открывает https://127.0.0.1:8000/, он делает запрос GET по ссылке и показывает ответ.

Получение данных в конечной точке

Создание конечной точки для получения информации не так уж отличается от того, что мы делали ранее. Основное отличие состоит в том, что функция также должна будет получать параметры. Например, конечная точка ниже получает два параметра:

@app.get("/example/") 
def read_item(id: int, name: string): 
    return {"your_id": id, "your_name": name}

Эта информация отправляется клиентом по запросу в формате JSON (подробно далее), как показано ниже:

{ "id":123, "name": "Joao" }

Самое интересное в этом то, что FastAPI автоматически проверяет данные для нас. Таким образом, если клиент отправляет запрос с {"name":123} или вообще без имени, он вернет ошибку типа/поля. Помимо типов Python по умолчанию, FastAPI также поддерживает проверку классов Pydantic.

Проверка входных данных с помощью Pydantic

Pydantic — более надежный способ проверки данных. Это позволяет нам описать ожидаемый ввод (модель) с помощью классов Python, задав обязательные поля, допустимые интервалы и значения, необязательные параметры и больше. Например, следующий класс описывает, какие значения должен иметь Person.

Затем этот класс можно вставить в поле параметров функции, как и нативные типы Python, описанные в предыдущем примере.

Создание нашей конечной точки предварительной обработки

Теперь наконец пришло время реализовать сам API.

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

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

Подводя итог, нам нужно реализовать:

  1. Функция предварительной обработки текста.
  2. Модель проверки ввода для конечной точки.
  3. Конечная точка, которая получит текст и список шагов предварительной обработки и вернет предварительно обработанный текст.

Начнем с функции предварительной обработки текста. Как упоминалось ранее, мы будем использовать регулярное выражение для нормализации текстов. В следующем коде показана реализация нескольких классов, отвечающих за это. Класс BaseRegExPreprocessing действует как абстрактный класс. Каждый унаследованный класс переопределяет regex и replace_token со своими значениями, представляющими функциональность системы.

Проверка ввода очень проста, нам просто нужно создать класс, описывающий, как должны выглядеть данные, отправленные клиентом. Следующий код показывает эту реализацию.

Класс StringTransformation перечисляет все допустимые значения переменной steps в классе PreprocessingRequest, каждое из которых представляет одну функцию. PreprocessingRequest — основной класс, он описывает, как должны выглядеть отправляемые данные.

Наконец, мы можем собрать все это вместе в основном приложении FastAPI.

Затем просто запустите сервер с помощью uvicorn.

Тестирование на некоторых примерах

Чтобы правильно протестировать наш API, мы будем использовать библиотеку запросов python.

В первом примере будет замена всех телефонных номеров из строки.

Прежде чем увидеть результат ответа, давайте просмотрим код.

данные — это информация, которую мы отправляем в API. Он отформатирован, как описано в классе pydantic: поле «текст» с текстом для предварительной обработки и поле «шаги» со списком шагов предварительной обработки. Он передается в метод get() как json.

request.get( ) отправляет HTTP-запрос GET на https://localhost/preprocess/, который является URL-адресом нашей конечной точки.

Возвращенный вывод можно получить, вызвав response.json().

Одна из прелестей API заключается в том, что клиент не имеет абсолютно никакого отношения к приложению. Наш клиент написан на python, но это может быть приложение C++, веб-браузер или что-то еще, что может делать HTTP-запросы.

На самом деле, еще один способ проверить конечные точки — получить доступ к пути https://127.0.0.1:8000/docs на localhost. Этот путь указывает на автоматическую документацию FastAPI, создающую итеративное окно для выполнения запросов.

Давайте закончим более сложным примером, который исследует многие функции системы:

Выход:

Заключение

В этом посте мы создадим API для нормализации текста, используя регулярное выражение Python и FastAPI. Мы рассмотрели возможности регулярных выражений для нормализации текстов, важного процесса в приложениях НЛП, и описали, как этот процесс можно инкапсулировать и распространять с помощью концепции микросервисови APIs. Несмотря на то, что это простое приложение, оно продемонстрировало фундаментальные концепции, которые можно распространить на более сложные случаи.

Все темы, обсуждаемые в тексте, были кратко раскрыты, чтобы сделать пост небольшим и позволить нам быстрее двигаться в направлении основной цели. Чтобы создать более прочную основу, ознакомьтесь с ссылками ниже :)

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

Спасибо за чтение! ;)

Рекомендации

Код на Github: https://github.com/jaumpedro214/posts/tree/main/text_pre_fast_api

[1] Youtube-канал CodingEntrepreneurs, Учебное пособие по Python и FastAPI: создание микросервиса ИИ для извлечения текста из изображений.
[2] Аашиш Наир, Регулярные выражения: швейцарский нож для анализа текста. На Medium, к науке о данных.
[3] Youtube-канал AmigosCode, Учебное пособие по FastAPI — создание RESTful API с помощью Python
[3] Что такое REST API?. На Red Hat.
[4] Методы HTTP-запросов. В веб-документах MDN
[5] Официальная документация Fast API.
[6] Официальная документация Pydantic