Статьи

Ruby & OpenCalais: семантически помечать что угодно

calais_logo

Семантический Что ??

Если вам интересно, о чем весь этот шум вокруг Семантической сети, не бойтесь — вы не единственный! Помимо того, что Semantic Web является модной модной фразой, она имеет множество практических приложений. В этом руководстве мы рассмотрим некоторые из них с помощью веб-службы семантического анализа прямо из нашего любимого языка программирования!

Веб-сервис OpenCalais

Вкратце, и цитирование создателей OpenCalais :

« Веб-служба OpenCalais автоматически создает богатые семантические метаданные для контента, который вы отправляете — гораздо быстрее, чем за секунду. Используя обработку естественного языка (NLP), машинное обучение и другие методы, Кале анализирует ваш документ и находит сущности в нем. Но Кале выходит далеко за рамки классической идентификации сущностей и возвращает факты и события, скрытые в вашем тексте. «

OpenCalais Simple XML Response Format (который мы будем использовать в этом руководстве) возвращает три вида тегов: Entitites, Events и Topics . Сущности — это статичные «вещи», такие как Persons, Places и др. которые участвуют в текстовом контексте в некотором качестве. OpenCalais назначает оценку релевантности каждому объекту, чтобы указать его релевантность в контексте общей темы источника данных. События — это факты или действия, которые относятся к одной или нескольким сущностям. Темы — это характеристика или общее описание контекста источника данных.

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

Прежде чем мы начнем …

  • Чтобы использовать веб-сервис OpenCalais, вам необходимо получить ключ API OpenCalais, который можно легко получить с веб-сайта OpenCalais .

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

    gem 'dover_to_calais' 

    И затем выполните:

     $ bundle 

    Или установите его самостоятельно как:

     $ gem install dover_to_calais 

Также имейте в виду, что DoverToCalais требует наличия работающей JRE .

Давайте начнем

Мы начнем с анализа URL-адреса и посмотрим, что мы получим. Поскольку DoverToCalais использует всю мощь EventMachine , наш код должен быть размещен внутри контура реактора EM:

 1 require 'dover_to_calais' 2 3 EM.run do 4 5 # use Control + C to stop the EM 6 Signal.trap('INT') { EventMachine.stop } 7 Signal.trap('TERM') { EventMachine.stop } 8 9 # we need an API key to use OpenCalais 10 DoverToCalais::API_KEY = 'my-opencalais-api-key' 11 # create a new dover 12 dover = DoverToCalais::Dover.new('http://www.bbc.co.uk/news/world-africa-24412315') 13 # parse the text and send it to OpenCalais 14 dover.analyse_this 15 puts 'do something....' 16 # set a callback for when we receive a response 17 dover.to_calais { |response| puts response.error ? response.error : response } 18 19 puts 'do something else....' 20 21 end 

Вышесказанное довольно просто: мы оборачиваем наш источник данных в объект Dover (строка 12), устанавливаем обратный вызов, чтобы делать то, что нам нужно, с данными ответа (строка 17), и не забываем отправлять наш dover для пометка (строка 14). Это даст следующий результат:

Как вы можете видеть, ответ OpenCalais представляет собой большую кучу XML. К счастью, DoverToCalais позволяет нам легко анализировать и фильтровать этот XML, как мы увидим далее в этом руководстве.

Также имейте в виду, что, хотя мы передали URL конструктору DoverToCalais, гем также может обрабатывать большинство форматов файлов. Мы могли бы так же легко передать ему путь к любому (ну почти любому) файлу и пометить его содержимое.

Чтобы получить представление о более глубоком и реалистичном использовании DoverToCalais, нам нужно поговорить о Конноре.

Загадка Коннора

Коннор — многообещающий журналист для государственной газеты. Его босс только что попросил его написать одну страницу на все важные новости, связанные со спортом, которые произошли в (вымышленном) городе Олдервуде в течение прошлого года. Она отправляет ему ссылку на сетевую папку, в которой содержится отсканированное изображение каждой статьи, опубликованной Alderwood Gazette за последний год (предоставлено VAST Challenge 2006 ). «Вот где вы найдете то, что вам нужно», — говорит она. «Я хочу, чтобы твоя страница была у меня на столе завтра утром!». И с этим она покидает офис. Коннор остается, обдумывая свой выбор:

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

  2. Используйте grep-подобный инструмент для поиска связанных со спортом ключевых слов в каждой статье. Сначала это кажется хорошей идеей. Однако Коннор вскоре понимает, что это не такая практичная идея, в конце концов. Какие виды спорта он должен искать? Баскетбол, футбол, бейсбол, кто знает, чем увлекаются хорошие жители Олдервуда? А как насчет более экзотических видов спорта, таких как борьба сумо или ню йодлинг? Откуда ему знать обо всех возможных спортивных мероприятиях, которые были упомянуты в «Олдервуд Газетт» за последний год, чтобы он мог их искать ?! Не говоря уже о ложных срабатываниях, которые он получит, когда в несвязанной статье будет упоминаться о спорте попутно и вне контекста. Нет, думает он, grep тоже не ответ.

К счастью, Коннор знает Руби, и он читал о DoverToCalais. Внезапно будущее Коннора выглядит ярким!

Осмысление больших данных

Коннор начинает набирать код:

 1 require 'dover_to_calais' 2 EM.run do 3 4 # use Control + C to stop the EM 5 Signal.trap('INT') { EventMachine.stop } 6 Signal.trap('TERM') { EventMachine.stop } 7 8 DoverToCalais::API_KEY = 'my-opencalais-api-key' 9 data_dir = '/home/connor/data/Alderwood_News/' 10 11 dovers = [] 12 Dir.foreach(data_dir) do |filename| 13 next if filename == '.' or filename == '..' 14 dover = DoverToCalais::Dover.new(data_dir + filename) 15 dovers << dover 16 end 17 18 ##what now? 19 end 

Все идет нормально. Коннор создал список всех своих файлов данных как объекты Dover. Затем он должен проанализировать эти объекты. Он заменяет ##what now? (строка 18) прокомментировать с помощью:

 18 dovers.each do |dover| 19 dover.to_calais do |response| 20 if response.error 21 puts "*** Data source #{dover.data_src} error: #{response}" 22 else 23 topics = response.filter({:entity => 'Topic'}) 24 puts "Data file: #{dover.data_src} is about #{topics.map{|x| x.value}.join(",")}" 25 26 end #if 27 end #block 28 29 dover.analyze_this 30 end #each 

Для каждого объекта dover (то есть для каждой новостной статьи) Коннор установил обратный вызов (строка 19), определяющий, что делать, когда он получает действительный ответ, то есть извлечение сущностей «Тема», чтобы он мог видеть, что представляет собой вся статья около. Затем он отправляет объект в OpenCalais для пометки (строка 29).

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

Теперь он готов запустить код. Но когда он это делает, его лицо становится пепельным… на его экране начали появляться сообщения об ошибках!

Коннор не должен паниковать, объяснение довольно простое: OpenCalais ограничивает количество одновременных запросов на пользователя максимум 4 в секунду. Когда Коннор вызывает dover.analyze_this , DoverToCalais отправляет HTTP-запрос в OpenCalais. Поскольку этот запрос выполняется один раз для каждой итерации массива dovers , это означает, что десятки запросов одновременно отправляются в OpenCalais. Неудивительно, что OpenCalais жалуется на это!

Как Коннор может решить эту проблему?

Рука на газ

Коннор может dover.analyze_this искушение решить эту проблему, добавив оператор sleep непосредственно перед dover.analyze_this . Однако это не сработает. Коннор забыл, что его код работает в потоке EventMachine и — по причинам, выходящим за рамки этого руководства и относящимся к модели потоков EM, — использование sleep было бы идеей baaad!

Именно здесь в игру вступает точно названная EM Throttled Queue . Задушенная очередь позволяет нам контролировать скорость, с которой предметы выталкиваются из нее.

Итак, Коннор модифицирует код следующим образом:

 1 require 'dover_to_calais' 2 require 'em/throttled_queue' 3 EM.run do 5 # use Control + C to stop the EM 6 Signal.trap('INT') { EventMachine.stop } 7 Signal.trap('TERM') { EventMachine.stop } 8 9 DoverToCalais::API_KEY = 'my-opencalais-api-key' 10 data_dir = '/home/connor/data/Alderwood_News/' 11 12 # allow up to 2 dovers to be de-queued in a second 13 # that should keep us well within the OpenCalais 14 # concurrency limit 15 queue = EM::ThrottledQueue.new(2, 1) 16 17 dovers = [] 18 Dir.foreach(data_dir) do |filename| 19 next if filename == '.' or filename == '..' 20 dover = DoverToCalais::Dover.new(data_dir + filename) 21 dovers << dover 22 # push the dover on our throttled queue as well 23 queue.push(dover) 24 end 25 26 dovers.each do |dover| 27 dover.to_calais do |response| 28 puts "----------------------------------------" 29 if response.error 30 puts "*** Data source #{dover.data_src} error: #{response}" 31 else 32 topics = response.filter({:entity => 'Topic'}) 33 puts "Data file: #{dover.data_src} is about #{topics.map{|x| x.value}.join(",")}" 34 35 end #if 36 end #block 37 38 # because we told the queue to pop a maximum of two dovers per second 39 # we're not exceeding the OpenCalais limit so we'll get no errors 40 dovers.length.times { queue.pop { |dover| dover.analyze_this } } 41 end #each 42 end 

Коннор все улыбается. Вскоре его код пометил все статьи тегами «Тема», что позволило ему быстро узнать, о чем каждая статья. Теперь он может легко выбрать спортивные статьи для дальнейшего чтения и сэкономить часы усилий и беспокойства. Он может отсканировать только соответствующие статьи и подготовить свое произведение к завтрашнему изданию.

эпилог

В этом руководстве мы увидели, как мы можем использовать сервис OpenCalais для тегирования и суммирования больших объемов контента. Тем не менее, мы только что коснулись поверхности богатых семантических метаданных, предлагаемых сервисом, и того, как мы можем использовать их для более точного анализа данных, интеллектуального анализа и интеллектуального поиска.