Погружение в обработку естественного языка

*: код обновлен для Spacy 3.2

Вдохновение

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

Хайку - это не рифмованная поэтическая форма, состоящая всего из 17 слогов, которая обычно записывается в три строки с количеством слогов 5-7-5. Имея в руках инструменты Python и NLP (обработка естественного языка), мы можем запрограммировать машину хайку, которая берет произвольный абзац текста с одной стороны и выводит хайку с другой стороны.

Давайте погрузимся.

Библиотеки НЛП

Дебютировав в 2001 году, NLTK (набор инструментов для естественного языка) остается могучей силой и самой известной библиотекой НЛП на сегодняшний день. Его недостатки сложны и медленны. В 2012 году Том Де Смедт и Уолтер Дэлеманс разработали библиотеку под названием Pattern, которая включает анализ тональности и графиков. Более популярный TextBlob был разработан на основе Pattern и NLTK.

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

Для того, что мы собираемся здесь делать, я бы выбрал spaCy. spaCy работает быстро, так как он написан на Cython и разработан для готовности к использованию за счет включения предварительно обученных моделей для обработки общих задач. На досуге я бы порекомендовал вам посмотреть видео ниже от Мэтью Хоннибала и Инес Монтани, которые объяснили философию дизайна spaCy:

Настройка проекта

Настройка проекта проста с использованием Python 3. Нам нужны две библиотеки: spaCy для обработки текстов и syllapy для подсчета слогов. Мы уже знаем, что при составлении хайку необходимо количество слогов:

pip3 install -U spacy
pip3 install syllapy

После установки spaCy нам нужно загрузить языковую модель. spaCy поддерживает множество языков. Здесь мы будем использовать английский:

python3 -m spacy download en_core_web_sm

Чтение текста

Мы можем использовать любой текст в качестве ввода. Для этого упражнения я выбрал пару сотен слов из классического романа Джорджа Оруэлла 1984.

Создайте папку для нашего проекта, а затем откройте папку с Visual Studio Code. Создайте папку с именем data для хранения текстового файла. Затем создайте файл Python с именем z2poem.py.

В файле Python мы настраиваем spaCy. Внутри spaCy поддерживает конвейер для обработки текста. Его можно настроить, но настройка по умолчанию подходит для многих проектов.

Давайте загрузим языковую модель в конвейер nlp, а затем создадим документ doc для чтения в тексте:

import spacy
nlp = spacy.load("en_core_web_sm")
file = "data/orwell_1984.txt"
doc = nlp(open(file).read())

Соответствие шаблону на основе правил

Чтобы осуществить задумку стихотворения затемнения, нам нужно выделить фразу из абзаца текста. Чтобы сделать выбор подходящим для хайку, необходимо соблюдать определенные правила. Например, мы никогда не заканчиваем строку «the» и редко видим «of» в качестве последнего слова.

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

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

pattern = [{'POS': 'ADJ'},
           {'POS': 'NOUN'}]

POS означает часть речи. spaCy предоставляет нам интерактивный инструмент, с которым мы можем поиграть и обозначить используемые шаблоны. Затем мы можем скопировать и вставить их в нашу программу Python.

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

from spacy.matcher import Matcher
matcher4 = Matcher(nlp.vocab)
pattern = [{'POS':  {"IN": ["NOUN", "ADP", "ADJ", "ADV"]} }, 
{'IS_ASCII': True, 'IS_PUNCT': False, 'IS_SPACE': False},  {'IS_ASCII': True, 'IS_PUNCT': False, 'IS_SPACE': False}, {'POS':  {"IN": ["NOUN", "VERB", "ADJ", "ADV"]} }]
matcher4.add("FourWords", [pattern])

Количество слогов

Самый известный инструмент для подсчета слогов - это, вероятно, произношение CMU, но у него есть недостаток. На самом деле при произношении учитываются фонемы, а не слоги, а фонемы не всегда совпадают со слогами. Программа Майкла Хольцшера исправила эту проблему. Хотя произношение обеспечивает другие функции, мы с удовольствием используем слоговую , потому что она предлагает именно то, что нам нужно:

syllapy.count("word")

В соответствии с количеством слогов, фразы, соответствующие правилам, делятся на категории. Созданы два списка: один для словосочетаний из пяти слогов, а другой - для фраз из семи слогов. Все, что не входит в эти два списка, просто выбрасывается.

Композиция хайку

Самый простой способ - выбрать фразу из списка из пяти слогов, затем выбрать одну из семи, а затем снова выбрать из пяти слогов. Вот код, когда мы все собираем:

Тест Тьюринга

Программа может генерировать хайку за доли секунды. Я отправил один в House of Haiku, и он был принят, и мне интересно, заметил ли кто-нибудь, что хайку было сгенерировано программой.

Если кажется, что хайку мог написать человек, можем ли мы считать, что оно прошло тест Тьюринга?

Обсуждение

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

Ваше здоровье!