Анализируем самые частые слова в любом тексте
medium

Анализируем самые частые слова в любом тексте

Льву Толстому приготовиться

Мы уже анализировали самые частые слова в тексте, но делали это быстро, на коленке и с помощью Экселя. Теперь подойдём к этому серьёзно и используем дата-сайенс и Python — с ним такой анализ будет проще, быстрее и эффективнее. Заодно научимся делать такое красивое облако самых частых слов — это из первого тома «Войны и мира»:

Что делаем

Сегодня мы проанализируем текст всех томов «Войны и мира» и посмотрим, изменятся ли самые частые слова, как это будет выглядеть в облаке. Интересно, можно ли по таким облакам хотя бы примерно понять общее настроение или содержание текста.

Логика будет простая:

  1. Скачиваем четыре тома, каждый отдельным текстовым файлом.
  2. Пишем алгоритм, который проанализирует слова в первом томе.
  3. Генерируем для него облако слов.
  4. Меняем имя файла в программе и получаем картинки для трёх оставшихся томов.
  5. Смотрим, что получилось, и сравниваем картинки между собой.

Вместо художественного текста анализировать так можно что угодно: статьи «Кода», записи в дневнике или инструкцию от пылесоса.

Загружаем текст

Мы всё будем делать в редакторе 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, нам понадобится сделать такое:

  1. В терминале VS Code выполнить команду python (или python3). Запустится среда выполнения Python, в которой мы будем дальше работать.
  2. Пишем и выполняем команду import nltk — она подгрузит библиотеку в Python.
  3. После этого установим нужный модуль командой nltk.download('word_tokenize')
  4. Также можем сразу установить второй модуль, который мы будем использовать: nltk.download('stopwords').
  5. Выходим из среды 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()
Чтобы сохранить картинку, надо нажать значок дискеты в нижнем меню

Точно так же получаем картинки для второго, третьего и четвёртого тома — просто меняем название файла в первой команде скрипта и запускаем код:

Второй том — главным персонажем становится Наташа, за ней с большим отрывом идут Пьер и князь Андрей
Третий том — вперёд выходят Пьер и Наполеон, а за ними с большим отставанием все остальные
Четвёртый том — всё вращается вокруг Пьера и Наташи

Что с этим можно сделать

Вот несколько идей:

  1. Подразбить тома на главы и посмотреть на частотность на микроуровне.
  2. Докрутить токенизатор, возвращая все слова в начальную форму, и проанализировать снова.
  3. Докрутить токенизатор, чтобы он отдельно смотрел на существительные, отдельно — на прилагательные, отдельно — на глаголы. В идеале ещё отделить имена людей и имена собственные.
  4. Заменить частотность на анализ связей: например, что чаще всего делал Пьер или Наташа? 
  5. Насобирать своих старых текстов из соцсетей и проанализировать, как вы менялись с годами: какие слова использовали. Для этого сначала напарсить сайт, не привлекая внимания. 
  6. Записать свою устную речь, расшифровать через облако и найти слова-паразиты.
  7. То же самое, но с другими людьми.
  8. Напарсить текстов какого-нибудь издания до того, как сменилась команда, и после.
  9. Насобирать новостных сюжетов за год и построить карту популярных слов в течение года.
  10. Ничего из этого не делать, а открыть API-платформу OpenAI и натренировать нейронку на всём корпусе текстов Толстого. 

Что-то из этого мы сделаем в будущем. Или это вы сделаете сами, потому что пойдёте заниматься дата-сайенсом впереди нас.

Код:

Айрат Галлямов (@metaformus)

Художник:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Виталий Вебер

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Вам может быть интересно
medium
[anycomment]
Exit mobile version