Inference in Graph Database. In this blog post, I will try to... | by Atakan Güney | Towards Data Science

In this blog post, I will try to explain what the inference is on Semantic Web and to show how the inference can be applied in a local graph database. The outline of my blog is the following:
What is Inference?What is used for?Types of the procedureGraph Database and OntologyInference on DatabaseConclusion
What is Inference?
What is used for?
Types of the procedure
Graph Database and Ontology
Inference on Database
Conclusion
As described in W3 standards, the inference is briefly discovering new edges within a graph based on a given ontology. On Semantic Web, the data as modeled as triples, i.e. two resources and one relationship between them. The inference is that inferring new triples based on the data and some additional information, which may be in the form of vocabularies(ontologies) and rule sets(logic). For example, let’s say we have two sources: John the human and Max the dog and we have information that John has Max and Max is Dog. In addition, if we have an additional vocabulary, which includes information; Dog is Mammal. We can infer that Max is Mammal and John has Mammal.
Inference on Semantic Web is used for improving the quality of data integration on the web. It automatically provides new links within the data and analyzes the content. Similarly, it also checks for consistency of the data on the web. For example, let’s say we have the data that includes information Dora is Cow and Dora is Carnivore. If we check the animal’s ontology, it is inconsistent with that the Cows are vegetarians.
As stated, the automatic discovery of new links is done by either using vocabulary or a rule set. On the Semantic Web, vocabularies or ontologies can be described in OWL, SKOS, and RDF whereas rule sets are described in RIF. These technologies are recommendations of the W3C foundation. Additionally, the ontologies are based on class and sub-class relationships, however, rule sets are describing general rules to generate new relationships based on existing ones.
We are able to store our data as graphs thanks to the new handy technologies in the database field. Especially, the Graph Databases. It is very nice to have such a powerful tool. The nicer is that we can make them more powerful by including common vocabularies, ONTOLOGIES 🚀
In my previous blog post, I described how to import an ontology into a Neo4j database by using a plugin called NSMNTX — Neo4j RDF & Semantics toolkit. Please read first that blog post before continue.
medium.com
In addition to importing a database, now we do inference on it. As you would remember from the previous post, we could import the ontology from an external store online. But for simplicity in this blog post, we will create our Animal World ontology by ourselves. Let’s do it 😅
CREATE (a: AnimalType{authoritativeLabel: "Mammals", dbLabel: "Mammals"})CREATE (b: AnimalType{authoritativeLabel: "Dog", dbLabel: "Dog"})CREATE (c: AnimalType{authoritativeLabel: "Cat", dbLabel: "Cat"})CREATE (d: AnimalType{authoritativeLabel: "Horse", dbLabel: "Horse"})CREATE (a)<-[:IS_A]-(b)CREATE (a)<-[:IS_A]-(c)CREATE (a)<-[:IS_A]-(d)
This will produce some nodes which have the type AnimalType and they have IS_A relationship. Let’s see.
This AnimalType is telling us about relations between animals. So, now create some animal instances which are considered as Pets.
CREATE (:Pet:Dog{name: "Max"})CREATE (:Pet:Cat{name: "Missy"})CREATE (:Pet:Horse{name: "DulDul"})
And this will produce
Our first inference would be getting all Mammals. So, as you can see our data consists of only three distinct nodes.
CALL semantics.inference.nodesLabelled('Mammals',  { catNameProp: "dbLabel", catLabel: "AnimalType", subCatRel: "IS_A" }) YIELD nodeRETURN node.name as name, labels(node) as categories
This will return
So, without having any relation in our database we inferred common label relation by using our vocabulary.
Now, let’s add some relations.
MATCH (c:Cat{name: "Missy"})MATCH (d:Dog{name: "Max"})MATCH (h:Horse{name: "DulDul"})CREATE(jn: Person{name: "John"})CREATE(al: Person{name: "Alex"})CREATE (jn)-[:LOVES]->(d)CREATE (h)-[:LOVES]->(d)CREATE (al)-[:LOVES]->(c)
This will result
As a second kind of inference, let’s try to get all animal lovers ❤️
MATCH (p)-[:LOVES]->(pt)WHERE semantics.inference.hasLabel(pt,'Mammals', { catNameProp: "dbLabel", catLabel: "AnimalType", subCatRel: "IS_A" })RETURN p.name as name
And results come...
Now, let’s do inference on vocabulary itself. Before that, let’s extend it a little bit
MATCH (h:AnimalType{authoritativeLabel: "Horse"})MATCH (d:AnimalType{authoritativeLabel: "Dog"})MATCH (c:AnimalType{authoritativeLabel: "Cat"})CREATE (:Film {title: "A Dog's Journey"})-[:HAS_SUBJECT]->(d)CREATE (:Film {title: "Cats"})-[:HAS_SUBJECT]->(c)CREATE (:Film {title: "The Mustang"})-[:HAS_SUBJECT]->(h)
And visualize it
We added some movies, which has subject as animals. Our next inference type would be node in category type of inference. Let’s try to get all films, which has subject as Mammals
MATCH (cat:AnimalType { authoritativeLabel: "Mammals"})CALL semantics.inference.nodesInCategory(cat, { inCatRel: "HAS_SUBJECT", subCatRel: "IS_A"}) yield nodereturn node.title as film
And...
We got what we asked for 😈
Now, let’s see our last inference type. Our data takes place, again. But before that let’s define other AnimalType, which is different than Mammals: Fish and Shark. Similarly, let’s add another IS_A relationship.
CREATE (f:AnimalType{authoritativeLabel: "Fish", dbLabel: "Fish"})CREATE (sh:AnimalType{authoritativeLabel: "Shark", dbLabel: "Shark"})CREATE (f)<-[:IS_A]-(sh)
And create a film about Shark
MATCH (s: AnimalType{authoritativeLabel: "Shark"})CREATE (:Film {title: "Frenzen"})-[:HAS_SUBJECT]->(s)
Our final vocabulary will look like the following
Now add new information into our data
MERGE (p:Person { name : "John"}) with pMATCH (film1:Film { title : "Cats" })MATCH (film2:Film { title : "Frenzen" })WITH p, film1, film2CREATE (film1)<-[:LIKES]-(p)-[:LIKES]->(film2)
See the corresponding data in our graph database
So, our person John likes both Cats and Frenzen. Let’s query which of the films that John likes has subject about Fish.
MATCH (fish:AnimalType { authoritativeLabel: "Fish"})MATCH (:Person { name : "John"})-[:LIKES]->(b:Film)WHERE semantics.inference.inCategory(b,fish,{ inCatRel: "HAS_SUBJECT", subCatRel: "IS_A"})RETURN b.title as title
Yeah, we got our result 💪
Recently, NoSQL databases attracted attention instead of relational databases. Among various kinds of NoSQL databases, Graph-based ones are getting more attraction in time. In my humble opinion, it will be valuable including external information onto a Graph Database and managing, analyzing and proof checking it. Importing ontologies is a nice and compact way of doing that. I hope you enjoyed the blog. For more interesting tools, stay tuned 🚀