Во время недавнего проекта НЛП я наткнулся на статью, в которой облака слов были созданы в форме президентов США, используя слова из их инаугурационных речей. Хотя я использовал облака слов для визуализации наиболее часто встречающихся слов в документе, я не рассматривал возможность использования этого с маской для представления темы или предмета. Это заставило меня задуматься ...

Несколько месяцев назад, незадолго до финальной серии Игры Престолов и после того, как я только что пересмотрел 1–7 сезоны, я с нетерпением ждал финала - настолько, что я пошел искать любые данные Игры Престолов, которые мог найти в Интернете, чтобы создать предсказатель того, кто выживет в хаосе 8-го сезона и что произойдет в 7 Королевствах. К сожалению, у меня не было времени, но я нашел много данных и визуализаций, которые люди собрали вместе. Когда я натолкнулся на первые облака слов, я подумал, могу ли я использовать эти данные Игры престолов, особенно сценарии, с масками изображений персонажей для создания довольно крутых визуализаций. В этой статье, представленной на недавней технической встрече, я расскажу о своих шагах по созданию облака слов Игры Престолов с использованием Python.

Начиная

Следуя методу, аналогичному методу, описанному в первой статье об облаке слов, при работе с текстовыми данными необходимо выполнить несколько шагов. Шаги следующие:

  1. Поиск релевантных данных
  2. Данные очистки
  3. Создание маски из изображения
  4. Создание облаков слов

Так как я буду использовать python в этом руководстве, существует множество библиотек, которые помогут с вышеуказанными шагами, а также Руководство Дипанджана Саркара по обработке естественного языка предоставляет исчерпывающее введение в методы текстовой аналитики, если вы ищете дополнительную информацию по этой теме. .

Прежде чем приступить к первому шагу, я определил цель проекта, чтобы не пропустить ни одного важного шага и иметь четкое видение цели.

Цель проекта: создать облака слов для персонажей Игры престолов, замаскированных изображением.

1. Поиск релевантных данных

В Интернете доступно множество данных по Game Of Thrones - GitHub и Kaggle - это то место, где я обычно сначала ищу наборы данных - и я быстро нашел набор данных, содержащий скрипты.

Для достижения цели проекта необходимо указать линии для каждого персонажа. Первый вопрос: доступны ли линии символов?

Глядя на отрывок из первого эпизода, данные персонажей доступны! Однако при изучении дальнейших эпизодов и сезонов формат имен персонажей меняется.

В приведенном выше случае используется только имя персонажа и все это в верхнем регистре, в то время как в других сезонах полное имя персонажа используется с буквенным регистром. Сценические направления также могут быть включены в имя персонажа.

Для поиска всех строк по имени персонажа можно использовать регулярные выражения с именами персонажей:

re.findall(r'(^'+name+r'.*:.*)', line, re.IGNORECASE)

Это выражение ищет начало строки (^), за которым следует имя символа, которое мы вводим как переменная, за которым следует любой текст (. *), Затем двоеточие, чтобы указать, что это строка символа (:), а затем любым текстом (. *). Если это регулярное выражение заключено в квадратные скобки, возвращается вся строка. Наконец, регистр игнорируется, поэтому имя символа может быть в верхнем / нижнем / буквенном регистре.

Использование функции ниже вернет все строки для символа:

# final_data taken from:  
# https://github.com/shekharkoirala/Game_of_Thrones
# get data for characters
def get_char_lines(char):    
    output = []          
    print('Getting lines for', char)        

    with open('final_data.txt', 'r') as f:
        for line in f:
            if re.findall(r'(^'+char+r'.*:.*)',line,re.IGNORECASE):
                output.append(line)
    f.close()
    print(char, 'has ', len(output), 'lines')
return output
# get lines using
get_char_lines('arya')

2. Очистка данных

Теперь, когда у нас есть линии для персонажа, их нужно очистить.

Следующие техники используются для очистки линий, эти же техники также подробно описаны в упомянутом выше Руководстве по НЛП. Здесь снова полезны регулярные выражения для замены или удаления символов:

  • Удалить информацию о строке, например. JON:
re.sub(r'.*:', '', text)
  • Удалить скобки - убрать все направления сцены из символьных строк.
re.sub('[\(\[].*?[\)\]]', ' ', text)
  • Удалите символы с диакритическими знаками и нормализуйте их с помощью библиотеки unicodedata
unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('utf-8', 'ignore')
  • (Необязательно): примените лемматизацию, когда слово связано с корневым словом, которое есть в словаре, например. is, are → be
    В настоящее время не использует лемматизацию, так как она плохо обрабатывает некоторые слова, например. Станнис → Станни
  • Преобразовать весь текст в нижний регистр
text.lower()
  • Удалите специальные символы (* ,.!?) С возможностью удаления чисел - по умолчанию установлено значение false.
pattern = r'[^a-zA-Z0-9\s]' if not remove_digits else r'[^a-zA-Z\s]'    re.sub(pattern, '', text)
  • Удалите стоп-слова, используя стоп-слова из библиотеки nltk, сначала разметив текст, разбив строку на список подстрок, а затем удалив все стоп-слова
stopword_list = stopwords.words('english')    
tokens = nltk.word_tokenize(text)    
tokens = [token.strip() for token in tokens]    
' '.join([token for token in tokens if token not in stopword_list])

Эти методы очистки основаны на нескольких различных источниках, и существует множество вариантов этих этапов, а также дополнительные методы очистки, которые можно использовать. Эти начальные этапы очистки были использованы в этом проекте.

3. Создайте маску из изображения.

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

char_mask = np.array(Image.open("images/image.jpeg"))    image_colors = ImageColorGenerator(char_mask)

При желании массив numpy можно использовать с wordcloud.ImageColorGenerator, чтобы затем recolor облако слов для представления цветов изображения, или иначе. Это будет рассмотрено в следующем разделе.

После первоначального тестирования изображения как маски облака слов фон в изображении создавал слишком много шума, поэтому форма символа не была четко определена. Чтобы избежать этого, может быть полезно удалить фон изображения и заменить его белым фоном.

4. Создавайте облака слов

Последний шаг - создать облако слов с помощью функции generate().

wc = WordCloud(background_color="white", max_words=200, width=400, height=400, mask=char_mask, random_state=1).generate(text)
# to recolour the image
plt.imshow(wc.recolor(color_func=image_colors))

Облако слов будет замаскировано изображением, а размер текста будет зависеть от частоты встречаемости слов.

Параметры облака слов можно настроить - попробуйте увеличитьmax_words, чтобы увидеть некоторые из менее часто встречающихся слов, обратите внимание, что это должно быть меньше, чем количество уникальных слов в вашем документе.

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

Игра престолов облака слов

Используя описанные выше шаги с изображениями персонажей Игры престолов, сгенерированные облака слов представлены ниже:

Арья

Джон Сноу

Дейенерис

Сер Давос

Это также было расширено для создания облаков слов на основе домов:

Дом Ланнистеров

Дом Старков

С этими облаками слов первоначальная цель проекта была достигнута!

Улучшения

Эти облака слов можно улучшить несколькими способами.

  • Распространенные слова: встречаются повторяющиеся слова, которые являются общими для всех сценариев символов. В настоящее время облака слов создаются на основе частоты слов, однако альтернативой может быть функция TFIDF, которая взвешивает термины на основе частоты терминов в документе и частоты по отношению к корпусу. В качестве альтернативы можно создать собственный список стоп-слов, чтобы удалить другие часто встречающиеся слова.
  • Лемматизация / основание: лемматизация не использовалась в приведенных выше примерах, поскольку некоторые слова, уникальные для Игры престолов, были сокращены при тестировании (Станнис → Станни), однако это означает, что слова происходят от одного корня слова не связаны и встречаются несколько раз в облаке слов, например. говорят, сказал. Можно использовать альтернативный метод лемматизации или метод стемкинга.
  • Очистка текста. Можно выполнить дальнейшие действия по очистке или подготовке данных.
  • Возможности облака слов. Я тестировал слова с разными цветами, цветами фона и параметрами облака слов, серый цвет и черный фон работают в этом случае, но некоторые параметры можно оптимизировать.
  • Дальнейший анализ текста: из этого набора данных можно извлечь много полезной информации. Намного больше возможностей для анализа!

Расширение - Очень странные дела

Изучая дальнейшие шоу, я в конце концов нашел Скрипт очень странных дел - хотя в них отсутствуют символьные строки, данные все же можно использовать для создания облаков слов….

Резюме

В этой статье я прошел через основные шаги по созданию словесных облаков, замаскированных изображением.

Это только начало моих экспериментов с облаками слов! В проекте есть огромные возможности для дальнейшего развития и улучшения, я надеюсь, вы сможете выполнить шаги, чтобы создать свои собственные проекты с облаками слов! \

Спасибо за чтение! Если вам понравилась моя статья, то подпишитесь на мой ежемесячный информационный бюллетень, где вы сможете получать мои последние статьи и лучшие ресурсы прямо на ваш почтовый ящик!

Вы можете подписаться на меня на Medium, чтобы увидеть больше статей, подписаться на меня в Twitter или узнать больше о моих планах на моем веб-сайте.