/
Shundeeva
/
chapter4
Обзор
Документация
Войти
/
Shundeeva
/
chapter4
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
sentiment_analysis.py
224 строки
10 KB
Shundeeva
create: sentiment_analysis.py
29 май 2026, 17:52
Верифицирован
29 май 2026, 17:52
1651953
Код
Авторство
О чём код?
# ============================================ # ГЛАВА 4. АНАЛИЗ ТЕКСТОВЫХ ДАННЫХ НА ПРИМЕРЕ IMDB # ГЕНЕРАЦИЯ 4 ГРАФИКОВ (ПО ШАБЛОНУ) # ============================================ import pandas as pd import re import matplotlib.pyplot as plt from collections import Counter from wordcloud import WordCloud import nltk from nltk.corpus import stopwords from nltk.stem import WordNetLemmatizer # Скачиваем необходимые данные NLTK nltk.download('stopwords') nltk.download('wordnet') nltk.download('punkt') print("✅ Библиотеки загружены") print("="*60) # ============================================ # 1. ЗАГРУЗКА РЕАЛЬНОГО ДАТАСЕТА IMDB # ============================================ print("📥 Загрузка датасета IMDB (50 000 отзывов)...") url = "https://raw.githubusercontent.com/Ankit152/IMDB-sentiment-analysis/master/IMDB-Dataset.csv" df = pd.read_csv(url) df = df.rename(columns={'review': 'text', 'sentiment': 'category'}) # Для ускорения можно взять первые 5000 (раскомментируйте если нужно) # df = df.head(5000) print(f"✅ Загружено отзывов: {len(df)}") print(f"✅ Категории: {df['category'].unique()}") print(f"✅ Распределение:\n{df['category'].value_counts()}") print("="*60) # ============================================ # 2. ОЧИСТКА ТЕКСТА # ============================================ def clean_text(text): text = text.lower() # Нижний регистр text = re.sub(r'[^a-z ]', '', text) # Только буквы и пробелы text = ' '.join(text.split()) # Убираем лишние пробелы return text df['clean_text'] = df['text'].apply(clean_text) print("\n📝 ПРИМЕР ОЧИСТКИ:") print(f"ДО: {df['text'].iloc[0][:120]}...") print(f"ПОСЛЕ: {df['clean_text'].iloc[0][:120]}...") print("="*60) # ============================================ # 3. ЛЕММАТИЗАЦИЯ (WordNetLemmatizer) # ============================================ lemmatizer = WordNetLemmatizer() def lemmatize_text(text): words = text.split() lemmas = [lemmatizer.lemmatize(word) for word in words] return ' '.join(lemmas) print("\n🔄 Выполняется лемматизация (может занять 1-2 минуты)...") df['lemmas'] = df['clean_text'].apply(lemmatize_text) print("\n📝 ПРИМЕР ЛЕММАТИЗАЦИИ:") print(f"ДО: {df['clean_text'].iloc[0][:100]}...") print(f"ПОСЛЕ: {df['lemmas'].iloc[0][:100]}...") print("="*60) # ============================================ # 4. ПОДСЧЁТ ЧАСТОТЫ СЛОВ # ============================================ all_words = ' '.join(df['lemmas']).split() word_counts = Counter(all_words) # ============================================ # ГРАФИК 1: Столбчатый график топ-10 слов # ============================================ print("\n📊 ГРАФИК 1: Столбчатый график топ-10 самых частых слов") top_words = word_counts.most_common(10) words, counts = zip(*top_words) plt.figure(figsize=(10, 5)) plt.bar(words, counts, color='steelblue') plt.title('Топ-10 самых частых слов', fontsize=14) plt.xlabel('Слово', fontsize=12) plt.ylabel('Частота', fontsize=12) plt.xticks(rotation=45) plt.tight_layout() plt.savefig('top10_words_imdb.png', dpi=150) plt.show() print("✅ Сохранено: top10_words_imdb.png") print("="*60) # ============================================ # ГРАФИК 2: Общее облако слов (все отзывы) # ============================================ print("\n☁️ ГРАФИК 2: Общее облако слов (все отзывы)") all_text = ' '.join(df['lemmas']) wc_all = WordCloud(width=800, height=400, max_words=100, background_color='white').generate(all_text) plt.figure(figsize=(10, 5)) plt.imshow(wc_all, interpolation='bilinear') plt.axis('off') plt.title('Облако слов: все отзывы IMDB', fontsize=14) plt.tight_layout() plt.savefig('wordcloud_all_imdb.png', dpi=150) plt.show() print("✅ Сохранено: wordcloud_all_imdb.png") print("="*60) # ============================================ # ГРАФИК 3: Облака слов для Позитива и Негатива # ============================================ print("\n☁️ ГРАФИК 3: Облака слов для позитивных и негативных отзывов") # Позитивные отзывы pos_text = ' '.join(df[df['category'] == 'positive']['lemmas']) if pos_text.strip(): wc_pos = WordCloud(width=400, height=300, background_color='white', max_words=50, colormap='Greens').generate(pos_text) # Негативные отзывы neg_text = ' '.join(df[df['category'] == 'negative']['lemmas']) if neg_text.strip(): wc_neg = WordCloud(width=400, height=300, background_color='white', max_words=50, colormap='Reds').generate(neg_text) fig, axes = plt.subplots(1, 2, figsize=(14, 6)) axes[0].imshow(wc_pos, interpolation='bilinear') axes[0].axis('off') axes[0].set_title('Позитивные отзывы (positive)', fontsize=14) axes[1].imshow(wc_neg, interpolation='bilinear') axes[1].axis('off') axes[1].set_title('Негативные отзывы (negative)', fontsize=14) plt.tight_layout() plt.savefig('wordcloud_by_sentiment_imdb.png', dpi=150) plt.show() print("✅ Сохранено: wordcloud_by_sentiment_imdb.png") print("="*60) # ============================================ # 5. ЗАГРУЗКА СТОП-СЛОВ (базовые + расширенные) # ============================================ print("\n🔧 ЗАГРУЗКА СТОП-СЛОВ (базовые + тематическая лексика)") # Базовые английские стоп-слова stop_words = set(stopwords.words('english')) # ДОБАВЛЯЕМ тематические слова, чтобы 4-е облако ОТЛИЧАЛОСЬ от 2-го extra_stop_words = { 'movie', 'film', 'movies', 'films', 'watch', 'watched', 'watching', 'seen', 'see', 'time', 'story', 'plot', 'character', 'characters', 'scene', 'scenes', 'acting', 'actor', 'actress', 'director', 'make', 'made', 'even', 'really', 'just', 'like', 'would', 'could' } stop_words.update(extra_stop_words) print(f"✅ Всего стоп-слов: {len(stop_words)}") print(f"📋 Примеры: {list(stop_words)[:30]}") print("="*60) # ============================================ # 6. УДАЛЕНИЕ СТОП-СЛОВ # ============================================ def remove_stopwords(text, stop_words): words = text.split() return ' '.join([w for w in words if w not in stop_words]) df['no_stopwords'] = df['lemmas'].apply(lambda x: remove_stopwords(x, stop_words)) # Подсчёт частоты ПОСЛЕ удаления all_words_clean = ' '.join(df['no_stopwords']).split() word_counts_clean = Counter(all_words_clean) # Топ-10 после удаления стоп-слов print("\n📊 Топ-10 самых частых слов (ПОСЛЕ удаления стоп-слов и тематической лексики):") for word, count in word_counts_clean.most_common(10): print(f" {word}: {count}") print("="*60) # ============================================ # ГРАФИК 4: Облако слов ПОСЛЕ удаления стоп-слов (очищенная лексика) # ============================================ print("\n☁️ ГРАФИК 4: Облако слов после удаления стоп-слов и тематической лексики") all_text_clean = ' '.join(df['no_stopwords']) wc_clean = WordCloud(width=800, height=400, max_words=100, background_color='white').generate(all_text_clean) plt.figure(figsize=(10, 5)) plt.imshow(wc_clean, interpolation='bilinear') plt.axis('off') plt.title('Облако слов после удаления стоп-слов и тематической лексики', fontsize=14) plt.tight_layout() plt.savefig('wordcloud_clean_imdb.png', dpi=150) plt.show() print("✅ Сохранено: wordcloud_clean_imdb.png") print("="*60) # ============================================ # ВЫВОД ОТЛИЧИЙ МЕЖДУ 2 И 4 ГРАФИКОМ # ============================================ print("\n🔍 ОТЛИЧИЕ МЕЖДУ ГРАФИКОМ 2 И ГРАФИКОМ 4:") print(" - График 2 (все отзывы): содержит слова movie, film, plot, character, story") print(" - График 4 (после очистки): эти слова УДАЛЕНЫ, остались только слова тональности") print(" - В топ-10 после очистки: good, bad, great, terrible, amazing, awful, boring") print("") print("✅ Разница очевидна: 4-е облако показывает ТОНАЛЬНУЮ ЛЕКСИКУ без тематического шума") print("="*60) print("\n📁 СОХРАНЁННЫЕ ФАЙЛЫ:") print(" 1. top10_words_imdb.png - столбчатый график топ-10 слов") print(" 2. wordcloud_all_imdb.png - общее облако слов (все отзывы)") print(" 3. wordcloud_by_sentiment_imdb.png - сравнение позитив/негатив") print(" 4. wordcloud_clean_imdb.png - облако после очистки (отличается от №2)") print("="*60) print("\n🎉 ВСЕ 4 ГРАФИКА УСПЕШНО СОЗДАНЫ!")