Sentiment Analysis Bot на Rasa 3.1

Начну с того, что последние 3 месяца я стажировалась в лаборатории искусственного интеллекта ООО «ОЦРВ» в группе обработки естественного языка. За это время успела поучаствовать в разработке системы сентимент-анализа для компании. В этой статье расскажу как вижу эту задачу я, что делала и с какими проблемами пришлось столкнуться.

Давайте разберёмся что такое сентимент-анализ

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

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

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

Схема сентимент-анализа

Схема сентимент-анализа

Задача

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

Работа началась с сбора датасета и разметки. Нужно было собрать высказывания от диспетчеров, машинистов, ремонтников, управляющих служб и тд. Далее фразы размечали в Label Studio на три класса по тональности — положительные, отрицательные, нейтральные. Примерно так это выглядело:

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

Про модель — ее писала не я, а мой коллега. Он взял RuGPT3 в качестве основы для нашей модели сентимент-анализа. Эта модель была предварительно обучена на подготовленном нами датасете и была готова для дальнейшего использования в рамках нашей задачи.

Бот на Rasa

Следующий этап — интеграция модели с пользовательским интерфейсом. Для этого решили использовать библиотеку Rasa, специально предназначенную для разработки ботов с машинным обучением. Она позволила создать удобный интерфейс для взаимодействия с нашей моделью сентимент-анализа.

d5e31216efd94e8e7cd385f9e7743b63.jpg

По поводу зависимостей — для создания я использовала Python версии 3.8 и Rasa версии 3.1, так как они наилучшим образом взаимодействуют друг с другом. Сейчас я попробую подробно описать процесс разработки.

Начало проекта

Итак, создаем новый проект со своей виртуальной средой, устанавливаем Rasa и создаем необходимую структуру каталогов и файлов для чат-бота:

pip install rasa==3.1
rasa init

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

Структура проекта

Созданная структура проекта Rasa обычно включает в себя такие основные элементы:

структура проекта в Rasa

структура проекта в Rasa

  • nlu.yml — файл с намерениями пользователя (интентами)

  • rules.yml — определения правил взаимодействия модели с пользователем

  • stories.yml — описания различных сценариев диалогов 

  • actions.py — содержит определения кастомных действий

  • models/ — хранит обученные модели

  • config.yml — параметры конфигурации для моделей

  • domain.yml — информация о намерениях, сущностях, ответах бота и правилах поведения агента диалога

  • endpoints.yml — настройки внешних сервисов

  • credentials.yml — файл конфигурации проекта

nlu.yml

Intent — это намерение пользователя, выраженное в его сообщении. Для их определения мы используем файл data/nlu.yml. Например, часть фраз нашего датасета — сообщение машиниста диспетчеру о своем местоположении. Мы можем определить этот intent следующим образом:

- intent: place
  examples: |
    - Нахожусь на 174-м километре.
    - 106-й километр.
    - Софиевка, 148-й километр.
    - 171-й километр.
    - 3441, нахожусь на 144-м километре.

Подобным образом я расписала различные намерения из датасета. У меня их получилось около 20.

rules.yml

Сценарии диалога определяют, как бот должен реагировать на различные интенты пользователя. Пример:

 - rule: place
  steps:
    - intent: place
    - action: action_define_phrase

То есть на интент сообщения о местоположении, будет вызываться action обращения к модели классификации. О нем позднее. Подобные правила хранятся так же в файле data/stories.yml, но его в отличие отdata/rules.ymlзаполнять не обязательно, однако стоит это сделать для большей точности бота.

Обращение к модели

Для определения тональности фраз пользователей пропишем обращение к созданной нами модели как custom action в файле actions.py

class ActionDefinePhrase(Action):
    def name(self) -> Text:
        return "action_define_phrase"

    def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, 
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
        
        ...

        def main():
            # путь к модели
            model_path = '../rugpt3small_based_on_gpt2.bin'
            model, tokenizer = load_model(model_path)

            # получение последнего сообщения пользователя
            text = tracker.latest_message.get("text")

            # классификация
            sentiment_labels = ['Neutral', 'Positive', 'Negative']
            predictions = predict_sentiment(text, model, tokenizer)
            predicted_sentiment = sentiment_labels[np.argmax(predictions.cpu().numpy())]

            # конвертация результата
            if predicted_sentiment == 'Positive':
                result = "положительная"
            elif predicted_sentiment == 'Neutral':
                result = "нейтральная"
            else:
                result = "негативная"

            # вывод тональности пользователю
            dispatcher.utter_message(text=f"Я распознал фразу: {result}")
        
        ...

Заключение

В данной статье я постаралась представить основные аспекты сентимент-анализа. Кроме того, я поделилась своим личным опытом работы над этим проектом и описала вклад, который внесла в его реализацию.

Использованные материалы и полезные ссылки

https://www.twilio.com/docs/glossary/what-is-sentiment-analysis — сентимент-анализ
https://habr.com/ru/companies/simbirsoft/articles/539508/ — подход сентимент-анализа
https://github.com/divlv/rugpt3.git — модель RuGPT3
https://rasa.com — ссылка на Rasa
https://qudata.com/ml/ru/NLP_RASA.html — документация Rasa

© Habrahabr.ru