Перейти к содержимому

Практическое занятие 9: Анализ тональности

Изучить библиотеку 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-sentimentRuBERT для анализа тональности
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 json
from 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 json
from 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 sqlite3
from 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")
  1. Создайте программу, которая анализирует тональность пользовательских отзывов и классифицирует их по категориям.

  2. Напишите функцию для визуализации результатов анализа (например, гистограмма распределения тональности).

  3. Реализуйте анализ тональности для разных языков с использованием соответствующих моделей.

  4. Создайте систему, которая анализирует тональность комментариев и фильтрует негативные.

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

import json
import matplotlib.pyplot as plt
from 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.