Практическое занятие 9: Анализ тональности
Цель занятия
Заголовок раздела «Цель занятия»Изучить библиотеку transformers для работы с моделями машинного обучения и выполнить анализ тональности текста.
Установка библиотек
Заголовок раздела «Установка библиотек»transformers
Заголовок раздела «transformers»Библиотека transformers от Hugging Face предоставляет доступ к предобученным моделям для обработки естественного языка.
pip install transformersФреймворк PyTorch необходим для работы с моделями:
pip install torchПримечание: Размер установки torch может быть значительным. Для Windows можно использовать lighter-версию:
pip install torch --index-url https://download.pytorch.org/whl/cpuЧто такое анализ тональности?
Заголовок раздела «Что такое анализ тональности?»Анализ тональности (sentiment analysis) — это определение эмоциональной окраски текста:
- Положительная (positive) — положительные эмоции
- Отрицательная (negative) — отрицательные эмоции
- Нейтральная (neutral) — отсутствие ярко выраженных эмоций
Первый анализ тональности
Заголовок раздела «Первый анализ тональности»Простейший пример
Заголовок раздела «Простейший пример»from transformers import pipeline
# Создание пайплайна для анализа тональностиsentiment_analyzer = pipeline("sentiment-analysis")
# Анализ текстаtext = "Я очень рад сегодня отличному результату!"result = sentiment_analyzer(text)
print(result)# [{'label': 'POSITIVE', 'score': 0.9987}]Использование на русском языке
Заголовок раздела «Использование на русском языке»Для анализа русского текста нужны специальные модели:
from transformers import pipeline
# Использование модели для русского языкаsentiment_analyzer = pipeline( "sentiment-analysis", model="blanchefort/rubert-base-cased-sentiment")
# Анализ русского текстаtexts = [ "Это отличный фильм, я очень рекомендую!", "Ужасный сервис, никогда больше сюда не вернусь.", "Сегодня обычный день, ничего особенного."]
for text in texts: result = sentiment_analyzer(text)[0] print(f"Текст: {text}") print(f"Тональность: {result['label']}") print(f"Уверенность: {result['score']:.4f}\n")Модель для русского языка
Заголовок раздела «Модель для русского языка»Рекомендуемые модели для русского языка:
| Модель | Описание |
|---|---|
blanchefort/rubert-base-cased-sentiment | RuBERT для анализа тональности |
cointegrated/rubert-tiny2-sentiment | Лёгкая модель (быстрее работает) |
Работа с результатами
Заголовок раздела «Работа с результатами»from transformers import pipeline
sentiment_analyzer = pipeline( "sentiment-analysis", model="blanchefort/rubert-base-cased-sentiment")
def analyze_sentiment(text): """Функция для анализа тональности с красивым выводом""" result = sentiment_analyzer(text)[0]
# Преобразование метки label_map = { "POSITIVE": "Положительная", "NEGATIVE": "Отрицательная", "NEUTRAL": "Нейтральная" }
sentiment = label_map.get(result["label"], result["label"]) confidence = result["score"] * 100
return { "текст": text, "тональность": sentiment, "уверенность": f"{confidence:.2f}%" }
# Использованиеtexts = [ "Прекрасная погода сегодня!", "Мне не понравилось это блюдо.", "Обычный рабочий день."]
for text in texts: analysis = analyze_sentiment(text) print(f"Текст: {analysis['текст']}") print(f"Тональность: {analysis['тональность']}") print(f"Уверенность: {analysis['уверенность']}\n")Интеграция со скрапером
Заголовок раздела «Интеграция со скрапером»Анализ собранных статей
Заголовок раздела «Анализ собранных статей»import jsonfrom transformers import pipeline
# Загрузка скрапированных данныхwith open("habr_articles.json", "r", encoding="utf-8") as file: articles = json.load(file)
# Создание анализатораsentiment_analyzer = pipeline( "sentiment-analysis", model="blanchefort/rubert-base-cased-sentiment")
# Анализ каждой статьиprint("Анализ тональности статей:\n")
for i, article in enumerate(articles, 1): title = article.get("заголовок", "") if title: result = sentiment_analyzer(title)[0]
label_map = { "POSITIVE": "🟢 Положительная", "NEGATIVE": "🔴 Отрицательная", "NEUTRAL": "⚪ Нейтральная" }
sentiment = label_map.get(result["label"], result["label"]) confidence = result["score"] * 100
print(f"{i}. {title}") print(f" Тональность: {sentiment}") print(f" Уверенность: {confidence:.2f}%\n")
# Статистикаpositive = sum(1 for a in articles if sentiment_analyzer(a.get("заголовок", ""))[0]["label"] == "POSITIVE")negative = sum(1 for a in articles if sentiment_analyzer(a.get("заголовок", ""))[0]["label"] == "NEGATIVE")neutral = len(articles) - positive - negative
print(f"Статистика:")print(f"Положительных: {positive}")print(f"Отрицательных: {negative}")print(f"Нейтральных: {neutral}")Сохранение результатов анализа
Заголовок раздела «Сохранение результатов анализа»import jsonfrom transformers import pipeline
def analyze_and_save(input_file, output_file): """Анализирует тональность и сохраняет результаты"""
# Загрузка данных with open(input_file, "r", encoding="utf-8") as file: articles = json.load(file)
# Создание анализатора sentiment_analyzer = pipeline( "sentiment-analysis", model="blanchefort/rubert-base-cased-sentiment" )
# Анализ и добавление результатов for article in articles: title = article.get("заголовок", "") if title: result = sentiment_analyzer(title)[0] article["тональность"] = result["label"] article["уверенность"] = round(result["score"], 4)
# Сохранение результатов with open(output_file, "w", encoding="utf-8") as file: json.dump(articles, file, ensure_ascii=False, indent=4)
print(f"Результаты сохранены в {output_file}") return articles
# Использованиеanalyzed_articles = analyze_and_save("habr_articles.json", "habr_sentiment.json")Оптимизация производительности
Заголовок раздела «Оптимизация производительности»Использование лёгкой модели
Заголовок раздела «Использование лёгкой модели»from transformers import pipeline
# Использование лёгкой модели (быстрее, но менее точная)sentiment_analyzer = pipeline( "sentiment-analysis", model="cointegrated/rubert-tiny2-sentiment")
text = "Это отличный день!"result = sentiment_analyzer(text)print(result)Пакетная обработка
Заголовок раздела «Пакетная обработка»from transformers import pipeline
sentiment_analyzer = pipeline( "sentiment-analysis", model="blanchefort/rubert-base-cased-sentiment")
# Пакетная обработка (быстрее для большого количества текстов)texts = [ "Отличный результат!", "Плохой сервис.", "Нормально.", "Превосходно!", "Ужасно."]
results = sentiment_analyzer(texts)
for text, result in zip(texts, results): print(f"{text} -> {result['label']} ({result['score']:.4f})")Полный пример: интеграция с базой данных
Заголовок раздела «Полный пример: интеграция с базой данных»import sqlite3from transformers import pipeline
class SentimentAnalyzer: """Класс для анализа тональности статей из базы данных"""
def __init__(self, model_name="blanchefort/rubert-base-cased-sentiment"): self.analyzer = pipeline("sentiment-analysis", model=model_name) self.label_map = { "POSITIVE": "Положительная", "NEGATIVE": "Отрицательная", "NEUTRAL": "Нейтральная" }
def analyze_text(self, text): """Анализ тональности одного текста""" result = self.analyzer(text)[0] return { "тональность": self.label_map.get(result["label"], result["label"]), "уверенность": round(result["score"], 4) }
def analyze_database(self, db_name, table_name): """Анализ статей из базы данных""" connection = sqlite3.connect(db_name) cursor = connection.cursor()
# Получение статей cursor.execute(f"SELECT rowid, заголовок FROM {table_name}") articles = cursor.fetchall()
print(f"Найдено {len(articles)} статей для анализа\n")
# Добавление столбца, если не существует cursor.execute(f"ALTER TABLE {table_name} ADD COLUMN тональность TEXT") cursor.execute(f"ALTER TABLE {table_name} ADD COLUMN уверенность REAL")
# Анализ и обновление for row_id, title in articles: if title: result = self.analyze_text(title) cursor.execute( f"UPDATE {table_name} SET тональность = ?, уверенность = ? WHERE rowid = ?", (result["тональность"], result["уверенность"], row_id) ) print(f"Обработано: {title[:50]}...")
connection.commit() connection.close() print("\nАнализ завершён и сохранён в базу данных")
# Использованиеif __name__ == "__main__": analyzer = SentimentAnalyzer() analyzer.analyze_database("articles.db", "habr")Задания для самостоятельной работы
Заголовок раздела «Задания для самостоятельной работы»-
Создайте программу, которая анализирует тональность пользовательских отзывов и классифицирует их по категориям.
-
Напишите функцию для визуализации результатов анализа (например, гистограмма распределения тональности).
-
Реализуйте анализ тональности для разных языков с использованием соответствующих моделей.
-
Создайте систему, которая анализирует тональность комментариев и фильтрует негативные.
-
Интегрируйте анализ тональности в ваш скрапер для автоматической классификации собранных статей.
Пример решения задания 2
Заголовок раздела «Пример решения задания 2»import jsonimport matplotlib.pyplot as pltfrom transformers import pipeline
def visualize_sentiment(input_file): """Визуализация распределения тональности"""
# Загрузка данных with open(input_file, "r", encoding="utf-8") as file: articles = json.load(file)
# Подсчёт counts = {"Положительная": 0, "Отрицательная": 0, "Нейтральная": 0}
for article in articles: sentiment = article.get("тональность", "NEUTRAL") if sentiment == "POSITIVE": counts["Положительная"] += 1 elif sentiment == "NEGATIVE": counts["Отрицательная"] += 1 else: counts["Нейтральная"] += 1
# Построение графика labels = list(counts.keys()) values = list(counts.values())
colors = ["green", "red", "gray"]
plt.figure(figsize=(10, 6)) plt.bar(labels, values, color=colors) plt.xlabel("Тональность") plt.ylabel("Количество") plt.title("Распределение тональности статей") plt.show()
# Использованиеvisualize_sentiment("habr_sentiment.json")Полезные ресурсы
Заголовок раздела «Полезные ресурсы»Следующий шаг
Заголовок раздела «Следующий шаг»На следующем занятии мы изучим Docker, Airflow и автоматизацию процессов с помощью DAG.