Статьи

Визуализация схемы RDF с помощью Neo4J, Tinkerpop, Sail и Gephi

На прошлой неделе Neo4j плагин для Gephi был освобожден. Gephi — это инструмент для визуализации и манипулирования с открытым исходным кодом, который позволяет пользователям интерактивно просматривать и исследовать графики . Сами графики могут быть загружены через различные форматы файлов. Благодаря Martin Škurla теперь можно загружать и лениво исследовать графики, которые хранятся в хранилище данных Neo4J.

В одной из моих предыдущих статей я объяснил, как Neo4J и инфраструктура Tinkerpop могут использоваться для загрузки и запроса троек RDF. Недавно выпущенный плагин Neo4J теперь позволяет визуально просматривать эти тройки RDF и выполнять некоторые более необычные операции, такие как поиск шаблонов и выполнение алгоритмов анализа социальных сетей из самой Gephi. Tinkerpop в Sail Ouplementation также поддерживает понятие RDF Schema логического вывода . Инференция — это процесс, в котором новые (RDF) данные автоматически вычитаются из существующих (RDF) данных посредством аргументации., К сожалению, разум Парус не может быть легко интегрирован в Gephi, так как плагин Gephi захватывает блокировку хранилища Neo4J, и данные RDF не могут быть добавлены, кроме как через сам плагин.

Было бы неплохо иметь возможность визуализировать процесс рассуждения схемы RDF и графически указывать, какие тройки RDF были добавлены вручную и какие данные RDF были автоматически выведены. Чтобы реализовать эту функцию, мы должны быть в состоянии перенести изменения графика с Tinkerpop и Neo4J на Gephi. К счастью, плагин для потоковой передачи графов Gephi позволяет нам сделать это. В оставшейся части этой статьи я подробно расскажу, как настроить требуемую среду Gephi и как мы можем передавать (выводить) данные RDF из Neo4J в Gephi.

 

1. Добавление (предполагаемых) данных RDF

Давайте начнем с настройки требуемой среды Neo4J / Tinkerpop / Sail, которую мы будем использовать для хранения и вывода RDF-троек. Настройка аналогична описанной в моей предыдущей статье о Tinkerpop . Однако вместо того, чтобы обернуть наш GraphSail в SailRepository , мы обернем его как ForwardChainingRDFSInferencer . Этот механизм вывода будет прослушивать тройки RDF, которые добавлены и / или удалены, и автоматически выполнит вывод схемы RDF, применяя правила, определенные в Рекомендации по семантике RDF .

neograph = new Neo4jGraph("var/rdf");
// Let's use manual transaction mode
neograph.setMaxBufferSize(0);
sail = new ForwardChainingRDFSInferencer(new GraphSail(neograph));
sail.initialize();
connection = sail.getConnection();

 

Теперь мы готовы добавить тройки RDF. Давайте создадим простой цикл, который позволяет нам читать тройки RDF и добавлять их в хранилище Sail.

InferenceLoop loop = new InferenceLoop();
Scanner in = new Scanner(System.in);
while (true) {
   System.out.println("Provide RDF statement:");
   System.out.print("=> ");
   String input = in.nextLine();
   System.out.println("The following edges were created:");
   loop.inference(input);
}

 

Сам метод вывода довольно прост. Сначала мы разберем объект RDF , предикат и объект . Затем мы начинаем новую транзакцию, добавляем инструкцию и фиксируем транзакцию. Это не только добавит тройку RDF в наш магазин Neo4J, но и дополнительно запустит процесс вывода схемы RDF и автоматически добавит предполагаемые тройки RDF. Довольно легко!

// Parses and add the RDF statement accordingly
public void inference(String statement) throws SailException, InterruptedException {
   String[] triple = statement.split(" ");
   inference(new URIImpl(triple[0]), new URIImpl(triple[1]), new URIImpl(triple[2]));
}

// Add the inference
public void inference(URI subject, URI predicate, URI object) throws SailException, InterruptedException {
   neograph.startTransaction();
   connection.addStatement(subject, predicate, object);
   connection.commit();
   neograph.stopTransaction(TransactionalGraph.Conclusion.SUCCESS);
}

 

Но как нам получить предполагаемые тройки RDF, которые были добавлены в процессе логического вывода? Хотя ForwardChainingRDFSInferencer позволяет нам зарегистрировать прослушиватель, способный обнаруживать изменения в графике, он не предоставляет требуемого API для различения вручную добавленных или предполагаемых троек RDF . К счастью, мы все еще можем получить доступ к базовому хранилищу Neo4J и зафиксировать эти изменения графиков, реализовав интерфейс Neo4J TransactionEventHandler . После того, как транзакция зафиксирована, мы можем получить вновь созданные отношения (т.е. тройки RDF). Для каждого из этих отношений начальный узел (т. Е. Субъект RDF), конечный узел (т. Е. Объект RFD) итип связи (т. е. предикат RDF) может быть получен. В случае, если тройка RDF была добавлена ​​посредством логического вывода, значение логического свойства «выведено» равно «истина» . Мы фильтруем отношения с теми, которые определены в нашем домене (иначе будет также визуализирована полная метамодель RDFS). Наконец, мы нажимаем соответствующие узлы и ребра.

public class PushTransactionEventHandler implements TransactionEventHandler {

   private int id = 1;

   public void afterCommit(TransactionData transactionData, Object o) {
      // Retrieve the created relationships. (The relevant nodes will be retrieved through these relationships)
      Iterable relationships = transactionData.createdRelationships();

      // Iterate and add
      for (Relationship relationship : relationships) {
         // Retrieve the labels
         String start = (String)relationship.getStartNode().getProperty("value");
         String end = (String)relationship.getEndNode().getProperty("value");
         String predicate = relationship.getType().toString();

         // Limit the relationships that are shown to our own domain
         if (!start.startsWith("http://www.w3.org") && !end.startsWith("http://www.w3.org")) {
            // Check whether the relationship is inferred or not
            boolean inferred = (Boolean)relationship.getProperty("inferred",false);
            // Retrieve the more meaningful names
            start = getName(start);
            end = getName(end);
            predicate = getName(predicate);
            // Push the start and end nodes (they will only be created once)
            PushUtility.pushNode(start);
            PushUtility.pushNode(end);
            PushUtility.pushEdge(id++, start, end, predicate, inferred);
         }
      }
   }

   ...

}

 

2. Подталкивание (предполагаемых) данных RDF

Плагин потоковой передачи для Gephi позволяет читать и визуализировать данные, которые отправляются на его главный сервер. Этот главный сервер является интерфейсом REST, который может получать графические данные через интерфейс JSON. PushUtility используется в PushTransactionEventHandler отвечает за генерацию требуемого края и узел формата данных JSON и толкая его к мастеру Gephi.

public class PushUtility {

   private static final String url = "http://localhost:8080/workspace0?operation=updateGraph";
   private static final String nodejson = "{\"an\":{\"%1$s\":{\"label\":\"%1$s\"}}}";
   private static final String edgejson = "{\"ae\":{\"%1$d\":{\"source\":\"%2$s\",\"target\":\"%3$s\",\"directed\":true,\"label\":\"%4$s\",\"inferred\":\"%5$b\"}}}";

   private static void push(String message) {
      try {
         // Create a connection and push the node or edge json message
         HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
         con.setRequestMethod("POST");
         con.setDoOutput(true);
         con.getOutputStream().write(message.getBytes("UTF-8"));
         con.getInputStream();
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }

   // Pushes a node
   public static void pushNode(String label) {
      push(String.format(nodejson, label));
   }

   // Pushes an edge
   public static void pushEdge(int id, String source, String target, String label, boolean inferred) {
      push(String.format(edgejson, id, source, target, label, inferred));
      System.out.println(String.format(edgejson, id, source, target, label, inferred));
   }

}

 

3. Визуализация (предполагаемых) данных RDF

Запустите главный сервер Gephi Streaming. Это позволит Gephi получать (предполагаемые) тройки RDF, которые мы отправляем через его интерфейс REST. Давайте запустим наше Java-приложение и добавим следующие тройки RDF:

http://datablend.be/example/teaches http://www.w3.org/2000/01/rdf-schema#domain http://datablend.be/example/teacher
http://datablend.be/example/teaches http://www.w3.org/2000/01/rdf-schema#range http://datablend.be/example/student
http://datablend.be/example/Davy http://datablend.be/example/teaches http://datablend.be/example/Bob

 

Первые два RDF троек выше состояния , что учитель учит на ученика . Последняя тройка RDF утверждает, что Дэви учит Боба . В результате логический вывод схемы RDF выводит, что Дэви должен быть учителем, а Бобстудентом . Давайте посмотрим, что Gephi визуализировал для нас.

gephi

Ммм … Это не выглядит впечатляюще :-). Давайте использовать некоторое форматирование. Сначала примените раскладку Force Atlas . Затем масштабируйте края и активируйте метки как на краях, так и на узлах. Наконец, примените разбиение по краям, раскрасив стрелки, используя выведенное свойство на краях. Теперь мы можем четко определить предполагаемые утверждения RDF (т.е. Дэви — учитель, а Боб — ученик).

gephi

 

Давайте добавим некоторые дополнительные тройки RDF.

http://datablend.be/example/teacher http://www.w3.org/2000/01/rdf-schema#subClassOf http://datablend.be/example/person
http://datablend.be/example/student http://www.w3.org/2000/01/rdf-schema#subClassOf http://datablend.be/example/person

 

В основном, этот RDF тройки состояния, как учитель и ученик являются подклассами от человека . В результате логарифм RDFS может сделать вывод, что и Дэви, и Боб должны быть людьми . Визуализация Gephi обновляется соответственно.

gephi

 

 

4. Вывод

С помощью всего лишь нескольких строк кода мы можем передавать (выводить) RDF-тройки в Gephi и использовать его мощные инструменты визуализации и анализа для изучения и проверки наших наборов данных. Как всегда, полный исходный код можно найти в общедоступном GitHub-хранилище Datablend . Обязательно зайдите в Интернет, чтобы найти несколько других хороших примеров потокового вещания Gephi, самым крутым из которых, вероятно, является визуализация египетской революции в Twitter .

 

Источник: http://datablend.be/?p=1146