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

Что такое анализ тональности
Анализ тональности — это техника обработки естественного языка (NLP), которая выявляет отношение автора текста. Проще: модель классифицирует текст как положительный, отрицательный или нейтральный. Краткое определение: метод, автоматически оценивающий эмоциональную окраску текста.
Важно: в реальных данных «нейтральный» класс часто менее однозначен и требует дополнительной валидации.
Основные этапы проекта (кратко)
- Подготовка окружения и установка пакетов.
- Загрузка и очистка датасета (выбор колонок Review и Rating).
- Токенизация, последовательности и паддинг.
- One-hot кодирование меток.
- Разделение на train/test.
- Создание и обучение модели (Embedding + Conv1D).
- Оценка, сохранение и развёртывание модели.
Настройка окружения
Требования: базовые знания Python, доступ к Google Colab или Jupyter Notebook. Создайте новый ноутбук и установите библиотеки:
! pip install tensorflow scikit-learn pandas numpy pickle5Полный исходный код проекта может быть в репозитории на GitHub (ссылка в исходном материале).
Импорт необходимых библиотек
Импортируйте библиотеки, которые понадобятся для предобработки, обучения и оценки модели:
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Conv1D, GlobalMaxPooling1D, Dense, Dropout
import pickle5 as pickleЗагрузка датасета
В этом руководстве используется набор Trip Advisor Hotel Reviews (Kaggle). Загрузите CSV и проверьте первые строки:
df = pd.read_csv('/content/tripadvisor_hotel_reviews.csv')
print(df.head())В датасете есть столбцы с индексом, Review и Rating.
Предобработка данных
- Выберите столбцы Review и Rating.
- Создайте новый столбец sentiment: >3 → positive, <3 → negative, ==3 → neutral.
- Оставьте только Review и sentiment, перемешайте строки и сбросьте индекс.
df = df[['Review', 'Rating']]
df['sentiment'] = df['Rating'].apply(lambda x: 'positive' if x > 3 else 'negative' if x < 3 else 'neutral')
df = df[['Review', 'sentiment']]
df = df.sample(frac=1).reset_index(drop=True)Токенизируйте текст и приведите последовательности к одинаковой длине (pad_sequences):
tokenizer = Tokenizer(num_words=5000, oov_token='')
tokenizer.fit_on_texts(df['Review'])
word_index = tokenizer.word_index
sequences = tokenizer.texts_to_sequences(df['Review'])
padded_sequences = pad_sequences(sequences, maxlen=100, truncating='post') Преобразуйте метки в one-hot кодировку:
sentiment_labels = pd.get_dummies(df['sentiment']).valuesКомментарий: num_words=5000 и maxlen=100 — типичные гиперпараметры для прототипа. Для производства стоит провести исследование чувствительности.
Разделение набора на тренировочный и тестовый
Разделите данные случайным образом: 80% — обучение, 20% — тест.
x_train, x_test, y_train, y_test = train_test_split(padded_sequences, sentiment_labels, test_size=0.2)Пояснение: фиксируйте random_state при повторяемости экспериментов.
Создание нейронной сети
Пример простой модели с шестью слоями: Embedding → Conv1D → GlobalMaxPooling → Dense → Dropout → Dense(3).
model = Sequential()
model.add(Embedding(5000, 100, input_length=100))
model.add(Conv1D(64, 5, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()Краткое объяснение слоёв:
- Embedding: учит плотные векторные представления слов.
- Conv1D: извлекает локальные шаблоны (n-grams).
- GlobalMaxPooling1D: сводит последовательность в вектор фиксированной длины.
- Dense + Dropout: классификация и регуляризация.
Обучение модели
Обучаем модель 10 эпох (можно изменить):
model.fit(x_train, y_train, epochs=10, batch_size=32, validation_data=(x_test, y_test))После каждой эпохи модель оценивается на данных валидации.
Оценка качества
Предскажите классы и посчитайте точность:
y_pred = np.argmax(model.predict(x_test), axis=-1)
print("Accuracy:", accuracy_score(np.argmax(y_test, axis=-1), y_pred))В примере точность составляет около 84% на тестовом наборе (результат может отличаться в зависимости от предобработки и семян генератора).
Сохранение модели и токенизатора
model.save('sentiment_analysis_model.h5')
with open('tokenizer.pickle', 'wb') as handle:
pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)Токенизатор понадобится при предобработке новых текстов перед подачей в модель.
Использование модели для предсказаний на новых текстах
Загрузите модель и токенизатор, затем определите функцию прогнозирования:
# Load the saved model and tokenizer
import keras
model = keras.models.load_model('sentiment_analysis_model.h5')
with open('tokenizer.pickle', 'rb') as handle:
tokenizer = pickle.load(handle)
def predict_sentiment(text):
# Tokenize and pad the input text
text_sequence = tokenizer.texts_to_sequences([text])
text_sequence = pad_sequences(text_sequence, maxlen=100)
# Make a prediction using the trained model
predicted_rating = model.predict(text_sequence)[0]
if np.argmax(predicted_rating) == 0:
return 'Negative'
elif np.argmax(predicted_rating) == 1:
return 'Neutral'
else:
return 'Positive'Пример предсказания:
text_input = "I absolutely loved my stay at that hotel. The staff was amazing and the room was fantastic!"
predicted_sentiment = predict_sentiment(text_input)
print(predicted_sentiment)Модель в примере корректно классифицирует все три отзыва.
Предобученные модели и альтернативы
Иногда набор данных труднодоступен или ресурсов мало. В таких случаях стоит рассмотреть предобученные трансформеры (BERT, RoBERTa) и API-предложения (Hugging Face, cloud NLP APIs). Альтернативы этому подходу:
- Использовать bag-of-words + логистическую регрессию для быстрого baseline.
- Применить предобученные эмбеддинги (GloVe, FastText) вместо обучения Embedding с нуля.
- Подключить трансформер и дообучить (fine-tune) для повышения качества на малых объёмах данных.
Преимущество Conv1D-подхода — скорость и простота; ограничение — слабая способность моделировать длинные зависимости по сравнению с трансформерами.
Когда этот метод даёт сбои (примеры)
- Сарказм и ирония: модель без дополнительных признаков обычно их не уловит.
- Доменная специфика: слова меняют значение в узкоспециальной лексике (медицина, юриспруденция).
- Короткие отзывы или эмодзи: требуется специальная обработка токенов.
- Несбалансированные классы: при малом количестве примеров одного класса модель будет смещена.
Методологическая мини-инструкция (шаги для проекта)
- Исследование данных: типы колонок, пропуски, распределение оценок.
- Очистка текста: нижний регистр, удаление HTML, управление эмодзи при необходимости.
- Балансировка: undersampling/oversampling или взвешивание потерь.
- Токенизация и векторизация: решите num_words и maxlen по EDA.
- Выбор модели: baseline → CNN/RNN → трансформер.
- Валидация: cross-validation или выделенная валидация по времени для отзывов.
- Тестирование и критерии приёмки.
- Сохранение и развёртывание.
Критерии приёмки
- Модель проходит тестовый набор с метрикой accuracy/precision/recall, согласованной с бизнес-задачей.
- Поведение на контрольных примерах (сарказм, смешанные отзывы) подробно задокументировано.
- Токенизатор и версия модели задокументированы и сохранены.
- Наличие ретеста после обновления данных.
Ролевые чек-листы
Data Scientist:
- Провёл EDA и анализ классов.
- Выбрал и обосновал токенизацию и maxlen.
- Подготовил baseline и несколько моделей для сравнения.
ML Engineer:
- Обеспечил логирование и reproducibility (random_state, версии библиотек).
- Настроил сохранение артефактов (model.h5, tokenizer.pickle).
- Подготовил контейнер или endpoint для инференса.
Product Manager:
- Определил целевую метрику и приемлемый порог.
- Согласовал требования к быстродействию и латентности.
- Подготовил план мониторинга качества после релиза.
Тестовые случаи и критерии приёмки
- Unit-тест: токенизатор корректно обрабатывает неизвестные слова (oov_token).
- Интеграционный тест: endpoint возвращает ответ за допустимое время (
- Регрессионный тест: после дообучения accuracy на контрольном наборе не ухудшилась.
- Кейс-листы: ручная проверка 50 случайных предсказаний из продовой ленты.
Факто-бокс: ключевые параметры из примера
- vocab size: 5000
- maxlen (последовательность): 100 токенов
- embedding dim: 100
- Conv1D filters: 64, kernel size: 5
- batch_size: 32, epochs: 10
Эти числа подходят для прототипа; для продакшна требуется тюнинг.
Безопасность и конфиденциальность
- Не храните чувствительные персональные данные без явного согласия.
- Для GDPR/локального законодательства обеспечьте удаление личных данных и документируйте verarbeitet данные.
- Логируйте минимально необходимые поля для отладки.
Советы по доработке и оптимизации
- Попробуйте уменьшить oov_token-эффект, увеличив num_words или применив субсловную токенизацию (Byte-Pair Encoding).
- Для многоязычных отзывов используйте мультилингвальные эмбеддинги или отдельные модели для каждого языка.
- Для повышения устойчивости применяйте регуляризацию, балансировку классов и увеличение данных (data augmentation).
Краткое резюме
- Простой pipeline анализа тональности включает загрузку данных, предобработку, токенизацию, обучение модели и развёртывание.
- Для прототипа Conv1D + Embedding даёт быстрый результат; при высоких требованиях к качеству рассмотрите трансформеры.
- Обязательно включите контрольные метрики, тесты и план мониторинга после релиза.
Важно: перед публикацией модели в продакшн согласуйте метрики с бизнесом и проведите аудит данных на предмет персональной информации.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone