S

Sentiment-analyzer

Анализатор тональности отзывов

Веб-приложение для автоматической классификации русскоязычных и англоязычных отзывов по тональности с использованием ML-модели на базе XLM-RoBERTa.

Возможности

  • Автоматическая классификация текстов на 3 класса: негативный, нейтральный, позитивный
  • Мультиязычная поддержка (100+ языков включая русский и английский)
  • Асинхронная обработка больших файлов с прогресс-баром
  • Интерактивные визуализации и дашборд
  • Валидация модели с расчётом Macro-F1
  • Экспорт результатов в CSV
  • Ручная корректировка разметки

📦 Предварительные требования

  • Docker и Docker Compose
  • Python 3.11+ (для локальной разработки)
  • Node.js 18+ (для локальной разработки)
  • 4GB RAM минимум

🚀 Быстрый старт

Docker (рекомендуется)

git clone https://github.com/meloch287/Sentiment-analyzer.git
cd Sentiment-analyzer
docker compose up --build

Приложение будет доступно:

Остановка

docker compose down

Локальная разработка

Backend:

cd backend
python -m venv venv
venv\Scripts\activate        # Windows
source venv/bin/activate     # Linux/Mac
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000

Frontend:

cd frontend
npm install
npm run dev

Frontend: http://localhost:8080

🌐 Демо и репозитории

Основной репозиторий

Live Demo (скоро)

  • Frontend: -
  • Backend API: -

📸 Скриншоты

Главная страница

Home

Загрузка файла

Upload

Dashboard с визуализациями

Dashboard

Результаты анализа

Results

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

sentiment-analyzer/
├── backend/
│   ├── app/
│   │   ├── api/
│   │   │   └── routes.py          # API эндпоинты
│   │   ├── models/
│   │   │   ├── classifier.py      # ML классификатор
│   │   │   └── preprocessing.py   # Препроцессинг текста
│   │   ├── services/
│   │   │   └── ml_service.py      # Сервис анализа
│   │   ├── core/
│   │   │   └── config.py          # Конфигурация
│   │   └── main.py                # FastAPI приложение
│   ├── training/
│   │   ├── train_model.py         # Скрипт обучения
│   │   └── evaluate.py            # Скрипт оценки
│   ├── requirements.txt
│   └── Dockerfile
├── frontend/
│   ├── src/
│   │   ├── pages/                 # Страницы приложения
│   │   ├── components/            # UI компоненты
│   │   ├── services/              # API клиент
│   │   └── store/                 # Zustand store
│   ├── package.json
│   └── Dockerfile
├── data/
│   ├── test_sample.csv            # Тестовые данные
│   └── validation_sample.csv      # Данные для валидации
├── docker-compose.yml
└── README.md

📋 Формат данных

Входной CSV

text,src
"Отличный товар! Очень доволен покупкой!",ozon
"Ужасное качество, деньги на ветер.",wildberries
"Нормальный товар, ничего особенного.",yandex
Колонка Обязательная Описание
text Да Текст отзыва
src Нет Источник отзыва

Выходной CSV

text,src,label,confidence
"Отличный товар! Очень доволен покупкой!",ozon,2,0.95
"Ужасное качество, деньги на ветер.",wildberries,0,0.89
"Нормальный товар, ничего особенного.",yandex,1,0.76

Метки тональности

Значение Тональность
0 Негативная
1 Нейтральная
2 Позитивная

🔧 API Reference

Base URL

http://localhost:8000/api

POST /api/analyze

Загрузка CSV файла для анализа тональности.

Request:

curl -X POST "http://localhost:8000/api/analyze" \
  -H "Content-Type: multipart/form-data" \
  -F "file=@reviews.csv"

Response:

{
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "Analysis started"
}

GET /api/results/{task_id}

Получение результатов анализа.

Request:

curl "http://localhost:8000/api/results/550e8400-e29b-41d4-a716-446655440000"

Response (в процессе):

{
  "status": "processing",
  "progress": 150,
  "total": 500
}

Response (завершено):

{
  "status": "completed",
  "data": [
    {
      "text": "Отличный товар!",
      "src": "ozon",
      "label": 2,
      "confidence": 0.95
    }
  ],
  "stats": {
    "total": 500,
    "negative": 120,
    "neutral": 180,
    "positive": 200
  }
}

GET /api/results/{task_id}/download

Скачивание результатов в CSV формате.

Request:

curl -O "http://localhost:8000/api/results/550e8400-e29b-41d4-a716-446655440000/download"

Response: CSV файл


POST /api/validate

Валидация предсказаний с расчётом метрик.

Request:

curl -X POST "http://localhost:8000/api/validate" \
  -H "Content-Type: multipart/form-data" \
  -F "file=@validation.csv"

CSV должен содержать колонки label (предсказание) и true_label (истинная метка).

Response:

{
  "macro_f1": 0.823,
  "precision": {
    "0": 0.85,
    "1": 0.78,
    "2": 0.87
  },
  "recall": {
    "0": 0.82,
    "1": 0.81,
    "2": 0.84
  },
  "confusion_matrix": [
    [192, 28, 14],
    [54, 459, 54],
    [26, 43, 364]
  ]
}

GET /api/search

Поиск по текстам в результатах.

Request:

curl "http://localhost:8000/api/search?task_id=550e8400&query=отличный&source=ozon"

Parameters:

Параметр Тип Обязательный Описание
task_id string Да ID задачи
query string Да Поисковый запрос
source string Нет Фильтр по источнику

Response:

{
  "results": [
    {
      "text": "Отличный товар!",
      "src": "ozon",
      "label": 2,
      "confidence": 0.95
    }
  ]
}

GET /api/filter

Фильтрация результатов по тональности и источнику.

Request:

curl "http://localhost:8000/api/filter?task_id=550e8400&label=2&source=ozon"

Parameters:

Параметр Тип Обязательный Описание
task_id string Да ID задачи
label int Нет Фильтр по тональности (0, 1, 2)
source string Нет Фильтр по источнику

Response:

{
  "results": [
    {
      "text": "Отличный товар!",
      "src": "ozon",
      "label": 2,
      "confidence": 0.95
    }
  ]
}

PATCH /api/results/{task_id}/correct

Ручная корректировка метки тональности.

Request:

curl -X PATCH "http://localhost:8000/api/results/550e8400/correct?text_id=5&new_label=1"

Parameters:

Параметр Тип Обязательный Описание
task_id string Да ID задачи
text_id int Да Индекс текста в результатах
new_label int Да Новая метка (0, 1, 2)

Response:

{
  "status": "updated",
  "text_id": 5,
  "new_label": 1
}

GET /health

Проверка состояния сервиса.

Request:

curl "http://localhost:8000/health"

Response:

{
  "status": "healthy"
}

🧹 Предобработка текста

Модуль preprocessing.py выполняет очистку текста перед подачей в модель.

Шаги предобработки

Шаг Описание Пример
1 Приведение к нижнему регистру ОТЛИЧНОотлично
2 Удаление HTML-тегов <b>текст</b>текст
3 Удаление ссылок смотри https://site.ruсмотри
4 Удаление эмодзи круто 🔥😊круто
5 Удаление спецсимволов цена: 100$цена 100
6 Схлопывание повторов отлично!!!отлично!
7 Нормализация пробелов много пробеловмного пробелов
8 Фильтрация коротких текстов ок → `` (пустая строка)

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

from preprocessing import preprocess_text, preprocess_batch

text = preprocess_text("СУПЕР товар!!! 🔥 https://shop.ru")
# Результат: "супер товар!"

texts = preprocess_batch(["Отлично!!!", "Брак 😡"])
# Результат: ["отлично!", "брак"]

Запуск тестов

cd backend/training
python test_prepocessing.py

Обработка CSV файлов

Для обработки больших CSV файлов используйте run_preprocessing.py:

cd backend/training

# Базовый запуск
python run_preprocessing.py --input ../../data/train.csv

# С параметрами
python run_preprocessing.py \
  --input ../../data/train.csv \
  --output ../../data/train_cleaned.csv \
  --column text \
  --chunk 50000
Параметр Описание По умолчанию
--input, -i Путь к CSV файлу обязательный
--output, -o Куда сохранить результат *_preprocessed.csv
--column, -c Название колонки с текстом text
--chunk Размер чанка для больших файлов 10000

Скрипт читает файл чанками, показывает прогресс и выводит статистику. Для файла на 1 млн строк потребуется ~2-3 ГБ RAM.

🎓 Обучение модели

Файнтюнинг на своих данных

cd backend/training

python train_model.py \
  --data_path train.csv \
  --output_dir ./model \
  --model_name cointegrated/rubert-tiny2 \
  --epochs 5 \
  --batch_size 16

Оценка модели

python evaluate.py \
  --model_path ./model \
  --test_path test.csv \
  --output_report metrics_report.txt

📈 Метрики модели

Метрика Значение
Macro F1 ~0.78-0.82
Inference <2 сек на 100 отзывов (CPU)
Поддержка языков 100+ (RU, EN, и др.)

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

Backend

  • Python 3.11+
  • FastAPI
  • PyTorch
  • Transformers (Hugging Face)
  • scikit-learn
  • pandas, numpy

Frontend

  • React 18
  • TypeScript
  • Tailwind CSS
  • shadcn/ui
  • Recharts
  • Zustand

ML Model

  • cardiffnlp/twitter-xlm-roberta-base-sentiment

DevOps

  • Docker
  • Docker Compose
  • GitHub Actions

👥 Команда Dakt

Александр Максименко - backend/frontend

Андрей Деревцов - backend/ML

Никита Аграфенин - Frontend

Ксения Святогорова - Дизайн