Это 4-я статья в моей серии статей по Python для НЛП. В моей предыдущей статье я объяснил , как библиотека space может использоваться для выполнения таких задач, как сопоставление слов и фраз.
В этой статье мы подробно рассмотрим части речевого тегирования и распознавания именованных сущностей. Мы увидим, как космическая библиотека может быть использована для выполнения этих двух задач.
Маркировка частей речи (POS)
Маркировка частей речи просто относится к присвоению частей речи отдельным словам в предложении, что означает, что, в отличие от сопоставления фраз, которое выполняется на уровне предложения или нескольких слов, маркировка частей речи выполняется на уровне токенов.
Давайте возьмем очень простой пример маркировки частей речи.
import spacy sp = spacy.load('en_core_web_sm')
Как обычно, в приведенном выше скрипте мы импортируем основную модель space English. Затем нам нужно создать пространственный документ, который мы будем использовать для выполнения частей речи тегирования.
sen = sp(u"I like to play football. I hated it in my childhood though")
Объект документа пространства имеет несколько атрибутов, которые могут быть использованы для выполнения различных задач. Например, для печати текста документа используется атрибут text
. Аналогично, атрибут pos_
возвращает крупнозернистый тег POS. Чтобы получить мелкозернистые POS-теги, мы могли бы использовать атрибут tag_
. И наконец, чтобы получить объяснение тега, мы можем использовать метод space.explain()
и передать ему имя тега.
Давайте посмотрим на это в действии:
print(sen.text)
Приведенный выше скрипт просто печатает текст предложения. Вывод выглядит следующим образом:
I like to play football. I hated it in my childhood though
Далее рассмотрим атрибут pos_
. Мы напечатаем POS-тег слова “ненавистный”, который на самом деле является седьмым маркером в предложении.
print(sen[7].pos_)
Выход:
VERB
Вы можете видеть, что СООБЩЕНИЕ налоговых деклараций для “ненавистного” – это “ГЛАГОЛ”, поскольку “ненавистный” – это глагол.
Теперь давайте напечатаем мелкозернистый POS-тег для слова “ненавистный”.
print(sen[7].tag_)
Выход:
VBD
Чтобы увидеть, что означает VBD, мы можем использовать метод spacey.explain ()
, как показано ниже:
print(spacy.explain(sen[7].tag_))
Выход:
verb, past tense
Вывод показывает, что VBD-это глагол в прошедшем времени.
Давайте напечатаем текст, крупнозернистые POS-теги, мелкозернистые POS-теги и объяснение тегов для всех слов в предложении.
for word in sen: print(f'{word.text:{12}} {word.pos_:{10}} {word.tag_:{8}} {spacy.explain(word.tag_)}')
В приведенном выше сценарии мы улучшаем читаемость и форматирование, добавляя 12 пробелов между текстом и крупнозернистым POS-тегом, а затем еще 10 пробелов между крупнозернистыми POS-тегами и мелкозернистыми POS-тегами.
Выход:
I PRON PRP pronoun, personal like VERB VBP verb, non-3rd person singular present to PART TO infinitival to play VERB VB verb, base form football NOUN NN noun, singular or mass . PUNCT . punctuation mark, sentence closer I PRON PRP pronoun, personal hated VERB VBD verb, past tense it PRON PRP pronoun, personal in ADP IN conjunction, subordinating or preposition my ADJ PRP$ pronoun, possessive childhood NOUN NN noun, singular or mass though ADP IN conjunction, subordinating or preposition
Полный список тегов для частей речи и мелкозернистых тегов, а также их объяснение доступны в официальной документации space.
Почему POS-маркировка полезна?
POS-теги могут быть действительно полезны, особенно если у вас есть слова или токены, которые могут иметь несколько POS-тегов. Например, слово “google” может использоваться как существительное, так и глагол, в зависимости от контекста. При обработке естественного языка важно выявить это различие. К счастью, космическая библиотека поставляется предварительно построенной с алгоритмами машинного обучения, которые, в зависимости от контекста (окружающих слов), способны возвращать правильный POS-тег для слова.
Давайте посмотрим на это в действии. Выполните следующий сценарий:
sen = sp(u'Can you google it?') word = sen[2] print(f'{word.text:{12}} {word.pos_:{10}} {word.tag_:{8}} {spacy.explain(word.tag_)}')
В приведенном выше скрипте мы создаем космический документ с текстом “Can you google it?” Здесь слово “google” используется как глагол. Далее мы печатаем POS-тег для слова “google” вместе с объяснением тега. Вывод выглядит следующим образом:
google VERB VB verb, base form
Из выходных данных вы можете видеть, что слово “google” было правильно идентифицировано как глагол.
Давайте теперь рассмотрим другой пример:
sen = sp(u'Can you search it on google?') word = sen[5] print(f'{word.text:{12}} {word.pos_:{10}} {word.tag_:{8}} {spacy.explain(word.tag_)}')
Здесь, в приведенном выше сценарии, слово “google” используется как существительное, как показано на выходе:
google PROPN NNP noun, proper singular
Поиск количества POS-тегов
Вы можете найти количество вхождений каждого POS-тега, вызвав count_by
в объекте space document. Метод принимает space.attrs.POS
как значение параметра.
sen = sp(u"I like to play football. I hated it in my childhood though") num_pos = sen.count_by(spacy.attrs.POS) num_pos
Выход:
{96: 1, 99: 3, 84: 2, 83: 1, 91: 2, 93: 1, 94: 3}
В выходных данных вы можете увидеть идентификатор POS-тегов вместе с их частотами появления. Текст тега POS может быть отображен путем передачи идентификатора тега в словарь фактического документа пространства.
for k,v in sorted(num_pos.items()): print(f'{k}. {sen.vocab[k].text:{8}}: {v}')
Теперь в выходных данных вы увидите идентификатор, текст и частоту каждого тега, как показано ниже:
83. ADJ : 1 84. ADP : 2 91. NOUN : 2 93. PART : 1 94. PRON : 3 96. PUNCT : 1 99. VERB : 3
Визуализация частей речевых тегов
Визуализация POS-тегов графическим способом чрезвычайно проста. Для этой цели используется модуль display
из библиотеки space
. Чтобы визуализировать POS-теги внутри блокнота Jupyter, вам нужно вызвать метод render
из модуля displacy
и передать ему документ spacy, стиль визуализации и установить атрибут jupyter
в True
как показано ниже:
from spacy import displacy sen = sp(u"I like to play football. I hated it in my childhood though") displacy.render(sen, style='dep', jupyter=True, options={'distance': 85})
В выходных данных вы должны увидеть следующее дерево зависимостей для POS-тегов.
Вы можете ясно видеть зависимость каждого токена от другого вместе с тегом POS.
Если вы хотите визуализировать POS-теги вне блокнота Jupyter, то вам нужно вызвать метод serve
. График для POS-тегов будет напечатан в HTML-форме внутри вашего браузера по умолчанию. Выполните следующий сценарий:
displacy.serve(sen, style='dep', options={'distance': 120})
Как только вы выполните описанный выше сценарий, вы увидите следующее сообщение:
Serving on port 5000... Using the 'dep' visualizer
Чтобы просмотреть дерево зависимостей, введите в браузере следующий адрес: http://127.0.0.1:5000/ . Вы увидите следующее дерево зависимостей:
Распознавание Именованных Сущностей
Распознавание именованных сущностей относится к идентификации слов в предложении как сущности, например, имени человека, места, организации и т. Д. Давайте посмотрим, как библиотека пространства выполняет распознавание именованных сущностей. Посмотрите на следующий сценарий:
import spacy sp = spacy.load('en_core_web_sm') sen = sp(u'Manchester United is looking to sign Harry Kane for $90 million')
В приведенном выше скрипте мы создали простой космический документ с некоторым текстом. Чтобы найти именованную сущность, мы можем использовать атрибут ents
, который возвращает список всех именованных сущностей в документе.
print(sen.ents)
Выход:
(Manchester United, Harry Kane, $90 million)
Вы можете видеть, что были идентифицированы три названные сущности. Чтобы увидеть детали каждой именованной сущности, вы можете использовать метод text
, label
и метод space.explain
, который принимает объект сущности в качестве параметра.
for entity in sen.ents: print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
В выходных данных вы увидите имя сущности вместе с типом сущности и небольшим описанием сущности, как показано ниже:
Manchester United - ORG - Companies, agencies, institutions, etc. Harry Kane - PERSON - People, including fictional $90 million - MONEY - Monetary values, including unit
Вы можете видеть, что “Манчестер Юнайтед” был правильно идентифицирован как организация, компания и т. Д. Точно так же “Гарри Кейн” был идентифицирован как человек, и, наконец, “90 миллионов долларов” были правильно идентифицированы как сущность типа Денег.
Добавление Новых Сущностей
Вы также можете добавить новые сущности в существующий документ. Например, в следующем примере “Несфрута” не идентифицируется космической библиотекой как компания.
sen = sp(u'Nesfruita is setting up a new company in India') for entity in sen.ents: print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
Выход:
India - GPE - Countries, cities, states
Из выходных данных вы можете видеть, что только Индия была идентифицирована как сущность.
Теперь, чтобы добавить “Nesfruita” как сущность типа “ORG” в наш документ, нам нужно выполнить следующие шаги:
from spacy.tokens import Span ORG = sen.vocab.strings[u'ORG'] new_entity = Span(sen, 0, 1, label=ORG) sen.ents = list(sen.ents) + [new_entity]
Во-первых, нам нужно импортировать класс Span
из модуля space.tokens
. Далее нам нужно получить хэш-значение типа сущности ORG
из нашего документа. После этого нам нужно присвоить span хэш-значение ORG
. Поскольку “Несфрута” – это первое слово в документе, интервал равен 0-1. Наконец, нам нужно добавить новый диапазон сущностей в список сущностей. Теперь, если вы выполните следующий скрипт, вы увидите “Nesfruta” в списке сущностей.
for entity in sen.ents: print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
Вывод приведенного выше скрипта выглядит следующим образом:
Nesfruita - ORG - Companies, agencies, institutions, etc. India - GPE - Countries, cities, states
Подсчет Сущностей
В случае POS-тегов мы могли бы подсчитать частоту каждого POS-тега в документе с помощью специального метода can.count_by
. Однако для именованных сущностей такого метода не существует. Мы можем вручную подсчитать частоту каждого типа сущностей. Предположим, что у нас есть следующий документ вместе с его сущностями:
sen = sp(u'Manchester United is looking to sign Harry Kane for $90 million. David demand 100 Million Dollars') for entity in sen.ents: print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
Выход:
Manchester United - ORG - Companies, agencies, institutions, etc. Harry Kane - PERSON - People, including fictional $90 million - MONEY - Monetary values, including unit David - PERSON - People, including fictional 100 Million Dollars - MONEY - Monetary values, including unit
Для подсчета сущностей типа person в приведенном выше документе мы можем использовать следующий скрипт:
len([ent for ent in sen.ents if ent.label_=='PERSON'])
В выходных данных вы увидите 2, так как в документе есть 2 сущности типа PERSON.
Визуализация Именованных Сущностей
Как и POS-теги, мы также можем просматривать именованные объекты внутри ноутбука Jupiter, а также в браузере.
Для этого мы снова будем использовать объект display
. Посмотрите на следующий пример:
from spacy import displacy sen = sp(u'Manchester United is looking to sign Harry Kane for $90 million. David demand 100 Million Dollars') displacy.render(sen, style='ent', jupyter=True)
Вы можете видеть, что единственное различие между визуализацией именованных сущностей и POS-тегами заключается в том, что здесь в случае именованных сущностей мы передали ent
в качестве значения параметра style
. Вывод приведенного выше скрипта выглядит следующим образом:
Из выходных данных видно, что именованные сущности были выделены разными цветами вместе с их типами сущностей.
Вы также можете отфильтровать, какие типы сущностей будут отображаться. Для этого вам нужно передать тип сущностей для отображения в списке, который затем передается в качестве значения ключу ends
словаря. Затем словарь передается в параметр options
метода render
модуля display
, как показано ниже:
filter = {'ents': ['ORG']} displacy.render(sen, style='ent', jupyter=True, options=filter)
В приведенном выше сценарии мы указали, что в выходных данных должны отображаться только сущности типа ORG. Вывод приведенного выше скрипта выглядит следующим образом:
Наконец, вы также можете отображать именованные сущности за пределами записной книжки Jupyter. Следующий сценарий отобразит именованные сущности в вашем браузере по умолчанию. Выполните следующий сценарий:
displacy.serve(sen, style='ent')
Теперь, если вы идете по адресу http://127.0.0.1:5000/ в вашем браузере вы должны увидеть именованные сущности.
Вывод
Части речи, помеченные тегами и распознавание именованных сущностей, имеют решающее значение для успеха любой задачи НЛП. В этой статье мы увидели, как космическая библиотека Python может быть использована для выполнения POS-тегов и распознавания именованных сущностей с помощью различных примеров.