Начну с того, что последние 3 месяца я стажировалась в лаборатории искусственного интеллекта ООО "ОЦРВ" в группе обработки естественного языка. За это время успела поучаствовать в разработке системы сентимент-анализа для компании. В этой статье расскажу как вижу эту задачу я, что делала и с какими проблемами пришлось столкнуться.
Давайте разберёмся что такое сентимент-анализ
Сентимент-анализ (включая анализ тональности) - это процесс определения тональности текста, выраженной в нем эмоциональной окраски. То есть способность системы распознавать и анализировать эмоции и настроения, выраженные в тексте. Программа определяет оттенок эмоций, выраженных в нем. Он может быть как позитивным (радость, удовлетворение), так и негативным (гнев, разочарование) или нейтральным (ничего особенного, просто информация).
Для того, чтобы правильно распознать эмоцию программа использует не только слова, но и контекст. Она должна понимать каждую мелочь в тексте, чтобы начать определять эмоции так же хорошо, как человек. Отдельная задача сентимент-анализа, как вы понимаете, состоит в определении сарказма. Так "Прекрасный сервис, жить без него не могу" на деле может оказаться не там и прекрасным.
Итак, сентимент-анализ нужен для того, чтобы автоматизировать процесс понимания эмоций людей. А теперь, почему это важно для компаний и как это вообще применимо. Использование сентимент-анализа может оказаться важным инструментом в управлении персоналом и повышении качества рабочей среды. Он может использоваться как для мониторинга эмоционального состояния одного работника, так и для определения уровня удовлетворенности сотрудников. Использование сентимент-анализа может улучшить внутреннюю коммуникацию между сотрудниками и отделами. Также сентимент-анализ применим для отслеживания физического состояния работника, так как оно непосредственно взаимосвязано с эмоциональным. Использование сентимент-анализа в связке с данными о физической активности, сне, питании и других факторах может помочь выявить связь между эмоциональным состоянием и образом жизни человека. Например, изменения в настроении могут отражаться на уровне физической активности или качестве сна сотрудника. Собирая эмоции и отзывы клиентов, можно наблюдать за удовлетворенностью клиентов сервисом.
Задача
Основная задача состояла в обучении модели машинного обучения, которая смогла бы классифицировать фразы на положительные, отрицательные и нейтральные. Здесь отмечу разницу между определением тональности текста и сентимент анализом - в глубине. Определение тональности ограничивается простой классификацией текста на положительный, отрицательный и нейтральный на основе ключевых слов. Это может быть полезным для быстрой оценки общего настроения текста, но оно не учитывает контекст, сарказм и другие нюансы, которые могут влиять на истинное значение высказывания. По сути наша задача так и звучит. В случае же сентимента, анализ проводится более сложными алгоритмами и классификация происходит на уровне ниже. То есть с его помощью уже можно определить что конкретно испытывает человек - грусть, радость, страх, сожаление и тд.
Работа началась с сбора датасета и разметки. Нужно было собрать высказывания от диспетчеров, машинистов, ремонтников, управляющих служб и тд. Далее фразы размечали в Label Studio на три класса по тональности - положительные, отрицательные, нейтральные. Примерно так это выглядело:
Данные собирали с разрешенных авторами сайтов, YouTube. Основной трудностью при разметке была неоднозначность и неявная тональность. Также в процессе подготовки датасета все сильнее наблюдался сильный дисбаланс между классами. Большинство фраз были нейтральными, что создавало неравновесие в обучающих данных. Соответственно нам пришлось синтезировать положительные и негативные высказывания, чтобы уравновесить количество примеров каждого класса. Это позволило улучшить будущую модель сентимент анализа.
Про модель - ее писала не я, а мой коллега. Он взял RuGPT3 в качестве основы для нашей модели сентимент-анализа. Эта модель была предварительно обучена на подготовленном нами датасете и была готова для дальнейшего использования в рамках нашей задачи.
Бот на Rasa
Следующий этап - интеграция модели с пользовательским интерфейсом. Для этого решили использовать библиотеку Rasa, специально предназначенную для разработки ботов с машинным обучением. Она позволила создать удобный интерфейс для взаимодействия с нашей моделью сентимент-анализа.
По поводу зависимостей - для создания я использовала Python версии 3.8 и Rasa версии 3.1, так как они наилучшим образом взаимодействуют друг с другом. Сейчас я попробую подробно описать процесс разработки.
Начало проекта
Итак, создаем новый проект со своей виртуальной средой, устанавливаем Rasa и создаем необходимую структуру каталогов и файлов для чат-бота:
pip install rasa==3.1
rasa init
При инициализации бота создается директория с проектом и нужной структурой файлов, также предварительно обучаем модель, если она попросит. Переходим к наполнению файлов.
Структура проекта
Созданная структура проекта 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
sunsexsurf
в пост призывается ваш коллега, чтобы рассказать про то, что он с RuGPT делал.