Новый API обработки естественного языка: Google прилагает все усилия, чтобы предоставить облачные сервисы, которые облегчают взаимодействие человека с компьютером с помощью инструментов, которые могут использовать человеческий язык.

В недавнем сообщении в блоге мы обсуждали Google Cloud Speech API, службу преобразования звуковой речи в текст. Возможно, руководствуясь аналогичной технологией, основанной на глубоких нейронных сетях (в частности, Tensorflow), Google недавно выпустила бета-версию API обработки естественного языка Google Cloud, еще один кирпичик в их архитектуре машинного обучения. . Такой сервис извлекает смысл и структуру из неструктурированного текста. В частности, механизм распознает объекты (люди, организации, местоположения и т. Д.), Их синтаксис, состоящий из их логической роли (существительное, глагол, наречия, прилагательные) и отношения (имя, к которому относится прилагательное) и документ полярность (положительный, нейтральный, отрицательный).

Вы можете впервые ознакомиться с его услугами и поиграть с некоторыми функциями на сайте cloud.google.com/natural-language. Чтобы использовать API обработки естественного языка, вы можете подать заявку на бесплатную пробную версию и создать ключ API из Менеджера API Google Cloud Platform.

API обработки естественного языка Google и Python

API предоставляет интерфейс RESTful , к которому можно получить доступ через обычные HTTP-запросы POST. Однако уже доступно множество клиентов для нескольких языков программирования. В наших тестах мы экспериментировали с клиентом Python, код которого можно получить на GitHub. Чтобы использовать клиент, просто добавьте следующую запись в свой файл требований:

# requirements.txt
google-api-python-client==1.5.5

Например, следующий скрипт Python определяет функцию для отправки текста в Google Cloud Natural Language Processing API (просто установите свои собственные ключи API). Google предоставляет четыре разных конечных точки (см. Официальную страницу документации): analysisEntities, analysisSentiment, analysisSyntax и annotateText. . После нескольких попыток мы поняли, что метод annotateText в основном включает всю информацию, возвращаемую тремя другими отдельными методами. По этой причине мы предлагаем использовать этот метод для ваших первоначальных экспериментов, чтобы получить обзор всех доступных анализов.

Например, следующий скрипт Python определяет функцию для отправки текста в Google Cloud Natural Language Processing API (просто установите свои собственные ключи API). Google предоставляет четыре разных конечных точки (см. Официальную страницу документации): analysisEntities, analysisSentiment, analysisSyntax и annotateText. . После нескольких попыток мы поняли, что метод annotateText в основном включает всю информацию, возвращаемую тремя другими отдельными методами. По этой причине мы предлагаем использовать этот метод для ваших первоначальных экспериментов, чтобы получить обзор всех доступных анализов.

import httplib2
import sys
from googleapiclient import discovery
from googleapiclient.errors import HttpError
def test_language_api(content):
  discovery_url = 'https://{api}.googleapis.com/$discovery' \ 
                  '/restversion={apiVersion}'
  service = discovery.build(
    'language', 'v1',
    http=httplib2.Http(),
    discoveryServiceUrl=discovery_url,
    developerKey='__PUT_YOUR_KEY_HERE__',
)
service_request = service.documents().annotateText(
  body={
    'document': {
    'type': 'PLAIN_TEXT',
    'content': content,
  },
  'features': {
    'extract_syntax': True,
    'extractEntities': True,
    'extractDocumentSentiment': True,
  },
  'encodingType': 'UTF16' if sys.maxunicode == 65535 else 'UTF32',
})
try:
  response = service_request.execute()
except HttpError as e:
  response = {'error': e}
return response

Ответ этого API обработки естественного языка - это JSON, содержащий:

  • язык, который определяется автоматически. Обратите внимание, что в настоящее время определение настроения работает только с английским (en), в то время как для анализа сущностей поддерживаются также испанский (es) и японский (ja). Это главное отличие от API преобразования речи в текст, где поддержка более 80 различных языков была отличительной особенностью.
  • Список предложений. Содержание разбито на предложения с использованием знаков препинания.
  • Список токенов. Контент разбивается на токены. Грубо говоря, жетон обычно соответствует слову. Каждый токен обогащен синтаксической информацией.
  • Список обнаруженных сущностей. Сущности, обнаруженные в документе, перечислены с их свойствами.
  • Отрицательная / положительная полярность отправленного содержания. Мы заметили, что API изменился за последние несколько дней. В то время как в предыдущих версиях вычислялась полярность всего отправленного контента, последняя версия, с которой мы экспериментировали, предлагает более детальный анализ, возвращая результат для каждого отдельного предложения.

API обработки естественного языка: основы

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

Токен - это основная единица текстового анализа. Его можно определять по-разному, но часто он соответствует 1 слову = 1 токену. Определение не является универсальным и зависит от механизма обработки. Например, некоторые движки обрабатывают «кредитную карту» как отдельный токен, тогда как API обработки естественного языка Google разделяет его на два отдельных токена (связанных отношениями). У каждого токена есть свой тип грамматики (например, существительное, глагол, прилагательное и т. Д.), Обычно обозначаемый как Часть речи (POS).

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

Один или несколько токенов могут определять объект, то есть кого-то или что-то интересное, упомянутое в тексте. В случае имен собственных (например, Paris, New York, Madonna, Tom Cruise) используется более конкретный термин именованный объект. Как правило, задача Распознавание именованных сущностей (NER) обнаруживает в документе собственные имена людей, мест и организаций. Тем не менее, тематические сущности, такие как даты, адреса, события, белки, названия лекарств и т. Д., Также могут быть целью извлечения сущности.

Наконец, структура кодирования отношений между словами в предложении фиксируется деревом зависимостей. Дерево включает синтаксические / семантические отношения, такие как:

Глагол-подлежащее и глагол-объект

  • Джон [субъект] ← играет → [объект] баскетбол

Модификатор прилагательного для данного существительного

  • Я вижу желтый [модификатор прилагательного] ← мяч

Аппозиции

  • Волшебник Гэндальф [приложение]

Эти отношения составляют «ребра зависимости» дерева. Концепция зависимости кодирует слово, на которое ссылается каждый. Давайте рассмотрим эти два предложения:

  1. Джон наблюдает за деревом в телескоп
  2. Джон смотрит на дерево с гнездом

Лексемы в двух предложениях имеют одинаковые типы грамматики, но их зависимости различаются. В (1) «телескоп» связано через «с» с глаголом «наблюдает» (телескоп - это то, что Джон использует, чтобы наблюдать за деревом), в то время как в (2) «гнездо» связано через «с» с «деревом», поскольку гнездо - это объект, помещенный на дереве, и не имеет отношения к «тому, как Джон что-то наблюдает». Подумайте об этом так: если вы удалите «дерево» из (1), телескоп все еще будет иметь «право» быть в предложении, в то время как это неверно для «гнезда» в (2).

Практическая демонстрация с естественным языком

Давайте посмотрим на такие определения с помощью сервиса Google. Образец текста извлечен из ABC news и передан в test_language_api () с использованием метода, определенного выше.

sample_content = """Joshua Brown, 40, was killed in Florida in May when his Tesla failed to differentiate between the side of a turning truck and the sky while operating in autopilot mode."""
test_language_api(sample_content)

Результат в JSON:

'documentSentiment': {
  'magnitude': 0.5,
  'polarity': -1,
  'score': -0.5
}
'entities': [{
  'mentions': [{
    'text': {'beginOffset': 0, 'content': 'Joshua Brown'},
    'type': 'PROPER'}],
  'metadata': {},
  'name': 'Joshua Brown',
  'salience': 0.62338889,
  'type': 'PERSON'
  },
  ...
]
'language': 'en',
'sentences': [{
  'sentiment': {'magnitude': 0.5, 'polarity': -1, 'score': -0.5},
  'text': {'beginOffset': 0, 'content': '...'}}
],
'tokens': [
  {
    'dependencyEdge': {'headTokenIndex': 1, 'label': 'NN'},
    'lemma': 'Joshua',
    'partOfSpeech': {'tag': 'NOUN', ...},
    'text': {'beginOffset': 0, 'content': 'Joshua'}},
  {
    'dependencyEdge': {'headTokenIndex': 6, 'label': 'NSUBJPASS'},
    'lemma': 'Brown',
    'partOfSpeech': {'tag': 'NOUN', ...},
    'text': {'beginOffset': 7, 'content': 'Brown'}
  },
  ...
  {
    'dependencyEdge': {'headTokenIndex': 6, 'label': 'P'},
    'lemma': '.',
    'partOfSpeech': {'tag': 'PUNCT', ...},
    'text': {'beginOffset': 167, 'content': '.'}
  }
]

Нашим первым впечатлением было то, что движок надежен в распознавании сущностей (обратите внимание, что «Джошуа Браун» указан среди сущностей как человек), напрямую связывая их со связанной страницей Википедии, когда она доступна. Однако в настоящее время возвращаемый набор метаданных не особенно богат (и предоставляются только URL-адреса Википедии, если они доступны). Вероятно, это функция в стадии разработки. Кроме того, механизм вычисляет показатель значимости, т. Е. Важность объекта в предложении, даже если он не совсем точен. Фактически, в этом примере он обнаружил, что Джошуа Браун является релевантным, но он оценил «Тесла» и «режим автопилота» как менее значимые, чем Флорида.

Что касается обнаружения настроения, он вернул отрицательную полярность, как вы можете видеть в возвращенном поле «documentSentiment».

В соответствии с официальной документацией, полярность - это значение в диапазоне [-1,0, 1,0], где большие числа представляют более позитивное настроение. величина - неотрицательное число, которое представляет собой абсолютную величину настроения независимо от полярности (положительной или отрицательной). Во всех наших экспериментах полярность принимала значение 1 или -1, в то время как величина была положительной, число с плавающей запятой никогда не превышало 1.0. Начиная с версии v1, возвращается третье значение, «оценка», которое просто отображает произведение между двумя другими, в нашем случае -0,5 (полученное умножением 0,5 на -1,0).

Как API обработки естественного языка обрабатывает крайние случаи?

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

sample_content = """Joshua Brown, 40, was in Florida in May when his Tesla failed to differentiate between the side of a turning truck and the sky while operating in autopilot mode."""
test_language_api(sample_content)
# output:
#
# ‘documentSentiment’: {
#   ‘magnitude’: 0.2,
#   ‘polarity’: -1,
#   ‘score’: -0.2
# },

Во втором испытании мы удалили «не удалось», глагол с сильной отрицательной полярностью. Значение предложения существенно изменилось по сравнению с исходным, и движок правильно определил положительную полярность нового предложения.

sample_content = """Joshua Brown, 40, was in Florida in May when his Tesla differentiate between the side of a turning truck and the sky while operating in autopilot mode."""
test_language_api(sample_content)
# output:
#
# ‘documentSentiment’: {
#   ‘magnitude’: 0.4,
#   ‘polarity’: 1,
#   ‘score’: 0.4
# },

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

sample_content = """Joshua Brown was in Florida when his Tesla differentiate between a turning truck and the sky."""
test_language_api(sample_content)
# output:
#
# ‘documentSentiment’: {
#   ‘magnitude’: 0.5,
#   ‘polarity’: 1,
#   ‘score’: 0.5
# },

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

  1. Майкл Джордан набрал последние очки за победу.
  2. Майкл Джордан сыграл в последнем фильме "Фантастическая четверка".

Мы можем заметить, что предложения относятся к двум разным Майклам Джордансу. Удивительно, но двигатель также может различать два разных объекта. Фактически, в первом случае он возвращает сущность Майкл Джордан, а во втором - Майкл Б. Джордан. Это означает, что до некоторой степени инструмент способен устранять неоднозначность на основе некоторого контекста вокруг объекта. Если копнуть глубже, это похоже на сильную улику, то есть упоминание Фантастической четверки необходимо для правильного устранения неоднозначности. Фактически, если мы удалим упоминание Фантастической четверки из второго предложения и превратим его во что-то вроде:

  • Майкл Джордан снялся в фантастическом фильме

Майкл Джордан интерпретируется как баскетболист, а не актер, несмотря на упоминание о кино и сфере кино в целом. Однако это непростая догадка, и это не обязательно неверно: учитывая роль Майкла Джордана в Space Jam, мы можем закрыть глаза на эту ошибку :)

Вывод

Наше первое впечатление от API обработки естественного языка Google Cloud - положительное. Это простой в использовании инструмент для базовых функций NLP, который можно легко интегрировать с любыми сторонними сервисами и приложениями через REST API. Нас особенно впечатлил богатый синтаксис (обратите внимание на большое количество Ярлыков зависимостей) и точное определение настроения. Основная проблема - плохая документация. Мы надеемся, что он будет расширен до того, как наконец будет выпущен стабильный сервис. Кроме того, сильным ограничением является поддержка только ограниченного набора языков; мы определенно ожидали более широкой поддержки. Один совет: будьте осторожны при использовании библиотек, поскольку они постоянно обновляются (также для версий, которые больше не помечены как бета).

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

Первоначально опубликовано на сайте cloudacademy.com 24 ноября 2016 г.