Facebook Graph Search предоставляет сообществу Graph Database более простой способ объяснить, что мы делаем и почему это важно. Я хотел донести эту мысль до дома, создав доказательство того, как вы можете сделать это с Neo4j . Тем не менее, у меня нет шести месяцев или большого опыта работы с НЛП (обработка естественного языка). У меня есть Сайфер . Cypher — это язык графиков Neo4j, и он позволяет легко выразить то, что мы ищем на графике. Мне нужен был способ взять «естественный язык» и создать из него Cypher. Это должно было стать проблемой.
Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения». Теперь у них две проблемы.
Это старая шутка программиста, но это то, что пришло на ум. Какие-то нечеткие регулярные выражения. В мире IPhone мы обычно слышим, как люди говорят: «Для этого есть приложение». В мире Ruby мы говорим «для этого есть драгоценный камень»… поэтому я попросил Google помочь и натолкнулся на Семра .
Semr — это основа лекарств для поддержки обработки естественного языка в вашем приложении. Его цель — следовать правилу 80/20, где 80% того, что вы хотите выразить в DSL, возможно знакомым способом, как разработчики обычно решают решения. (Примечание: есть и другие, более гибкие решения, но они также имеют более высокую кривую обучения, например, в виде дерева)
Круто, луч света, чтобы решить мою проблему … но Драгоценный камень 4 года. Я не мог заставить его установить. Облом … Подожди, что это было за Treetop ?
Treetop — это язык для описания языков. Сочетая элегантность Ruby с передовыми грамматиками синтаксического анализа, он помогает вам анализировать синтаксис с революционной легкостью.
Гол! Теперь я понятия не имел, как написать правильную грамматику языка, но это никогда никого не останавливало. Кто-то, у кого более двух часов опыта работы с Treetop, посмеется над этим, но я покажу вам часть того, что я сделал:
rule friends "friends" <Friends> end rule likes "who like" <Likes> end rule likeand likes space thing space "and" space thing <LikeAnd> end rule thing [a-zA-Z0-9]+ <Thing> end
Я создаю некоторые правила для вещей и отношений лайков, а также идею «нравится то и это».
«Естественный язык» управляется этими правилами, и синтаксическое дерево генерируется с соответствующими правилами. Затем они превращаются в хэши, представляющие части шифра. Глядя на код выше и ниже, вы можете увидеть, как «друзья, которым нравится Neo4j» анализируются в Friends, Likes, Thing.
class Friends < Treetop::Runtime::SyntaxNode def to_cypher return {:start => "me = node({me})", :match => "me -[:friends]-> people", :return => "people", :params => {"me" => nil }} end end class Likes < Treetop::Runtime::SyntaxNode def to_cypher return {:match => "people -[:likes]-> thing"} end end class Thing < Treetop::Runtime::SyntaxNode def to_cypher return {:start => "thing = node:things({thing})", :params => {"thing" => "name: " + self.text_value } } end end
Затем эти хэши объединяются и превращаются в правильную строку Cypher:
class Expression < Treetop::Runtime::SyntaxNode def to_cypher cypher_hash = self.elements[0].to_cypher cypher_string = "" cypher_string << "START " + cypher_hash[:start].uniq.join(", ") cypher_string << " MATCH " + cypher_hash[:match].uniq.join(", ") unless cypher_hash[:match].empty? cypher_string << " RETURN DISTINCT " + cypher_hash[:return].uniq.join(", ") params = cypher_hash[:params].empty? ? {} : cypher_hash[:params].uniq.inject {|a,h| a.merge(h)} return [cypher_string, params].compact end end
Наконец, я создал веб-приложение Sinatra, которое импортирует ваши данные из Facebook и страницу поиска, чтобы вы могли попробовать это сами . Как всегда, код доступен на Github и размещен на Heroku .
Хотя воспроизведение «своего рода» Facebook Graph Search интересно, более интересно было бы видеть, как другие люди используют эту идею в своих собственных данных. Если вы хотите узнать больше об этом доказательстве концепции, свяжитесь со мной или посетите Neo4j Meetups в Вирджинии (26 февраля) или в Бостоне (28 февраля) или в Чикаго (TBD) и где-то рядом с вами .