В этой серии статей описывается, как обнаруживать и нормализовать временные выражения (выражения даты) в тексте на французском языке. В этой статье, последней в серии, описывается, как создать небольшое веб-приложение для решения этой проблемы. Приложение состоит из серверной части, написанной с помощью Python FastApi; интерфейс на Javascript. Мы не будем вдаваться в подробности о Javascript или внешнем интерфейсе. Вместо этого мы кратко опишем задачи, отвечающие за внешний интерфейс; затем мы покажем вам, как выглядит веб-страница.
5. Демонстрационное приложение
5.1 Пример использования
Предположим, у нас есть документы наших клиентов в нашей базе данных. Такими документами могут быть платежные сертификаты (для медицинской страховки), отчеты о действиях пользователей, пользовательская история торгов и т. д. Наши клиенты могут отправить нам сообщение по электронной почте или в Центр поддержки с просьбой предоставить свои документы, соответствующие периоду.
- "Возьмите резюме по транзакциям в прошлом году".
- "Требуется сертификат на 3 последних срока службы svp!"
- "Je voudrais requireer un document pour décembre et janvier derniers svp."
- Документ Pouvez-vous m’envoyer un document pour février à mars 2020 et depuis le mois d’octobre 2021 svp ?
- Документ, который может быть отправлен мне, для того, чтобы semaine prochaine svp ?
Мы хотели бы иметь инструмент для преобразования всех этих требований в существенный период. Например, предположим, что сегодня 21 февраля 2022 года, тогда ответом на эти запросы должны быть следующие полузамкнутые интервалы (в формате ГГГГ-ММ-ДД):
[2022-02-21, 2022-02-22)
,[2021-11-21, 2022-02-22)
,[2021-12-01, 2022-01-01)
и[2022-01-01, 2022-02-01)
(или[2021-12-01, 2022-02-01)
, если мы объединим эти два интервала)[2020-02-01, 2020-04-01)
и[2021-10-01, 2022-02-02)
[2022-02-22, 2022-03-02)
5.2 Демонстрационное приложение
В следующем GIF мы представляем такое приложение.
Пользователь может ввести любой текст на французском языке в текстовом поле в левой половине экрана. Следующие разделы появятся в правой половине, когда они нажмут на «Посланник» (Отправить на французском языке).
- (1) Графическое представление
- (2) Прогноз по модели машинного обучения
- (3) Прогноз по модели машинного обучения (в формате кортежа)
- (4) Выведенные периоды
Рабочий процесс следующий.
ML Model (backend) -> (2) -> Convert to an object (like JSON) -> (3) -> Post process to retrieve absolute dates -> (4) -> Represent with graphics -> (1)
Точнее,
- (2): мы извлекаем необработанные выходные данные из модели машинного обучения, которая представляет собой наши знаменитые нормализованные временные выражения, определенные в статье 2 и обученные, как описано в статье 3.
- (3): тот же необработанный вывод, что и (2), но переписанный в формате структурированного объекта для лучшей обработки машиной.
- (4): объекты в (3) подвергаются постобработке путем обращения к текущему дню для получения правильных периодов.
- (1): Мы представляем объекты в (4) в виде удобных для пользователя графиков благодаря доступным библиотекам.
Раздел (1) предназначен для конечных пользователей, а (2), (3), (4) больше предназначен для разработчиков, чтобы понять рабочий процесс.
5.3 Реализация: серверная часть
Серверная часть приложения отвечает за получение запроса пользователя (некоторый свободный текст) и вызов модели машинного обучения для возврата прогнозов (то есть списка нормализованных временных выражений). Следовательно, нам нужно написать один API для этой цели. Мы хотели бы иметь такой API:
(Если вы знакомы с FastAPI, на приведенном выше рисунке показана известная документация Swagger, связанная с нашим приложением FastAPI).
Другими словами, мы пишем API, чтобы любой POST
запрос к пути /api/v1/temporal_expressions
в объекте JSON, содержащем запрос пользователя в поле «texts
», должен был получить ответ, содержащий временные выражения в поле «preds
», например:
{
"preds": [
"REL DIR - CURRENT D0"
],
"context": {
...
}
}
(Некоторая дополнительная информация о времени обработки, коде состояния и т. д. может быть добавлена в context
. В любом случае они не являются основными.)
Пишем API в одном main.py
файле:
5.4 Реализация: внешний интерфейс
Серверная часть возвращает только нормализованные выражения (например, REL DIR - CURRENT D0
). Все задачи постобработки в потоке:
ML Model (backend) -> (2) -> Convert to an object (like JSON) -> (3) -> Post process to retrieve absolute dates -> (4) -> Represent with graphics -> (1)
(упомянутые в разделе 5.2) делегированы внешнему интерфейсу (все написаны на TypeScript). Кратко опишу алгоритмы для каждого шага и дам ссылку на исходный код:
- 5.4.1. Преобразование нормализованных выражений в объекты JSON. Мы преобразуем такие строки, как
ABS DIR - PAST M2
в объект как
{
"type": "ABS",
"value": [
{
"unit": "M",
"value": 2
}
],
"mode": "DIR",
"tense": "PAST"
}
Алгоритм прост: разбиваем строку на элементы и ищем в словаре:
{
ABS: "type",
REL: "type",
DUR: "type",
FREQ: "type",
NONE: "type",
DIR: "mode",
IND: "mode",
FROM: "anchor",
TO: "anchor",
BEFORE: "anchor",
AFTER: "anchor",
PREV: "tense",
NEXT: "tense",
PAST: "tense",
FUTURE: "tense",
CURRENT:"tense",
START: "partial",
MID: "partial",
END: "partial",
LESS: "approximation",
MORE: "approximation",
APPROX: "approximation",
FIRST: "ordinal",
LAST: "ordinal"
}
Если термин присутствует в словаре, поместите его в соответствующее поле (например, «время»: «ПОСТ»). В противном случае проверьте, имеет ли он формат единица + число, затем поместите эти значения в поле «значение» (например: «M10 D7» должно стать «value: [{unit: M, value: 10}, {unit: D, value: 7}]
».
Исходный код: Функция getNormalizedTempExp
в этом файле.
- 5.4.2 Постобработка для получения абсолютных дат: чтобы получить окончательные даты из временных выражений и исходной даты (например, сегодня): никакого волшебства, нам нужно рассмотреть каждый отдельный случай
type
,tense
иvalue
, как описано в таблице в конце раздела 3.
Исходный код: Функция getRealDate
в этом файле.
Обратите внимание, что мы не обрабатываем ключевые слова. BEFORE
, AFTER
(для анкеров); START
, MID
, END
(для частичного); LESS
, MORE
, APPROX
(для приближения) здесь. Кроме того, мы не имеем дело со временем (час, минута, секунда) и днями недели, как указано в разделе 2. Понятие «первая, вторая неделя в месяце» также лениво представлено как «день с 1 по 7», "день с 8 по 14" соответствующего месяца, тогда как мы должны изучить его более внимательно.
- 5.4.3 Графическое представление: Наконец, для представления периодов под графиком мы используем временные шкалы библиотеки apexcharts. Библиотека поддерживает фреймворки Angular, ReactJS и VueJS, а также чистый JS. Можете посмотреть, если интересно.
Резюме
Мы подошли к концу серии «Обнаружение и нормализация темпоральных выражений во французском тексте». Мы надеемся, что дорожная карта, которой мы следовали, понятна нашим читателям: создание набора данных с нуля, определение формата этикетки и аннотации, моделирование (обучение) и создание приложения для практического применения. Некоторая идея обобщения по теме с нашей стороны продолжается: более интересные варианты использования, связи между временем и временем или временем и событиями — мы надеемся вскоре увидеть вас в следующей серии.
Ссылки
- [1] FastAPI — https://fastapi.tiangolo.com/
- [2] Хронология Apexcharts — https://apexcharts.com/angular-chart-demos/timeline-charts/advanced/
Подтверждение
Спасибо нашим коллегам Al Houceine KILANI и Ismail EL HATIMI за рецензию на статью.
О
Нхут ДОАН НГУЕН работает специалистом по данным в La Javaness с марта 2021 года.