TL;DR
Исследование показывает, как размечать эмоции в отзывах: берёте ту же инструкцию, по которой работали бы живые разметчики, и отдаёте её LLM. В инструкции три части: определения эмоций, правила разграничения похожих (когда это «гнев», а когда «отвращение») и примеры. Модель получает предложение, полный отзыв как контекст и возвращает набор эмоций в JSON.
Главная находка: на маленькой разметке (около тысячи предложений) обычный промптинг сильно обходит дообучение классических моделей. Лучший промпт дал macro-F1 0,642 (средняя точность по всем эмоциям, где редкие весят столько же, сколько частые). Дообученные «энкодеры» (BERT-подобные модели) дали 0,39–0,45. Эмоции в отзывах распределены неравномерно: «радость» и «грусть» встречаются постоянно, «страх» и «гнев» почти не встречаются. Классический классификатор на таких данных редких эмоций просто не замечает. Промпт с определениями и примерами не зависит от того, сколько раз эмоция попалась в обучающей выборке.
Суть метода в трёх режимах. Первый: zero-shot, только определения и инструкции. Второй: few-shot по инструкции, то же плюс примеры из неё. Третий: few-shot + свои примеры, до пяти размеченных предложений на каждую эмоцию. Каждый режим добавляет к предыдущему.
Схема метода
ШАГ 1: Собрать инструкцию разметки (определения 8 эмоций + «Нейтрально»,
правила разграничения, примеры) → текст инструкции
ШАГ 2: Выбрать режим:
A) только определения и правила (zero-shot)
B) + примеры из инструкции (few-shot)
C) + до 5 ваших размеченных предложений на эмоцию (few-shot+)
ШАГ 3: Подать предложение + полный отзыв как контекст → JSON с набором эмоций
(минимум одна, максимум три)
ШАГ 4: Температура 0 (в исследовании — значение по умолчанию)
Всё делается в одном промпте. Для потока отзывов запрос повторяется на каждое предложение.
Пример применения
Задача: Продакт приложения доставки продуктов вроде «ВкусВилл» или «Самоката» выгрузил из RuStore и Google Play 300 отзывов после обновления. Оценка «1 звезда» ничего не говорит о том, злятся люди или разочарованы. Ему нужно понять, где гнев (сломали заказ, не вернули деньги), где грусть и разочарование (любимая функция пропала), а где предвкушение («жду, когда добавят оплату СБП»). Первых надо разбирать срочно.
Промпт:
Ты размечаешь эмоции в предложениях из отзывов на мобильное приложение
доставки продуктов. Работай строго по инструкции ниже.
<Эмоции>
Радость — пользователь доволен результатом или функцией.
Пример: «Курьер приехал за 15 минут, супер!»
Доверие — пользователь полагается на приложение, считает его надёжным.
Пример: «Заказываю тут уже три года, ни разу не подвели.»
Страх — пользователь опасается последствий (потеря денег, данных).
Пример: «Боюсь привязывать карту, после обновления списали дважды.»
Удивление — неожиданное событие, хорошее или плохое.
Пример: «Не ожидал, что после обновления пропадёт история заказов.»
Грусть — разочарование из-за утраты или недоступности.
Пример: «Жаль, что убрали любимую подборку.»
Отвращение — отторжение продукта, нежелание им пользоваться.
Пример: «Мерзкий интерфейс, удалил и не вернусь.»
Гнев — раздражение, обвинение, враждебность к приложению или компании.
Пример: «Третий раз отменяют заказ и не возвращают деньги!»
Предвкушение — ожидание функции или улучшения.
Пример: «Скорей бы добавили оплату через СБП.»
Нейтрально — нет эмоции, констатация факта.
Пример: «Обновил приложение до версии 5.2.»
Эмоции>
<Правила_разграничения>
- Гнев — направлен на кого-то и требует действия; отвращение — отторжение
без требования что-то исправить.
- Грусть — сожаление об утрате; гнев — обвинение виноватого.
- Если эмоции нет, а есть факт или баг-репорт без оценки — «Нейтрально».
Правила_разграничения>
<Дополнительные_примеры>
«Приложение вылетает при оплате, я в ярости» → ["Гнев"]
«Классная идея с подписками, надеюсь, добавите ещё скидки» → ["Радость", "Предвкушение"]
Дополнительные_примеры>
<Формат>
Верни JSON: {"emotions": [...]}. Минимум одна метка, максимум три.
Используй только метки из списка выше. Без пояснений.
Формат>
<Полный_отзыв>
{полный_отзыв}
Полный_отзыв>
<Предложение>
{предложение}
Предложение>
Результат: Для каждого предложения модель вернёт короткий JSON с одной-тремя эмоциями, без пояснений. Большинство предложений получат одну метку. Это соответствует реальным данным: в исследовании 86% предложений несут ровно одну эмоцию. Дальше продакт считает долю «гнева» и «страха» по темам и разбирает их первыми. Редкие эмоции придётся проверить вручную: именно на них модели ошибаются чаще.
Почему это работает
Слабость обучаемых классификаторов. Маленькая дообученная модель учится только на примерах. Редкая эмоция («страх» встречается единицами) — мало примеров, и модель вообще её не предсказывает. Чтобы это исправить, нужны выравнивание обучения, синтетические данные и GPU. Читателю это недоступно.
Сильная сторона LLM. Модель уже знает, что такое страх, гнев и разочарование, из предобучения. Ей нужно только объяснить границы ваших категорий: чем «отвращение» отличается от «гнева» именно в отзывах на приложения. Это делают определения и правила разграничения. Примеры показывают, как выглядит граница на реальном тексте.
Как метод это использует. Вы не обучаете модель на частоте эмоций. Вы описываете задачу так, как описали бы новому разметчику. Редкая эмоция получает такое же описание и такие же примеры, как частая. Поэтому разрыв в качестве между редкими и частыми классами сжимается.
Рычаги управления: - Режим (A → B → C): добавляйте примеры, если модель путает соседние эмоции. Режим C берёт примеры из вашей же разметки. - Число примеров: в исследовании до пяти на эмоцию. Больше не значит лучше, и в доступной части статьи не показано, что именно прирастает. - Контекст: полный отзыв вместе с предложением помогает понять, на что направлена эмоция. - Температура 0: в исследовании это значение по умолчанию для основных результатов, ответы стабильнее. Её чувствительность тоже проверяли. - Лимит меток (1–3): подгоняйте под свои данные. Здесь потолок взят из реальной разметки, где больше трёх эмоций не встречалось.
Шаблон промпта
Ты размечаешь эмоции в {тип_текста}. Работай строго по инструкции.
<Эмоции>
{Название_эмоции_1} — {определение}.
Пример: «{пример_1}»
{Название_эмоции_2} — {определение}.
Пример: «{пример_2}»
...
Нейтрально — нет эмоции, констатация факта.
Пример: «{пример_нейтрального}»
Эмоции>
<Правила_разграничения>
- {эмоция_А} vs {эмоция_Б}: {в чём разница}
- {ещё_правило}
Правила_разграничения>
<Дополнительные_примеры>
«{размеченное_предложение_1}» → {метки_1}
«{размеченное_предложение_2}» → {метки_2}
(до 5 на каждую эмоцию)
Дополнительные_примеры>
<Формат>
Верни JSON: {"emotions": [...]}. Минимум одна метка, максимум {макс_меток}.
Только метки из списка. Без пояснений.
Формат>
<Контекст>{полный_текст}Контекст>
<Предложение>{предложение}Предложение>
Что подставлять: {тип_текста} — отзывы, письма в поддержку, комментарии. Эмоции с определениями берите из своей инструкции или из набора Плутчика. {макс_меток} выставляйте по своим данным. Блок «Дополнительные примеры» — режим C, его можно убрать (режим B) вместе с примерами в списке эмоций (режим A).
🚀 Быстрый старт — вставь в чат:
Вот шаблон классификатора эмоций с определениями, правилами разграничения
и примерами. Адаптируй под мою задачу: {опиши, какие тексты размечаешь и зачем}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие тексты вы размечаете, какие эмоции важны бизнесу, какие пары вы путаете и есть ли у вас размеченные примеры. Это нужно, чтобы написать определения и правила разграничения под ваш домен: без них метод не работает.
Ограничения
⚠️ Скромный потолок качества: лучший результат — это 0,642 macro-F1. Авторы сами называют его скромным. Эмоции субъективны, и часть предложений модель разметит иначе, чем человек. Для решений с высокой ценой ошибки нужна выборочная проверка людьми.
⚠️ Редкие эмоции остаются слабым местом: «страх», «гнев», «отвращение» встречаются реже всего, и именно на них ошибки самые заметные. Их нужно проверять в первую очередь.
⚠️ Только английские отзывы, один набор данных: проверяли ~1100 предложений на английском из Google Play. Как это работает на русском, исследование не показывает. Для русских отзывов нужна своя проверка на 50–100 предложениях.
⚠️ Нужна инструкция разметки: метод работает, потому что у авторов уже была подробная инструкция с определениями, правилами и примерами. Без неё придётся написать её самому, и качество будет зависеть от неё.
⚠️ Объём и цена: если у вас десятки тысяч отзывов в день, запросы к большой модели дороги и медленны. Авторы показали, что дообученные энкодеры (с генерацией синтетических данных и усиленным весом редких классов) почти догоняют промптинг и работают на порядки быстрее. Но это уже инженерный путь.
⚠️ Усечённый текст: в доступной части статьи нет разбивки по режимам A/B/C и по моделям. Какой из режимов лучший и насколько каждый следующий добавляет, здесь не видно.
Как исследовали
Исследователи взяли готовый набор: 1090 предложений из отзывов на 257 приложений в Google Play, размеченных пятью людьми по восьми эмоциям Плутчика плюс «Нейтрально». Эмоции распределены резко неравномерно: «радость» и «грусть» частые, «страх» и «гнев» редкие. Сравнили два пути. Первый — дообучение BERT-подобных моделей (в двух схемах: одна модель на все эмоции или отдельная на каждую). Второй — промптинг десяти LLM, и закрытых (в том числе gpt-5.2), и открытых, запущенных локально. Промпты строили прямо из инструкции для разметчиков в трёх режимах. Проверяли десятикратной кросс-валидацией, главная метрика — macro-F1, потому что она не даёт частым эмоциям «перекрыть» редкие.
Результат: лучший промптинг дал 0,642, а дообученные модели без доработок — 0,387 (одна модель) и 0,450 (ансамбль). Причина в том, что на ~1000 примерах с перекосом классов дообучаемая модель не успевает выучить редкие эмоции. Затем авторы пробовали чинить энкодеры: генерировали синтетические отзывы для редких эмоций и усиливали вес редких классов в функции потерь. Это закрыло большую часть разрыва (+0,204), и такие модели оказались быстрее промптинга до трёх порядков. Неожиданность: редкие эмоции выиграли больше всего (до +0,501 F1, раньше их вообще не находили).
Практический вывод для читателя: если нет ни GPU, ни времени на инженерию, достаточно хорошей инструкции в промпте. Дообучение имеет смысл, только когда счёт идёт на огромные потоки.
Адаптации и экстраполяции
🔧 Техника: правило «минимум 1, максимум 3» → меньше пустых ответов и мусорных меток
В исследовании это правило было частью постобработки: если ни одна эмоция не прошла порог, брали самую уверенную, а больше трёх не оставляли. В промпте этого можно добиться прямой фразой: «Верни минимум одну метку, максимум три. Если сомневаешься, выбери самую вероятную». Так вы повторяете логику авторов текстом, без кода.
🔧 Техника: свои примеры из ошибок → точнее на ваших данных
Прогоните 50 предложений, найдите, где модель путает «гнев» и «отвращение», и добавьте эти случаи в блок «Дополнительные примеры» с верной меткой. Это работает как режим C, только примеры выбираете вы. Приём не из статьи, но это логичное применение её режима «гайдлайн + размеченные предложения».
Экстраполяция: тот же подход для писем в поддержку.
Ты размечаешь эмоции в письмах клиентов службы поддержки интернет-банка.
Эмоции: Гнев, Страх, Грусть, Доверие, Предвкушение, Нейтрально.
Правила: «Страх» — клиент боится потерять деньги или доступ; «Гнев» — клиент
обвиняет банк. Если есть угроза уйти к конкуренту — обязательно «Гнев».
Верни JSON: {"emotions": [...], "срочно": true/false}.
Здесь добавлено поле «срочно», чтобы сразу выделять письма для первой очереди. Это моя вариация, в исследовании её нет.
Ресурсы
- Fine-Grained Emotion Classification from Mobile App Reviews: An Empirical Study with Large Language Models, Quim Motger, Carlota Catot, Marc Oriol, Universitat Politècnica de Catalunya (Испания). Препринт Elsevier.
- Набор данных и инструкция разметки: Motger et al. (2025b), 1090 предложений, 257 приложений, Google Play.
- Таксономия: восемь базовых эмоций Плутчика (Plutchik, 2001).
- Авторы выложили код, промпты, синтетические корпуса и дообученные модели (пакет для воспроизведения и Hugging Face).
