Работа с данными на естественном языке часто может быть сложной задачей из-за отсутствия структуры. Большинство специалистов по обработке данных, аналитиков и менеджеров по продуктам знакомы с структурированными таблицами, состоящими из строк и столбцов, но менее знакомы с неструктурированными документы, состоящие из предложений и слов. По этой причине знание того, как работать с набором данных на естественном языке, может быть довольно сложной задачей. В этом посте я хочу продемонстрировать, как вы можете использовать замечательные пакеты Python spaCy и Pandas для структурирования естественного языка и быстрого извлечения интересных идей.

Введение в Spacy

SpaCy - очень популярный пакет Python для продвинутого НЛП - у меня есть удобное для новичков введение в НЛП с SpaCy. spaCy - идеальный набор инструментов для специалистов по прикладным данным при работе над проектами НЛП. API очень интуитивно понятен, пакет работает быстро и очень хорошо документирован. Вероятно, будет справедливо сказать, что это лучший доступный пакет общего назначения для НЛП. Прежде чем погрузиться в структурирование данных НЛП, полезно познакомиться с основами библиотеки spaCy и API.

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

import spacy
nlp = spacy.load("en_core_web_sm")

Мы по соглашению инстанцируем эту модель как nlp. В этом посте я буду работать с набором известных мотивационных цитат. Давайте применим модель nlp к одинарной цитате из данных и сохраним ее в переменной.

doc = nlp(df.quote[819]) 
print(doc)

Если мы распечатаем документ, вы увидите, что он просто возвращает исходную цитату, но под капотом произошло много волшебства НЛП - мы создали объект spaCy doc. Итак, что может что мы с этим делаем?

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

Эти зависимости описывают лингвистическую структуру предложения, показывая, как каждое слово соотносится с другими словами в документе. Стоит остановиться на секунду, чтобы полюбоваться этим. Под капотом spaCy применила к документу большую нейронную языковую модель, проанализировала структуру зависимостей и позволила нам легко просмотреть это - все с помощью одной строчки кода. Если вы хотите лучше понять, как интерпретировать эту структуру зависимостей, вы можете использовать функцию spacy.explain, чтобы получить определение для каждого типа зависимости.

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

Мы можем получить доступ к этим свойствам документа программно, как показано ниже.

[(i, i.label_) for i in doc.ents]

Метод doc.ents обеспечивает доступ к объектам, которые были предсказаны языковой моделью spaCy. Как и в случае с тегами зависимости, вы можете использовать spacy.explain, чтобы понять значение каждого тега объекта.

Другими полезными свойствами объекта doc являются методы sents и noun_chunks, которые позволяют разбивать документ на предложения или части существительных (т. Е. Существительные плюс их дескрипторы).

doc = nlp(df.quote[0])
spacy.displacy.render(doc, style="ent")
doc_nouns = list(doc.noun_chunks)
print(doc_nouns)

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

[(i, i.ent_type_, i.is_stop) for i in doc]

Теперь, когда мы рассмотрели некоторые основы spaCy и api, давайте рассмотрим более структурированный подход к данным.

Структурирование данных на естественном языке

Цель здесь - преобразовать неструктурированные документы в структурированную таблицу данных. По сути, мы хотим перейти от неструктурированного корпуса документов, токенов и их метаданных к структурированному набору данных из строк и столбцов.

  • Шаг 1. Сначала нам нужно применить spaCy языковую модель ко всей коллекции цитат. Самый простой и эффективный с вычислительной точки зрения способ сделать это - использовать функцию nlp.pipe. Это будет проходить по каждому документу и применять языковую модель.
docs = list(nlp.pipe(df.quote))
  • Шаг 2: определите функцию для извлечения всех свойств каждого слова, которое вы хотите включить в таблицу. Эта функция будет перебирать токены в одном doc и извлекать различные атрибуты, такие как лемма, позиция, сущность и тег. Используйте эту функцию, чтобы определить все атрибуты, которые вы хотите извлечь из token объектов. В этом случае я извлекаю общие атрибуты, которые я часто использую и которые помогут при анализе данных.
  • Шаг 3: определите функцию для применения вышеуказанной функции ко всем документам и сохраните результаты в Pandas dataframe.

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

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

Анализ структурированных данных на естественном языке

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

tidy_docs.groupby("doc_id").size().hist(figsize=(14, 7), color="red", alpha=.4, bins=50);

В качестве альтернативы, мы могли бы быть заинтересованы в понимании наиболее распространенных сущностей, которые были идентифицированы в корпусе:

tidy_docs.query("ent_type != ''").ent_type.value_counts()

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

tidy_docs.query("is_stop == False & is_punct == False").lemma.value_counts().head(10).plot(kind="barh", figsize=(24, 14), alpha=.7)
plt.yticks(fontsize=20)
plt.xticks(fontsize=20);

Еще один интересный анализ, который мы можем провести с помощью структурированных данных, - это рассмотреть собственников, чтобы понять собственность внутри корпорации. Приведенный ниже код группирует по каждому документу, затем извлекает предыдущий и следующий токены, затем фильтрует токены, помеченные тегом POS, который указывает на притяжательную связь, т.е. объект предыдущего токена владеет субъектом следующий токен.

Это позволяет нам понять собственнические отношения по всему корпусу. Например, вы можете увидеть такие фразы, как «Мужество», «чьи-то молитвы» и «сегодняшние игры». Глубокий!

Как видите, работа с данными становится довольно тривиальной, поскольку они имеют структурированный формат.

Завершая все это

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

Спасибо за чтение!

P.S. Весь код этого поста можно найти здесь.