Skip to content

Репозиторий содержит решение задачи хакатона 'Hack&Change 2025' по треку 'ML / Web: Классификация тональности текстов от Правительства Москвы.' команды 'Gradient Tech'

Notifications You must be signed in to change notification settings

Ilia-Trof88/Hack_And_Change-Gradient_Tech

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Классификатор тональности отзывов

Решение задачи классификации тональности текстов от Правительства Москвы в рамках хакатона Hack&Change 2025.

Команда: Gradient Tech Капитан команды: Илья Трофимов


Описание проекта

Проект представляет собой систему автоматической классификации тональности отзывов на три класса:

  • 0 - Негативный отзыв
  • 1 - Нейтральный отзыв
  • 2 - Положительный отзыв

Реализованы три подхода к решению задачи:

  1. Дообученная модель RuBERT-tiny (cointegrated/rubert-tiny2)
  2. LLM-модель DeepSeek с промпт-инжинирингом
  3. LLM-модель GigaChat-2-Max с промпт-инжинирингом

Дополнительно разработан веб-интерфейс для удобной работы с классификацией и валидацией размеченных данных.


Результаты

Метрики качества моделей

Модель Accuracy F1-score (macro)
RuBERT-tiny (дообученная) 0.80 0.75
GigaChat-2-Max 0.75 0.73
DeepSeek 0.72 0.63

Лучший результат: дообученная модель RuBERT-tiny показала наилучшие метрики качества.


Этапы работы над проектом

1. Exploratory Data Analysis (EDA)

Проведен глубокий анализ предоставленных данных, в ходе которого были выявлены следующие проблемы:

  • Данные крайне разношерстные (11 различных источников: rureviews, geo, perekrestok, anime, kinopoisk, rusentiment, linis, ru-reviews-classification, sber, news, bank)
  • Присутствует значительный шум в данных
  • Неправильная разметка целевой переменной во многих случаях
  • Дисбаланс классов в различных источниках

Решение: Отобрано порядка 10 000 отзывов для повторной разметки с помощью LLM.

2. Разметка данных с помощью LLM

Для улучшения качества разметки использовалась модель GigaChat-2-Max:

Процесс разметки:

  • Отобраны образцы из различных источников (rureviews, geo, perekrestok, rusentiment, ru-reviews-classification, sber, bank)
  • Применена стратифицированная выборка для балансировки классов (по 1200 примеров из основных источников)
  • Проведена валидация размеченных данных через повторную классификацию
  • Дополнительно использованы данные из источников anime и kinopoisk для аугментации (добавлено ~4100 примеров для балансировки классов 1 и 2)
  • Создан чистый датасет для обучения моделей

Промпты для разметки: реализованы в config/model_prompts.py с четкими инструкциями по определению тональности и формату ответа.

3. Предобработка данных

Реализация: src/rubert_tiny_class.py

Выполнены следующие этапы предобработки:

  1. Приведение к нижнему регистру
  2. Удаление emoji
  3. Удаление знаков пунктуации
  4. Удаление цифр
  5. Удаление множественных пробелов
  6. Удаление стоп-слов (русский язык)

Важное наблюдение: Удаление стоп-слов незначительно снижает Accuracy (~5%), но повышает F1-score примерно на столько же.

4. Обучение моделей

RuBERT-tiny (Fine-tuning)

Дообучение модели cointegrated/rubert-tiny2:

Параметры обучения:

  • Базовая модель: cointegrated/rubert-tiny2
  • Количество классов: 3
  • Размер обучающей выборки: 6996 примеров
  • Размер тестовой выборки: 1750 примеров
  • Эпохи обучения: 3
  • Размер батча: 8
  • Максимальная длина последовательности: 300 токенов
  • Стратегия оценки: каждую эпоху
  • Метрика для выбора лучшей модели: eval_loss

Результаты на тестовой выборке:

  • Accuracy: 0.7977
  • F1-score (macro): 0.7504
  • Precision (macro): 0.76
  • Recall (macro): 0.75

Детальные метрики по классам:

  • Класс 0 (Негативный): Precision=0.87, Recall=0.91, F1=0.89
  • Класс 1 (Нейтральный): Precision=0.64, Recall=0.47, F1=0.54
  • Класс 2 (Положительный): Precision=0.78, Recall=0.86, F1=0.82

Сохраненная модель: model_training/my_final_model/

DeepSeek (LLM)

Классификация с использованием DeepSeek API и промпт-инженеринга:

  • Использован промпт из config/model_prompts.py с четкими инструкциями
  • Формат ответа: одна цифра (0, 1 или 2)
  • Протестировано на 525 примерах

Результаты:

  • Accuracy: 0.7219
  • F1-score (macro): 0.6334

GigaChat-2-Max (LLM)

Классификация с использованием GigaChat-2-Max API:

  • Использован тот же промпт из config/model_prompts.py
  • Формат ответа: одна цифра (0, 1 или 2)
  • Протестировано на 525 примерах
  • Время обработки: ~5:41 для 525 примеров (~1.54 it/s)

Результаты:

  • Accuracy: 0.7543
  • F1-score (macro): 0.7253

5. Разработка веб-интерфейса

Реализация: app.py, templates/

Создан Flask-based веб-интерфейс с возможностями:

Возможности интерфейса

Возможности сервиса

1. Классификация отзывов

  • Загрузка CSV файла с колонкой "text"
  • Автоматическая классификация тональности
  • Статистика по классам
  • Просмотр результатов в таблице

Выбор файла

2. Выбор модели

  • RuBERT-tiny (дообученная модель, доступна всегда)
  • DeepSeek (LLM, требует API ключ)
  • GigaChat-2-Max (LLM, требует API ключ)

Выбор модели

3. Результаты классификации

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

Результаты классификации

4. Редактирование результатов

  • Возможность изменения текста отзыва
  • Возможность изменения предсказанной тональности

Редактирование текста Изменение тональности

5. Валидация данных

  • Загрузка CSV с колонками "text" и "label"
  • Расчет метрик качества (Accuracy, F1-score, Precision, Recall)
  • Сравнение истинных и предсказанных меток
  • Визуализация ошибок классификации

Результаты валидации

6. Экспорт результатов

  • Выгрузка размеченных данных в формате CSV
  • Сохранение всех изменений и правок

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

.
├── app.py                      # Flask веб-приложение
├── requirements.txt            # Зависимости проекта
├── .env                        # API ключи (не в репозитории)
│
├── config/                     # Конфигурация
│   └── model_prompts.py        # Промпты для LLM моделей
│
├── src/                        # Исходный код
│   ├── rubert_tiny_class.py    # Класс для работы с RuBERT
│   ├── deepseek_model.py       # Класс для работы с DeepSeek
│   └── gigachat_model.py       # Класс для работы с GigaChat
│
├── scripts/                    # Вспомогательные скрипты
│   └── data_labeling.py        # Скрипты разметки данных
│
├── model_training/             # Обучение моделей
│   └── my_final_model/         # Веса обученной модели
│       ├── config.json
│       ├── model.safetensors
│       ├── tokenizer.json
│       └── ...
│
├── submissions/                # Файлы предсказаний
│   ├── deepseek_submission.csv
│   ├── gigachat_submission.csv
│   ├── rubert_submission.csv
│   └── test_data.csv
│
├── templates/                  # HTML шаблоны
│   └── index.html              # Главная страница веб-интерфейса
│
└── screenshots/                # Скриншоты интерфейса
    ├── service_capabilities.jpg
    ├── classification_stage_file_selection.jpg
    ├── model_selection.jpg
    ├── classification_result_without_validation.jpg
    ├── text_change_possibility.jpg
    ├── sentiment_change_possibility.jpg
    └── validation_result.jpg

Установка и запуск

Требования

  • Python 3.13
  • CUDA 12.4+ (для GPU поддержки PyTorch)

Установка зависимостей

pip install -r requirements.txt

Настройка API ключей (опционально)

Для работы с LLM моделями создайте файл .env в корне проекта:

# DeepSeek API
deepseek_api=your_deepseek_api_key

# GigaChat API
gigachat_auth_key=your_auth_key
gigachat_scope=your_scope
gigachat_client_id=your_client_id

Примечание: RuBERT-tiny работает без API ключей, модель загружается локально.

Запуск веб-интерфейса

python app.py

Откройте в браузере: http://localhost:5000


Использование

Классификация отзывов без целевой переменной

  1. Перейдите на вкладку "Классификация"
  2. Выберите модель для классификации
  3. Загрузите CSV файл с колонкой "text"
  4. Нажмите "Классифицировать"
  5. Просмотрите результаты и при необходимости отредактируйте
  6. Экспортируйте результаты в CSV

Валидация размеченных данных

  1. Перейдите на вкладку "Валидация"
  2. Выберите модель для валидации
  3. Загрузите CSV файл с колонками "text" и "label"
  4. Нажмите "Валидировать"
  5. Ознакомьтесь с метриками качества
  6. Просмотрите ошибки классификации
  7. Экспортируйте исправленные данные

Использование классов моделей в коде

RuBERT-tiny

from src.rubert_tiny_class import RubertModel

# Инициализация модели
model = RubertModel(model_path='model_training/my_final_model')

# Классификация CSV файла
df_result = model.dataframe_classification(csv_path='data/test.csv')

DeepSeek

from src.deepseek_model import DeepSeek
from config.model_prompts import classifier_system_prompt

# Инициализация модели
model = DeepSeek(api_key='your_api_key')

# Классификация одного текста
response = model.get_response(
    system_prompt=classifier_system_prompt,
    user_prompt=f'Классифицируй тональность следующего отзыва: ```{text}```'
)

GigaChat

from src.gigachat_model import GenerativeModel
from config.model_prompts import classifier_system_prompt

# Инициализация модели
model = GenerativeModel(
    auth_key='your_auth_key',
    model_scope='your_scope',
    client_id='your_client_id'
)

# Классификация одного текста
response = model.generate_response(
    system_prompt=classifier_system_prompt,
    user_prompt=f'Классифицируй тональность следующего отзыва: ```{text}```'
)

Технологический стек

Machine Learning & NLP

  • transformers 4.57.3 - для работы с BERT моделями
  • torch 2.6.0+cu124 - фреймворк глубокого обучения
  • scikit-learn 1.7.2 - метрики и классические ML модели
  • nltk 3.9.2 - обработка естественного языка

Data Processing

  • pandas 2.3.3 - работа с табличными данными
  • numpy 2.3.5 - численные вычисления
  • emoji 2.15.0 - обработка эмодзи

Web Framework

  • Flask 3.0.0 - веб-фреймворк
  • flask-cors 4.0.0 - CORS поддержка

API Integration

  • openai 2.8.1 - для работы с DeepSeek API
  • requests 2.32.5 - HTTP запросы для GigaChat API
  • python-dotenv 1.2.1 - управление переменными окружения

Выводы

  1. Качество данных критично: Исходные данные содержали значительное количество ошибок в разметке, что потребовало переразметки с использованием LLM.

  2. Fine-tuning превосходит промпт-инженеринг: Дообученная модель RuBERT-tiny показала лучшие результаты (Accuracy 0.80) по сравнению с LLM моделями (0.72-0.75), при этом работая полностью локально без API ключей.

  3. Предобработка данных важна: Удаление стоп-слов, эмодзи и нормализация текста значительно улучшили качество классификации.

  4. GigaChat опережает DeepSeek: Для задачи на русском языке GigaChat-2-Max показал лучшие результаты (F1 0.73) по сравнению с DeepSeek (F1 0.63).

  5. Веб-интерфейс повышает практическую ценность: Разработанный интерфейс позволяет не только классифицировать данные, но и валидировать результаты, редактировать разметку и экспортировать результаты.


Контакты

Команда: Gradient Tech Капитан: Илья Трофимов

About

Репозиторий содержит решение задачи хакатона 'Hack&Change 2025' по треку 'ML / Web: Классификация тональности текстов от Правительства Москвы.' команды 'Gradient Tech'

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published