Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Воган Ли - Python для хакеров (Библиотека программиста) - 2023.pdf
Скачиваний:
3
Добавлен:
07.04.2024
Размер:
14.76 Mб
Скачать

100      Глава3. Суммаризация текстаспомощьюобработкиестественногоязыка

things right.And, if by chance you have a miserable day, you will come home to a bed that is made — that you made — and a made bed gives you encouragement that tomorrow will be better.If you want to change the world, start off by making your bed.During SEAL training the students are broken down into boat crews. Basic SEAL training is six months of long torturous runs in the soft sand, midnight swims in the cold water off San Diego, obstacle courses, unending calisthenics, days without sleep and always being cold, wet and miserable.

Если вы прочтете всю речь, то наверняка решите, что gensim создает прекрасную суммаризацию. Несмотря на то что эти два результата отличаются, они оба вобрали основные моменты речи, включая фрагмент о заправке кровати. Учитывая размер документа, я нахожу этот результат впечатляющим.

Далее мы рассмотрим другой способ суммаризации текста при помощи слов и облака слов.

Проект #5. Суммаризация речи с помощью облака слов

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

Облако слов позволяет выделять ключевые слова в документе. К примеру, генерация облака слов для каждого доклада президента США конгрессу о положении дел в стране может быстро предоставить обзор проблем, с которыми столкнулось государство в текущем году. В первый год президентства Билл Клинтон делал акцент на проблемах мирного времени, таких как здравоохранение, трудовая занятость населения и налоги (рис. 3.1).

Рис. 3.1. Облако слов, созданное из доклада Билла Клинтона Конгрессу США в 1993 году

Проект #5. Суммаризация речи с помощью облака слов      101

Менее чем через 10 лет облако слов Джорджа Буша демонстрирует уже приоритеты в области государственной безопасности (рис. 3.2).

Рис. 3.2. Облако слов, созданное из доклада Джорджа Буша Конгрессу США в 2002 году

Еще одно применение облака слов — извлечение ключевых слов из отзывов покупателей. Если обнаружится преобладание таких слов, как плохой, медленный и дорогой, то это указывает на проблему. Писатели могут также использовать облако для сравнения глав книги или сцен в киносценарии. Если автор использует схожую лексику для экшн-сцен и романтических интерлюдий, то потребуется редактирование. Копирайтеры могут с помощью облака проверять плотность ключевых слов для оптимизации в поисковых системах (SEO).

Генерировать облако слов можно многими способами, включая использование бесплатных сайтов вроде https://www.wordclouds.com/ и https://www.jasondavies.com/wordcloud/. Но если вы хотите

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

Вместо использования базового прямоугольника, показанного на рис. 3.1 и 3.2, мы будем вписывать слова в контур головы Шерлока Холмса (рис. 3.3).

Так у нас получится более узнаваемое

Рис. 3.3. Силуэт Шерлока Холмса

и привлекательное представление.

 

102      Глава3. Суммаризация текстаспомощьюобработкиестественногоязыка

ЗАДАЧА

Использовать модуль wordcloud для генерации фигурного облака слов из повести о Шерлоке Холмсе.

Модули Word Cloud и PIL

Для генерации облака слов мы используем модуль wordcloud. Установите его с помощью pip.

pip install wordcloud

В случае использования Anaconda введите команду:

conda install -c conda-forge wordcloud

Страница модуля wordcloud находится на http://amueller.github.io/word_cloud/.

Вам также понадобится Python Imaging Library (PIL) для работы с изображениями. Для ее установки также используйте pip.

pip install pillow

А в случае с Anaconda введите команду:

conda install -c anaconda pillow

К слову, pillow является проектом-преемником PIL, поддержка которого была прекращена в 2011 году. Более подробно о нем можете узнать на https://pillow. readthedocs.io/en/stable/.

Код для создания облака слов

Для создания фигурного облака слов потребуются файл изображения и текстовый файл. Изображение, показанное на рис. 3.3, взято с площадки iStock by Getty Images (https://www.istockphoto.com/vector/detective-hat-gm698950970-129478957/). Разрешение этой картинки составляет всего 500 × 600 пикселей.

Схожее изображение, но уже без авторских прав (holmes.png) содержится среди доступных для скачивания файлов книги. Текстовый файл (hound.txt), файл изображения (holmes.png) и код (wc_hound.py) находятся в каталоге Chapter_3.

Импорт модулей, текстовых файлов, файлов изображений и стоп-слов

В листинге 3.8 мы импортируем модули, скачаем роман и изображение силуэта Холмса, а также создадим множество стоп-слов, которые нужно исключить из облака.

Проект #5. Суммаризация речи с помощью облака слов      103

Листинг 3.8. Импорт модулей и скачивание текста, изображения, а также стоп-слов

wc_hound.py, часть 1

import numpy as np from PIL import Image

import matplotlib.pyplot as plt

from wordcloud import WordCloud, STOPWORDS

# Загрузка текстового файла как строки.

with open('hound.txt') as infile:

text = infile.read()

#Скачивание изображения в виде массива NumPy. mask = np.array(Image.open('holmes.png'))

#Получение стоп-слов в виде множества и добавление дополнительных слов. stopwords = STOPWORDS

stopwords.update(['us', 'one', 'will', 'said', 'now', 'well', 'man', 'may',

'little', 'say', 'must', 'way', 'long', 'yet', 'mean', 'put', 'seem', 'asked', 'made', 'half', 'much', 'certainly', 'might', 'came'])

Начинаем с импорта NumPy и PIL. PIL открывает изображение, а NumPy преобразовывает его в маску. Использовать NumPy мы начали в главе 1. Если же вы эту главу пропустили, то обратитесь к разделу «Установка библиотек Python» на с. 31. Имейте в виду, что модуль pillow продолжает использовать акроним PIL для обратной совместимости.

Для отображения облака слов понадобится matplotlib, которую вы скачали в том же разделе «Установка библиотек Python» главы 1. Модуль wordcloud содержит собственный список стоп-слов, поэтому импортируйте STOPWORDS вместе с функциональностью облака.

Далее скачайте текстовый файл романа и сохраните его в переменной text . Как я говорил, описывая листинг 2.2 главы 2, при скачивании текста вы можете столкнуться с ошибкой UnicodeDecodeError.

UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 365: ordinal not in range(128)

В этом случае попробуйте изменить функцию open(), добавив аргументы encoding и errors.

with open('hound.txt', encoding='utf-8', errors='ignore') as infile:

После скачивания текста примените метод PIL Image.open(), чтобы открыть изображение Холмса, и с помощью NumPy преобразуйте его в массив. Если вы используете изображение с iStock, то измените соответствующим образом название файла.

104      Глава3. Суммаризация текстаспомощьюобработкиестественногоязыка

Далее присваиваем множество STOPWORDS, импортированное с wordcloud, переменной stopwords. Затем обновляем это множество списком дополнительных слов, которые нужно исключить . К ним относятся такие слова, как said и now, которые доминируют в облаке, но полезной информации не несут. Определение подобных слов происходит итеративно. Генерируется облако слов, из которого удаляются слова, не несущие смысловой нагрузки, после чего процесс повторяется. Если хотите увидеть конкретное влияние этой строки, можете ее закомментировать.

ПРИМЕЧАНИЕ

ЧтобыобновитьконтейнервродеSTOPWORDS,нужнознать,являетсялионсписком, словарем, множеством или чем-то другим. Встроенная в Python функция type() возвращает тип класса любого объекта, переданного ей в качестве аргумента. В этом случае команда print(type(STOPWORDS)) дает <class 'set'>.

Генерация облака слов

Код листинга 3.9 генерирует облако слов и задействует силуэт в качестве маски, иначе говоря, изображения, используемого для сокрытия другого изображения. Процесс, применяемый wordcloud, достаточно продуман, чтобы вписать слова в маску, а не просто обрезать их по краям. Кроме того, для изменения представления слов внутри маски также доступно множество параметров.

Листинг 3.9. Генерация облака слов wc_hound.py, часть 2

wc = WordCloud(max_words=500, relative_scaling=0.5, mask=mask, background_color='white', stopwords=stopwords, margin=2, random_state=7, contour_width=2, contour_color='brown',

colormap='copper').generate(text)

colors = wc.to_array()

Называем переменную wc и вызываем WordCloud(). Здесь множество параметров, так что я поместил каждый на отдельную строку для наглядности. Список и описание всех доступных параметров вы найдете на https://amueller.github.io/ word_cloud/generated/wordcloud.WordCloud.html.

Начинаем с передачи максимального количества слов, которое хотим использовать. Заданная вами величина будет означать n наиболее распространенных

Проект #5. Суммаризация речи с помощью облака слов      105

слов в тексте. Чем больше слов выбрано для показа, тем проще определить края маски и сделать ее узнаваемой. К сожалению, ввод слишком большого значения для максимума приводит к появлению большого числа мелких, неразборчивых слов. Для данного проекта начнем со значения 500.

Далее для управления размером шрифта и относительной важностью каждого слова устанавливаем для параметра relative_scaling значение 0.5. К примеру, при значении 0 предпочтение при выборе размера шрифта отдается рангу слова, а при значении 1 слова, встречающиеся вдвое чаще, будут иметь вдвое больший размер. Значения между 0 и 0.5 определяют оптимальный баланс между рангом и частотностью.

Ссылаемся на переменную mask и устанавливаем ее фоновый цвет как white. Если цвет не присвоить, то он по умолчанию — черный. Далее ссылаемся на множество stopwords, которое мы редактировали в предыдущем листинге.

Параметр margin регулирует интервалы между отображаемыми словами. При значении 0 слова будут расположены очень плотно. При значении 2 между ними уже будет некоторое расстояние.

Для размещения слов по облаку мы используем генератор случайных чисел и устанавливаем значение random_state как 7. В этом значении нет ничего особенного. Просто мне показалось, что при его использовании слова располагаются наиболее привлекательным образом.

Параметр random_state фиксирует стартовое число, чтобы результаты удалось повторить при условии сохранения других параметров. Это означает, что слова всегда будут упорядочены одинаково. Здесь можно установить только целочисленное значение.

Теперь задаем для contour_width значение 2. Любое значение больше нуля создает вокруг маски контур. В данном случае контур волнистый, что обусловлено разрешением изображения (рис. 3.4).

Спомощью параметра contour_color устанавливаем цвет контура как brown. Продолжаем использовать оттенки коричневого, установив colormap как copper. В matplotlib colormap — это словарь, отображающий числа в цвета. Цветовая карта copper создает текст с окраской в диапазоне от бледно-телесного до черного. Его спектр, как и другие опции цвета, можно посмотреть на странице https:// matplotlib.org/stable/gallery/color/colormap_reference.html. Если цветовую карту не задать, то программа будет использовать предустановленные цвета.

Спомощью точечной нотации вызываем метод generate() для построения облака слов. Передаем ему в качестве аргумента строку text. Завершается листинг именованием переменной colors и вызовом метода to_array() для объекта wc.

106      Глава3. Суммаризация текстаспомощьюобработкиестественногоязыка

Этот метод преобразует изображение облака слов в массив NumPy для дальнейшего использования с помощью matplotlib.

Рис. 3.4. Пример облака слов в маске с контуром (слева) и без (справа)

Отрисовка облака слов

Код листинга 3.10 добавляет облаку слов заголовок и использует matplotlib для его отображения. Он также сохраняет изображение облака слов в виде файла.

Листинг 3.10. Отображение и сохранение облака слов wc_hound.py, part 3

plt.figure()

plt.title("Chamberlain Hunt Academy Senior Class Presents:\n", fontsize=15, color='brown')

plt.text(-10, 0, "The Hound of the Baskervilles", fontsize=20, fontweight='bold', color='brown')

plt.suptitle("7:00 pm May 10-12 McComb Auditorium", x=0.52, y=0.095, fontsize=15, color='brown')

plt.imshow(colors, interpolation="bilinear") plt.axis('off')

plt.show() ##plt.savefig('hound_wordcloud.png')

В начале инициализируем рисунок matplotlib, затем вызываем метод title(), в который передаем название школы («Chamberian Hunt Academy Senior Class presents»), а также размер шрифта и его цвет.

Нам нужно, чтобы название спектакля было крупнее и жирнее других заголовков. Поскольку с помощью matplotlib изменить стиль текста в строке нельзя, мы используем метод text() для определения нового заголовка. В него передаем

Проект #5. Суммаризация речи с помощью облака слов      107

координаты (x, y) согласно осям рисунка, текстовую строку и детали стиля текста. Оптимальные координаты для размещения текста мы подбираем методом проб и ошибок. При использовании изображения Холмса с iStock вам может потребоваться изменить координату x с -10 на другое значение, чтобы добиться гармонии с асимметричным силуэтом.

Завершаем заголовки, указывая время и место проведения спектакля в нижней части рисунка. Можно снова использовать метод text(), но вместо этого мы воспользуемся его альтернативой — методом suptitle() из коллекции функций pyplot. Название метода означает «суперзаголовки». Передаем ему текст, координаты рисунка (x, y) и детали стилизации.

Для отображения облака слов вызываем imshow(), чтобы показать изображение, и передаем ему ранее созданный массив colors. Для интерполяции цветов указываем bilinear.

Отключаем оси рисунка и отображаем облако слов через вызов show(). Если вы хотите сохранить рисунок, раскомментируйте метод savefig(). Имейте в виду, что matplotlib может считывать расширение в имени файла и сохранять рисунок в верном формате. Как уже говорилось, команда сохранения не будет выполняться, пока вы вручную не закроете рисунок.

Настройка облака слов

Код листинга 3.10 создает облако слов, показанное на рис. 3.5. У вас может получиться иное расположение слов, поскольку алгоритм здесь стохастический.

Рис. 3.5. Флаер, сгенерированный кодом wc_hound.py

108      Глава3. Суммаризация текстаспомощьюобработкиестественногоязыка

Размер изображения можно изменить, добавив аргумент при инициализации рисунка. Вот пример: plt.figure(figsize=(50, 60)).

Известно и множество других способов изменить результат. Например, если установить параметр margin равным 10, то облако слов получится менее плотным (рис. 3.6).

Рис. 3.6. Облако слов, сгенерированное с margin=10

Изменение параметра random_state также изменит расположение слов в маске (рис. 3.7).

Рис. 3.7. Облако слов, сгенерированное с margin=10 и random_state=6