Мы уже анализировали самые частые слова в тексте, но делали это быстро, на коленке и с помощью Экселя. Теперь подойдём к этому серьёзно и используем дата-сайенс и Python — с ним такой анализ будет проще, быстрее и эффективнее. Заодно научимся делать такое красивое облако самых частых слов — это из первого тома «Войны и мира»:
Что делаем
Сегодня мы проанализируем текст всех томов «Войны и мира» и посмотрим, изменятся ли самые частые слова, как это будет выглядеть в облаке. Интересно, можно ли по таким облакам хотя бы примерно понять общее настроение или содержание текста.
Логика будет простая:
- Скачиваем четыре тома, каждый отдельным текстовым файлом.
- Пишем алгоритм, который проанализирует слова в первом томе.
- Генерируем для него облако слов.
- Меняем имя файла в программе и получаем картинки для трёх оставшихся томов.
- Смотрим, что получилось, и сравниваем картинки между собой.
Вместо художественного текста анализировать так можно что угодно: статьи «Кода», записи в дневнике или инструкцию от пылесоса.
Загружаем текст
Мы всё будем делать в редакторе VS Code — он бесплатный, есть окно вывода сообщений и ошибок, а ещё он умеет сразу показывать сгенерированные картинки в отдельном окне.
Также нам понадобятся все тома «Войны и мира»:
Их нужно положить в ту же папку, где будет скрипт.
Создаём новый python-файл, указываем в нём путь к файлу, потом загружаем в переменную и сразу проверяем, получилось или нет. Для этого выводим первые 300 символов текста:
# открываем текстовый файл
f = open('tom1.txt', "r", encoding="utf-8")
# закидываем его содержимое в переменную
text = f.read()
# выводим начало, чтобы убедиться, что всё считалось правильно
print(text[:300])
Видно, что файл считался нормально, всё на месте. Ещё сразу становится понятно, что в тексте будет много французского языка — это тоже мы учтём при анализе.
Убираем лишнее
Сейчас в тексте много лишнего, что будет мешать анализу:
- цифры,
- знаки препинания,
- большие и маленькие буквы,
- переносы строк.
Исправим это с помощью встроенного модуля String — в нём уже есть почти вся пунктуация, которую мы дополним несколькими символами:
# переводим символы в нижний регистр, чтобы всё было одинаково
text = text.lower()
# подключаем встроенный модуль работы со строками
import string
# добавляем к стандартным знакам пунктуации кавычки и многоточие
spec_chars = string.punctuation + '«»\t—…’'
# очищаем текст от знаков препинания
text = "".join([ch for ch in text if ch not in spec_chars])
# подключаем регулярные выражения
import re
# меняем переносы строк на пробелы
text = re.sub('\n', ' ', text)
# убираем из текста цифры
text = "".join([ch for ch in text if ch not in string.digits])
# смотрим на результат
print(text[:300])
Текст стал однородным: его теперь сложно читать, зато компьютеру будет легко распознать каждое слово.
Библиотека NLTK и токенизация
Дальше нам понадобится NLTK — мощная библиотека для обработки текста. Технически это даже не одна библиотека, а набор модулей, внутри которых тоже может быть разное, но для простоты назовём это так.
Токенизация — это сегментация, или разделение текста на отдельные компоненты, а токены — это и есть те самые компоненты. Так как мы ищем самые популярные слова, то нам нужно токенизировать на уровне слов. Например, если токенизировать по словам предложение «и швец, и жнец, и на дуде игрец», то токены будут такие: «и», «швец», «жнец», «на», «дуде», «игрец».
Важно помнить, что с точки зрения библиотеки, токены — это не строки, хотя они и хранятся там в таком виде. Чтобы можно было работать с ними как со строками, мы будем их отдельно приводить к этому виду.
Для установки библиотеки используем команду:
pip install nltk
Для установки отдельных модулей, например, word_tokenize, нам понадобится сделать такое:
- В терминале VS Code выполнить команду
python
(илиpython3
). Запустится среда выполнения Python, в которой мы будем дальше работать. - Пишем и выполняем команду
import nltk
— она подгрузит библиотеку в Python. - После этого установим нужный модуль командой
nltk.download('word_tokenize')
. - Также можем сразу установить второй модуль, который мы будем использовать:
nltk.download('stopwords')
. - Выходим из среды Python, набрав в консоли команду
exit()
.
Теперь найдём первые 5 самых популярных слов в тексте:
# из библиотеки обработки текста подключаем модуль для токенизации слов
from nltk import word_tokenize
# токенизируем текст
text_tokens = word_tokenize(text)
# подключаем библиотеку для работы с текстом
import nltk
# переводим токены в текстовый формат
text = nltk.Text(text_tokens)
# подключаем статистику
from nltk.probability import FreqDist
# и считаем слова в тексте по популярности
fdist = FreqDist(text)
# выводим первые 5 популярных слов
print(fdist.most_common(5))
Чистим текст от стоп-слов
Стоп-слова в NLTK — это те слова, которые мешают правильно оценить весь текст. К ним относятся:
- предлоги и союзы,
- местоимения,
- междометия,
- артикли,
- слова-связки.
Чтобы избавиться от них, используем специальный модуль, в котором уже собраны все стоп-слова из разных языков. Сразу добавим туда стоп-слова из французского языка, так как герои романа часто общаются друг с другом по-французски:
# подключаем модуль со стоп-словами
from nltk.corpus import stopwords
# добавляем русские и французские стоп-слова
russian_stopwords = stopwords.words("russian")
russian_stopwords += stopwords.words("french")
# перестраиваем токены, не учитывая стоп-слова
text_tokens = [token.strip() for token in text_tokens if token not in russian_stopwords]
# снова приводим токены к текстовому виду
text = nltk.Text(text_tokens)
# считаем заново частоту слов
fdist_sw = FreqDist(text)
# показываем самые популярные
print(fdist_sw.most_common(10))
Стало лучше, но появилась новая проблема: судя по первой десятке, герои слишком много говорят — «cказал», «сказала», «говорил». Для чистоты эксперимента их тоже можно убрать из текста, поместив их в список стоп-слов. Туда же отнесём «это» и «что»:
# добавляем свои слова в этот список
russian_stopwords.extend(['это', 'чтò','всё','сказал', 'сказала','говорил','говорила'])
# перестраиваем токены, не учитывая стоп-слова
text_tokens = [token.strip() for token in text_tokens if token not in russian_stopwords]
# снова приводим токены к текстовому виду
text = nltk.Text(text_tokens)
# считаем заново частоту слов
fdist_sw = FreqDist(text)
# показываем самые популярные
Рисуем облако слов
У нас всё готово, чтобы вывести слова в виде красивой картинки: чем чаще встречается слово, тем большим шрифтом оно будет написано. Сделаем это с помощью библиотеки wordcloud, которую нужно будет установить отдельно:
pip install wordcloud
# подключаем библиотеку для создания облака слов
from wordcloud import WordCloud
# и графический модуль, с помощью которого нарисуем это облако
import matplotlib.pyplot as plt
# переводим всё в текстовый формат
text_raw = " ".join(text)
# готовим размер картинки
wordcloud = WordCloud(width=1600, height=800).generate(text_raw)
plt.figure( figsize=(20,10), facecolor='k')
# добавляем туда облако слов
plt.imshow(wordcloud)
# выключаем оси и подписи
plt.axis("off")
# убираем рамку вокруг
plt.tight_layout(pad=0)
# выводим картинку на экран
plt.show()
Точно так же получаем картинки для второго, третьего и четвёртого тома — просто меняем название файла в первой команде скрипта и запускаем код:
Что с этим можно сделать
Вот несколько идей:
- Подразбить тома на главы и посмотреть на частотность на микроуровне.
- Докрутить токенизатор, возвращая все слова в начальную форму, и проанализировать снова.
- Докрутить токенизатор, чтобы он отдельно смотрел на существительные, отдельно — на прилагательные, отдельно — на глаголы. В идеале ещё отделить имена людей и имена собственные.
- Заменить частотность на анализ связей: например, что чаще всего делал Пьер или Наташа?
- Насобирать своих старых текстов из соцсетей и проанализировать, как вы менялись с годами: какие слова использовали. Для этого сначала напарсить сайт, не привлекая внимания.
- Записать свою устную речь, расшифровать через облако и найти слова-паразиты.
- То же самое, но с другими людьми.
- Напарсить текстов какого-нибудь издания до того, как сменилась команда, и после.
- Насобирать новостных сюжетов за год и построить карту популярных слов в течение года.
- Ничего из этого не делать, а открыть API-платформу OpenAI и натренировать нейронку на всём корпусе текстов Толстого.
Что-то из этого мы сделаем в будущем. Или это вы сделаете сами, потому что пойдёте заниматься дата-сайенсом впереди нас.