
Облако слов в Python представляет собой визуализированный набор слов с наибольшей частотой использования в тексте или базе данных. Чем чаще встречается слово в источнике, тем большим размером шрифта оно написано в облаке слов. Таким образом, благодаря визуальным эффектам, читатель с первого взгляда на, казалось бы, мило перемешанную кашу из слов, способен сформировать общее представление о сути текста или содержимого базы данных. Выходит, эта «каша» — весьма полезное блюдо для анализа данных, поэтому самое время взглянуть на рецепт приготовления и сформировать облако слов в Python!
В качестве примера мы рассмотрим датасет с информацией о статьях текущего сайта. Сформируем облако слов в Python на основе текстовой информации из колонки «Title». Действовать будем поэтапно:
- Сначала мы загрузим датасет
- После этого познакомимся с основным принципом создания облака слов и сформируем стандартное прямоугольное облако на неочищенных данных.
- Затем, используя функции препроцессинга текста, преобразуем наши данные и выведем прямоугольное облако на подготовленных данных.
- И в заключение, сформируем облако слов в виде фигуры, загруженной в качестве маски из jpg-изображения. В нашем случае это будет фигура самолета.
Итак, открываем редактор, потому как пришло время покодить!
1. Загружаем датасет
Скачать файл с данными можно по ссылке: «articles.csv». Для загрузки датасета нам необходимо импортировать библиотеку pandas, после чего можно загружать данные из файла в переменную data с помощью функции open(). Так как у меня датасет находится в одной папке со скриптом, то относительный путь, передаваемый в качестве аргумента функции open(), совпадает с названием файла:
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv("articles.csv")
data.head()

Отлично, данные загружены, можно приступать к созданию облака слов!
2. Создаем первое облако слов в Python — знакомимся с основным принципом на сырых данных:
Сейчас мы намеренно пропустим процесс подготовки данных, чтобы посмотреть, какое облако слов сформируется из сырого текста. Единственное, что нам потребуется сделать — это объединить данные из колонки «Title» в один текст. Это легко сделать с помощью функции «join» — добавленная строка выделена подсветкой:
import pandas as pd
# Считываем содержимое файла в переменную data
data = pd.read_csv("articles.csv")
data.head()
# Объединяем данные из колонки 'Title'
text = ' '.join(data['Title'])
А теперь загрузим класс WordCloud из библиотеки wordcloud и сгенерируем облако слов с помощью функции generate(). В качестве аргумента функции generate() передадим наш текст. После этого выведем сгенерированное облако с помощью библиотеки matplotlib. Добавленные на этом этапе строки выделены в коде подсветкой:
import pandas as pd
import matplotlib.pyplot as plt
# загружаем класс WordCloud из библиотеки wordcloud
from wordcloud import WordCloud
data = pd.read_csv("articles.csv")
text = ' '.join(data['Title'])
# Генерируем облако слов и сохраняем в переменной cloud
cloud = WordCloud().generate(text)
# Выводим облако слов на экран
plt.imshow(cloud)
# Отключаем отображение осей
plt.axis('off')
В результате исполнения кода, получим:

3. Осуществляем предобработку текста
3.1. Удаляем стоп-слова
На первый взгляд, получилось довольно приятное облако. Однако, после второго взгляда хочется воскликнуть: «Обманули! Подменили!..» и так далее. Ведь мы на самом деле ожидали, что крупным шрифтом будут написаны основные значащие слова, а вместо этого на переднем плане оказались теряющие смысл без контекста предлоги: «как, в, на, и». Эти предлоги называются стоп-словами, и они действительно чаще всего используются в нашей речи, однако в большинстве случаев при анализе текста, являются лишним шумом. Этот фактор был учтен создателями библиотеки wordcloud, и для объекта облака слова WordCloud() был добавлен параметр stopwords. По умолчанию, значение этого параметра «None», это значит, что функция использует встроенный список стоп-слов, среди которых присутствуют английские слова, но нет русских. Поэтому при выводе облака слов на основе английского текста, не нужно менять значение параметра stopwords — предлоги, союзы и прочие артикли будут исключены автоматически. В нашем же случае, необходимо передать параметру stopwords список со стоп-словами русского языка. Этот список есть в библиотеке nltk. Давайте это сделаем! (добавленные строки выделены подсветкой):
import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# подгружаем библиотеку nltk со стоп-словами
from nltk.corpus import stopwords
# сохраняем список с русскими стоп-cловами в переменную stop_words
stop_words = stopwords.words('russian')
data = pd.read_csv("articles.csv")
text = ' '.join(data['Title'])
# Определяем параметр stopwords при создании объекта облака слов
cloud = WordCloud(stopwords=stop_words).generate(text)
plt.imshow(cloud)
plt.axis('off')

3.2. Разбиваем текст на токены и получаем леммы
Отлично! Теперь предлоги исчезли из облака слов! Однако, выводятся слова с разными склонениями, такие как «помощи», «изображений», «файла» и т. д. Конечно, можно оставить оставить эти слова в покое, однако я предлагаю добавить немного строк кода, чтобы привести их все к основной форме до загрузки текста в функцию generate(). Для этого мы будем использовать библиотеку созданную для лемматизации русского и украинского языков под названием pymorphy2. Однако, предварительно, нам потребуется разбить текст на слова, другими словами, токенизировать текст:
import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Импортируем библиотеку для лемматизации русских и украинских слов
import pymorphy2
# Импортируем метод word_tokenize из библиотеки nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
stop_words = stopwords.words('russian')
data = pd.read_csv("articles.csv")
text = ' '.join(data['Title'])
# разбиваем текст на токены
# в результате получаем переменную типа list со списком токенов
text = word_tokenize(text)
# инициализируем лемматайзер MorphAnalyzer()
lemmatizer = pymorphy2.MorphAnalyzer()
# функция для лемматизации текста, на вхд принимает список токенов
def lemmatize_text(tokens):
# создаем переменную для хранения преобразованного текста
text_new=''
# для каждого токена в тексте
for word in tokens:
# с помощью лемматайзера получаем основную форму
word = lemmatizer.parse(word)
# добавляем полученную лемму в переменную с преобразованным текстом
text_new = text_new + ' ' + word[0].normal_form
# возвращаем преобразованный текст
return text_new
# вызываем функцию лемматизации для списка токенов исходного текста
text = lemmatize_text(text)
# генерируем облако слов
cloud = WordCloud(stopwords=stop_words).generate(text)
plt.imshow(cloud)
plt.axis('off')
В код была добавлена токенизация исходного текста, а также функция для лемматизации полученного списка токенов <strong>lemmatize_text()</strong>. По завершению цикла <strong>for</strong> функция <strong>lemmatize_text()</strong> возвращает строку с преобразованным текстом, прошедшим через токенизацию и лемматизацию! Посмотрим на результат:

Отлично! Теперь содержание нашего облака на высоте, а значит, пришло время побаловаться с параметрами WordCloud и поправить обертку! Для начала я предлагаю изменить форму облака слов!
4. Меняем форму облака слов
Чтобы изменить форму облака слов, нужно:
- Загрузить изображение, которое будет использоваться в качестве маски при формировании облака, и преобразовать его в матрицу
- Передать параметру mask в качестве значения полученную матрицу
- По желанию добавить параметры обводки полученной фигуры: contour_width и contour_color
Реализуем задуманное: загрузим изображение «plane.jpg» и определим параметры в WordCloud():
import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import pymorphy2
import nltk
from PIL import Image
# импортируем библиотеку numpy для преобразования изображения в массив
import numpy as np
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
stop_words = stopwords.words('russian')
data = pd.read_csv("articles.csv")
text = ' '.join(data['Title'])
text = word_tokenize(text)
lemmatizer = pymorphy2.MorphAnalyzer()
def lemmatize_text(tokens):
text_new=''
for word in tokens:
word = lemmatizer.parse(word)
text_new = text_new + ' ' + word[0].normal_form
return text_new
text = lemmatize_text(text)
# загружаем изображение с самолетом и преобразуем в матрицу
cake_mask = np.array(Image.open('plane.jpg'))
# генерируем облако слов
cloud = WordCloud(stopwords=stop_words, mask=cake_mask, contour_width=10, contour_color='#2e3043').generate(text)
# увеличим размер выводимой фигуры
plt.figure(figsize=(9,5))
plt.imshow(cloud)
plt.axis('off')
Посмотрим на результат:

Неплохо, однако, не мешало бы поиграться с параметрами WordCloud, изменить размеры изображения и цвета на свой вкус.

Редактируем облако слов в Python: меняем фон, цветовую схему и максимальное количество слов
У объекта WordCloud довольно много настраиваемых параметров. Описание всех параметров можно найти по ссылке в документации. Сейчас мы изменим значения лишь некоторых из них:
- background_color — цвет фона, заданный по умолчанию черный цвет фона я хочу поменять на background-color=’#272d3b’
- colormap — цветовая схема — это набор цветов, которыми будут раскрашены буквы в облаке слов. Полный набор цветовых схем можно посмотреть по ссылке: Цветовые схемы matplotlib. Я установлю значение colormap=’Set3′
- Максимальное количество слов в облаке — параметр max_words. Уменьшу количество слов до 80, max_words=80
Таким образом, после внесенных изменений итоговый код имеет вид:
import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import pymorphy2
import nltk
from PIL import Image
# импортируем библиотеку numpy для преобразования изображения в массив
import numpy as np
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
stop_words = stopwords.words('russian')
data = pd.read_csv("articles.csv")
text = ' '.join(data['Title'])
text = word_tokenize(text)
lemmatizer = pymorphy2.MorphAnalyzer()
def lemmatize_text(tokens):
text_new=''
for word in tokens:
word = lemmatizer.parse(word)
text_new = text_new + ' ' + word[0].normal_form
return text_new
text = lemmatize_text(text)
# загружаем изображение с самолетом и преобразуем в матрицу
cake_mask = np.array(Image.open('plane.jpg'))
# генерируем облако слов
cloud = WordCloud(stopwords=stop_words, mask=cake_mask, contour_width=10, contour_color='#2e3043', background_color='#272d3b', colormap='Set3', max_words=80).generate(text)
# увеличим размер выводимой фигуры
plt.figure(figsize=(9,5))
plt.imshow(cloud)
plt.axis('off')
Отлично! Теперь полученное облако слов выводится в виде симпатичного самолета:

Заключение:
Поздравляю вас с успешно проделанной работой! Мы изучили основной принцип формирования облака слов в Python, подготовили русский текст для формирования корректного облака, а также научились менять цвет и форму облака слов. В итоге у нас получилось 2 вида облаков: стандартное облако в виде прямоугольника, и облако в форме самолета!
Добрый день! Пробовал сделать тоже самое, но питон не видит словари. Пишет вот такую ошибку:
ValueError: Can’t find dictionaries. Please either pass a path to dictionaries, or install ‘pymorphy2-dicts’ package, or set PYMORPHY2_DICT_PATH environment variable.
Можете посоветовать что делать?
Снимается )
Разобрался