Интересное применение WordCloud

08b6f6b0dd7af3d1561af8fd284e5e24.jpeg

Всем привет! Хочу продемонстрировать вам, как я использовал библиотеку WordCloud для создания подарка для друга/подруги. Я решил составить облако слов по переписке с человеком, чтобы выделить основные темы, которые мы обсуждаем.

Выгружаем переписку

Для начала нам нужно будет выгрузить переписку из ВК. Как это сделать? Очень просто! Я пользовался расширением для браузера «VkOpt». Скачиваем его и устанавливаем. Теперь заходим в диалог с человеком, переписку с которым хотим скачать.

image-loader.svg

Наводим на три точки и выбираем «сохранить переписку». Далее будет окно с выбором типа файла. Я предпочитаю json.

Обработка переписки

Импортируем json и открываем наш файл с перепиской.

import json
vk = open('vk2.json', 'r', encoding='utf8')
vk = json.load(vk)

Теперь давайте выведем его и посмотрим как он выглядит.

image-loader.svg

Ну в общем всё ясно, массив таких вот сообщений. Каждый элемент соответствует одному облако-сообщению.

Давайте теперь вытащим из каждого сообщения его текст и разделим этот текст на слова.

mas = []
for i in range(len(vk)):
    mas.append(vk[i]['body'].split())
    
data = []
for i in mas:
    for j in range(len(i)):
        data.append(i[j].lower())

Теперь у нас есть массив data, в котором каждый элемент — это одно слово. Далее создадим большую строку, в которую просто запишем через пробел все наши слова.

big_string=''
for i in range(len(data)):
    big_string+=(data[i]+' ')

WordCloud

Почти всё готово, теперь давайте воспользуемся библиотекой WordCloud и построим наше облако слов.

pip install wordcloud

import matplotlib.pyplot as plt
%matplotlib inline

from wordcloud import WordCloud, STOPWORDS
wordCloud = WordCloud(width = 10000, height = 10000, random_state=1, background_color='black', colormap='Set2', collocations=False).generate(big_string)

plt.figure(figsize=(5,5))
plt.imshow(wordCloud)

image-loader.svg

Убираем стоп-слова

Так, и что же это? Не очень похоже на оригинальный подарок. Естественно всё не так просто. Дело в том, что в нашей речи и сообщениях встречается куча стоп-слов. Собственно, эти слова вы и видите на картинке. Они встречались в диалоге чаще всего, поэтому алгоритм выделил их крупным шрифтом.

Теперь наша задача: почистить строку от ненужный слов. Для этого скачаем словарик стоп-слов русского языка (https://snipp.ru/seo/stop-ru-words). Он представлен как обычный txt-шник, а значит прочитаем его и разделим по переносу строки.

stop_words = open('stop-ru.txt', 'r', encoding='utf8')
stop_words = stop_words.read()
stop_words = stop_words.split('\n')

Далее создадим массив clear_data, куда будем заносить слова из массива data, которые не содержатся в списке стоп-слов (т. е. нормальные слова).

clear_data=[]
for i in data:
    if(i not in stop_words):
        clear_data.append(i)

А теперь формируем нашу большую строку, только теперь из нового массива и заново строим WordCloud.

big_string=''
for i in range(len(clear_data)):
    big_string+=(clear_data[i]+' ')
    
wordCloud = WordCloud(width = 10000, height = 10000, random_state=1, background_color='black', colormap='Set2', collocations=False).generate(big_string)
plt.figure(figsize=(5,5))
plt.imshow(wordCloud)

image-loader.svg

Результат на лицо. Начинает проявляться оттенок переписки с тем или иным человеком. Ну и, естественно, куда же мы русского могучего, он тоже начинает проявляться на изображении, приходится его замазывать :)

Переходим на ручное управление

Так, вроде стоп-слова убрали, но картинка всё равно не выглядит привлекательной. В выборке остались различные выражения, которые мы часто используем в переписке. Например, мои слова паразиты: «ок», «ща», «крч». Что делать? Все просто. Открываем наш текстовик с русскими стоп-слова и просто вписываем туда слова, которые не должны присутствовать в новом облаке слов (не забудьте сохранить текстовик, перед повторным чтением).

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

stopw = ['а', 'ок', 'крч'] #массив слов, которые хотим удалить
#подадим массив stopw в WordCloud как параметр stopwords
wordCloud = WordCloud(width = 1000, height = 1000, random_state=1, 
                      background_color='black', colormap='Set2', 
                      collocations=False, stopwords=stopw).generate(big_string)

Таким образом, мы всё глубже и глубже погружаемся в чертоги нашей переписки. Обычно появляются слова, соответствующие темам, которые вы и ваш друг часто обсуждаете.

Форма облака слов

Теперь давайте воспользуемся одной фишкой WordCloud. Оформим наше облако слов в виде какой-то картинки. Я выберу банальное сердечко)

from PIL import Image
original_image = Image.open('путь до картинки')
image = original_image.resize([2000,2000], Image.ANTIALIAS)
image = np.array(image)

Подадим в функцию нашу картинку как параметр mask.

wordCloud = WordCloud(width = 1000, height = 1000, random_state=1, 
                      background_color='black', colormap='Set2', 
                      collocations=False, stopwords=stopw, mask=image).generate(big_string)

image-loader.svg

Вот такая штука у меня получилась.

По-хорошему, нужно удалить ещё около десятка слов, для более-менее приятной картины, но я уверен ту вы справитесь сами)

P.S. Выбирайте черно-белые изображения предметов. Лучше всего, если они выглядят как силуэты. С .png у меня не прошло, поэтому я сохранял в .jpg, может быть у вас получится.

Итог

Я нарисовал облако слов, которое отражает тональность переписки с тем или иным человеком. Дополнительно, в облаке содержатся слова, которые соответствуют тем темам, которые вы часто обсуждали в диалоге. Как вариант, можно сохранить эту картинку, распечатать, поставить в рамочку и вручить как подарок вашему собеседнику. Ему будет очень приятно, ведь всегда интересно посмотреть на то, как оценивает вашу переписку алгоритм)

© Habrahabr.ru