Как вы бы реализовали sentiment analysis?

Sentiment Analysis (анализ тональности) — это задача обработки естественного языка (NLP), направленная на определение эмоциональной окраски текста: положительной, отрицательной или нейтральной. В более сложных вариантах задача может включать определение степени полярности (например, "очень негативный" или "слегка позитивный") или классификацию по категориям эмоций (радость, злость, страх и т.д.).

Этапы реализации sentiment analysis

1. Сбор данных

Источники:

  • Отзывы пользователей (Amazon, IMDb, Yelp)

  • Комментарии в соцсетях (Twitter, Reddit)

  • Форумы и блоги

  • Открытые датасеты:

    • IMDb Movie Reviews

    • SST (Stanford Sentiment Treebank)

    • Amazon Reviews

    • Twitter US Airline Sentiment

    • RuSentiment (для русского языка)

Структура:

Чаще всего:

{
"text": "The product is amazing, I love it!",
"label": "positive"
}

Метки могут быть бинарные (positive / negative), трёхклассовые (добавляется neutral) или многоклассовые (5 баллов и т.д.).

2. Предобработка текста

Для классических моделей (не трансформеров) важно очистить текст:

  • Приведение к нижнему регистру

  • Удаление пунктуации и спецсимволов

  • Удаление стоп-слов (не всегда!)

  • Токенизация

  • Лемматизация/стемминг

  • Удаление HTML-тегов и эмодзи (при необходимости)

  • Фильтрация коротких/шумных сообщений

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

3. Векторизация текста

Варианты представления текста в числовом виде:

A. Bag of Words / TF-IDF

  • Подсчёт частоты слов (или n-грамм)

  • Прост в реализации

  • Не учитывает порядок слов и контекст

from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(ngram_range=(1,2), max_features=5000)
X = vectorizer.fit_transform(corpus)

B. Word Embeddings

  • Word2Vec / GloVe / FastText

  • Представление каждого слова — плотный вектор

  • Для предложения — усреднение векторов слов или использование RNN/Conv1D

C. Contextual Embeddings (Transformer-based)

  • Использование моделей типа BERT, RoBERTa, DistilBERT

  • Тексты обрабатываются через токенизатор, а выход [CLS]-токена используется как embedding

4. Построение модели

A. Классические модели

  • Logistic Regression

  • Naive Bayes (MultinomialNB)

  • SVM

  • Random Forest

from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X_train, y_train)

Подходят для небольших датасетов и базовых моделей.

B. Нейросетевые модели

Простые:
  • Embedding + LSTM/GRU

  • Embedding + CNN

  • Embedding + BiLSTM + Attention

Пример:
model = Sequential()
model.add(Embedding(input_dim=10000, output_dim=128))
model.add(Bidirectional(LSTM(64)))
model.add(Dense(1, activation='sigmoid'))

C. Модели на трансформерах (BERT и др.)

  • Использование предобученной модели и её дообучение на своей задаче (fine-tuning)

  • HuggingFace Transformers делает это просто

from transformers import BertTokenizer, BertForSequenceClassification
model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=3)
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")

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

  • Делим данные на train/val/test

  • Используем кросс-валидацию

  • Для нейросетей — используем batching, оптимизаторы (Adam), scheduler

  • Возможна балансировка классов (при дисбалансе)

6. Оценка качества

Метрики:

  • Accuracy — точность (непригодна при дисбалансе классов)

  • Precision / Recall / F1-score — по каждому классу

  • Confusion Matrix — наглядное сравнение предсказаний

from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred))

7. Инференс и деплой

  • Модель сохраняется: .pkl / .pt / .h5 или .onnx

  • Разворачивается через API (Flask, FastAPI, gRPC)

  • Используется в чат-ботах, аналитике, автоматической модерации

Продвинутые темы

  • Aspect-based Sentiment Analysis (ABSA)
    Определение тональности по аспектам (например, "батарея хорошая, экран плохой").

  • Emotion Classification
    Расширение меток с "positive/negative" до "joy, sadness, anger, fear..."

  • Multilingual SA
    Обработка текстов на разных языках (multilingual BERT)

  • Zero-shot Classification
    Модели типа XLM-R, которые не обучены на конкретной задаче, но могут классифицировать с помощью инструкций

Популярные библиотеки

Библиотека Описание
NLTK Токенизация, стоп-слова, препроцессинг
--- ---
Scikit-learn Классические модели
--- ---
spaCy Предобработка, простые пайплайны
--- ---
TextBlob Простая API для тональности
--- ---
VADER Лексикон-ориентированный метод для соцсетей
--- ---
HuggingFace SOTA модели, fine-tuning, API
--- ---

Пример на VADER (соцсети)

from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer()
score = analyzer.polarity_scores("I really loved the new iPhone!")
print(score) # {'neg': 0.0, 'neu': 0.357, 'pos': 0.643, 'compound': 0.6696}

Пример fine-tuning BERT

from transformers import Trainer, TrainingArguments
training_args = TrainingArguments(
output_dir="./results",
num_train_epochs=3,
per_device_train_batch_size=16,
evaluation_strategy="epoch",
save_strategy="epoch"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_data,
eval_dataset=val_data,
tokenizer=tokenizer
)
trainer.train()