What is a knowledge graph - Pokémon edition
Tags: knowledgegraph, rdf, linkeddata, pokemon
Published: 2020-01-16 10:54:33

---
title: What is a knowledge graph - Pokémon edition
published: true
description: The word "knowledge graph" is used more and more, but what exactly is a knowledge graph? In this blog post I will explain what it is through an example.
tags: knowledge graph, rdf, linked data, pokemon
---

_Originally posted on [my website](https://pieterheyvaert.com/blog/2019/12/27/kg-pkmn/)._

The word "knowledge graph" is used more and more, but what exactly is a knowledge graph? In this blog post I will explain what it is through an example, based on the approach of the [Resource Description Framework](https://www.w3.org/TR/rdf11-concepts/). And, as title suggests, the example will have as theme: Pokémon! Let's jump right in it!

But before we can really get started you need to pick your starter, trainer! Who will it be?

- Charmander: a bipedal, reptilian fire-type Pokémon with a primarily orange body and blue eyes.
- Bulbasaur: a small, quadruped grass/poison-type Pokémon that has blue-green skin with darker patches.
- Squirtle: a small water-type Pokémon that resembles a light blue turtle.

Which one do you want?
[I choose Charmander!](#charmander)
[I choose Bulbasaur!](#bulbasaur)
[I choose Squirtle!](#squirtle)

<h2 id="charmander">Charmander</h2>

Great! You picked the fire-type Pokémon. Here are some facts about Charmander:

> Charmander is a fire-type Pokémon introduced in Generation I.
  It evolves into Charmeleon starting at level 16, which evolves into Charizard starting at level 36. [source](https://bulbapedia.bulbagarden.net/wiki/Charmander_(Pok%C3%A9mon))

Let's see how we can represent the information in this text as a knowledge graph. At the centre of our graph is Charmander, as you can see below.

<img id="charmander-0" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-0.jpg" />

Graphs, including knowledge graphs, are formed of [nodes](https://en.wikipedia.org/wiki/Vertex_(graph_theory)) and [edges](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge). Our graph contains one _node_: Charmander. Now let's have a look at the first sentence:

> Charmander is a fire-type Pokémon introduced in Generation I.

This sentence can be split up in two bits of information:

- Charmander is a fire-type Pokémon.
- Charmander is introduced in Generation <span class="serif">I</span>.

We represent a fire-type Pokémon by the word "FIRE" in an orange rectangle:

<img id="charmander-1" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-1.svg" />

Now our graph contains two nodes: Charmander and the fire-type Pokémon. What is the relationship between these two? "Charmander is a fire-type Pokémon" means that there is a relationship between our two nodes. We add that information to our graph by drawing an _edge_ that connects the two nodes.

<img id="charmander-2a" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-2a.svg" />

We are not done yet though. We know that there is a relationship, but what kind of relationship is it? "Charmander is a fire-type Pokémon" means that Charmander belongs to the group of fire-type Pokémon, or that Charmander is of the type fire. Thus, we add "type" to the relationship.

<img id="charmander-2b" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-2b.svg" />

Note that the direction of the arrow is from Charmander to fire and not the other way around. If that were the case then our sentence would have been "A fire-type Pokémon is Charmander", or something like that. What doesn't make sense.

To add the second bit of information from the first sentence to the graph, we add a "<span class="serif">I</span>" to the graph that represents Generation <span class="serif">I</span>. Now there are three nodes in our graph.

<img id="charmander-3a" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-3a.svg" />

Next, we draw an edge between Charmander and I to show that there is a relationship between the nodes. Finally, we also add what kind of relationship it is. Here we add "generation" to the relationship.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/k1v6tx49xlvaqyqe5zu7.jpg)

The second sentence is

> It evolves into Charmeleon starting at level 16, which evolves into Charizard starting at level 36.

This sentence can be split up in two bits of information:

- Charmander evolves into Charmeleon, starting at level 16.
- Charmeleon evolves into Charizard, starting at level 36.

We add a new node for Charmeleon and add an "evolves" relationship between Charmander and Charmeleon.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ar410y948knt7xdv2016.jpg)

Now, we want to add the fact that the evolution can only happen at level 16 or higher. Again, we add a node. This time for "16", but where do we add the relationship? Do we add it between Charmander and 16? Do we add it between Charmeleon and 16? This is possible, but what happens if a Pokémon can evolve into two different Pokémon? How do you know to which evolution the level belongs? Actually, we want to say that that specific `evolve` relationship only happens starting at level 16. Thus, we want to add "16" to the relationship between Charmander and Charmeleon. But that is not possible: extra information cannot be added to a relationship. But don't despair trainer! If we alter our current graph we can still add that information where we want it.

We introduce a dedicated node for a single evolution. In our case the evolution from Charmander to Charmeleon. But instead of a relationship between Charmander and Charmeleon directly, we now have a relationship between Charmander and the evolution, and a relationship between the evolution and Charmeleon, as shown below.

<img id="charmander-5" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-5.svg" />

Now we can add as much information to that specific evolution as we want. Charmeleon is already one of them, and the level, via the `level` relationship, is the second one:

<img id="charmander-6" src="https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-6.svg" />

We can do the same for the fact that Charmeleon evolves into Charizard starting at level 36:

![](https://pieterheyvaert.com/img/blog/kg-pkmn/charmander-final.svg)

Nice job! We already have a pretty decent knowledge graph. But we are not done yet: we still need to add semantics to the graph. We do this by explicitly defining what each relationship means, so that there is no doubt when others try to understand the data in our knowledge graph. For the relationships we used we can define the following:

- `type`: Pokémon belong to one or more types. When there is a `type` relationship between a subject and object, then this means that the subject is of the type represented by the object. The subject is always a Pokémon, such as Charmander, and the object is always a type, such as Fire.
- `generation`: Pokémon are introduced in a specific generation. When there is a `generation` relationship between a subject and object, then this means that the subject is introduced in the generation represented by the object. The subject is always a Pokémon, such as Charmander, and the object is a always a generation, such as <span class="serif">I</span>. 
- `evolves`: Some Pokémon can evolve.  This relationship is used between a Pokémon, the subject, and a representation of a specific evolution, the object. The subject can be for example Charmander, and the object is then an evolution that is linked to Charmeleon. Note that the object of the `evolves` relationship is not a Pokémon.
- `into`: When a Pokémon evolves, they evolve into another Pokémon. This relationship says into which Pokémon another Pokémon evolves. The subject of this relationship is an evolution, and the object is the Pokémon into which the original Pokémon evolves. The subject is for example an evolution for Charmander, and the object is Charmeleon.
- `level`: When a Pokémon evolves is often determined by the level they should have. The subject of this relationship is the representation of an evolution, and the object is the level that is required before an evolution can take place. The subject is for example an evolution for Charmander, and then the object is the 16.

By incorporating this information in the graph, we now have a real knowledge graph: we have the data together with the meaning of the data. Note that in practice the meaning of the data is not described in plain text, but through the use of [ontologies](https://en.wikipedia.org/wiki/Ontology) (which are knowledge graphs themselves).

Great work trainer! This is the end of our example with Charmander. I hope you now have a better understanding of what knowledge graphs actually are. If you are eager to see more ~~Pokémon~~ knowledge graphs, do not hesitate to check the examples with <a href="#bulbasaur">Bulbasaur</a> and <a href="#squirtle">Squirtle</a>.

If you have any questions or remarks, don’t hesitate to contact me via <a href="mailto:pieter.heyvaert@ugent.be">email</a> or via <a href="https://twitter.com/HeyPieter">Twitter</a>.

<h2 id="bulbasaur">Bulbasaur</h2>

Great! You picked the grass/poison-type Pokémon. Here are some facts about Bulbasaur:

> Bulbasaur is a grass/poison-type Pokémon introduced in Generation I.
  It learns Leech Seed at level 7 and Vine Whip at level 13. [source](https://bulbapedia.bulbagarden.net/wiki/Bulbasaur_(Pokémon))

Let's see how we can represent the information in this text as a knowledge graph. At the centre of our graph is Bulbasaur, as you can see below.

<img id="bulbasaur-0" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-0.jpg" />

Graphs, including knowledge graphs, are formed of  [nodes](https://en.wikipedia.org/wiki/Vertex_(graph_theory)) and [edges](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge). Our graph contains one _node_: Bulbasaur. Now let's have a look at the first sentence:

> Bulbasaur is a grass/poison-type Pokémon introduced in Generation I.

This sentence can be split up in three bits of information:

- Bulbasaur is a grass-type Pokémon.
- Bulbasaur is a poison-type Pokémon.
- Bulbasaur is introduced in Generation <span class="serif">I</span>.

We represent a grass-type Pokémon by the word "GRASS" in a green rectangle:

<img id="bulbasaur-1" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-1.svg" />

Now our graph contains two nodes: Bulbasaur and the grass-type Pokémon. What is the relationship between these two? "Bulbasaur is a grass-type Pokémon" means that there is a relationship between our two nodes. We add that information to our graph by drawing an _edge_ that connects the two nodes.

<img id="bulbasaur-2a" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-2a.svg" />

We are not done yet though. We know that there is a relationship, but what kind of relationship is it? "Bulbasaur is a grass-type Pokémon" means that Bulbasaur belongs to the group of grass-type Pokémon, or that Bulbasaur is of the type grass. Thus, we add "type" to the relationship.

<img id="bulbasaur-2b" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-2b.svg" />

Note that the direction of the arrow is from Bulbasaur to grass and not the other way around. If that were the case then our sentence would have been  "A grass-type Pokémon is Bulbasaur", or something like that. What doesn't make sense.

We do the same for the fact that Bulbasaur is a poison-type Pokémon:

<img id="bulbasaur-3" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-3.svg" />

To add the third bit of information from the first sentence to the graph, we add a "<span class="serif">I</span>" to the graph that represents Generation <span class="serif">I</span>. Now there are four nodes in our graph.

<img id="bulbasaur-4a" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-4a.svg" />

Next, we draw an edge between Bulbasaur and <span class="serif">I</span> to show that there is a relationship between the nodes. Finally, we also add what kind of relationship it is. Here we add "generation" to the relationship.

<img id="bulbasaur-4b" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-4b.svg" />

The second sentence is

> It learns Leech Seed at level 7 and Vine Whip at level 13.

This sentence can be split up in two bits of information:

- Bulbasaur learns Leech Seed at level 7.
- Bulbasaur learns Wine Whip at level 13.

We add a new node for the move "Leech Seed" and add a `learns` relationship between Bulbasaur and Leech Seed.

<img id="bulbasaur-5" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-5.svg" />

Now, we want to add the fact that Leech Seed is learned at level 7. Again, we add a node. This time for "7", but where do we add the relationship? Do we add it between Bulbasaur and 7? Do we add it between Leech Seed and 7?
This is possible, but what happens if Leech Seed can be learned by multiple Pokémon at different levels? How do you know to which Pokémon the level belongs? Actually, we want to say that that specific `learns` relationship only happens at level 7 (for Bulbasaur). Thus, we want to add "7" to the relationship between Bulbasaur and Leech Seed. But that is not possible: extra information cannot be added to a relationship. But don't despair trainer! If we alter our current graph we can still add that information where we want it.

We introduce a dedicated node for the learning of a single move. In our case the learning of Leech Seed by Bulbasaur. But instead of a relationship between Bulbasaur and Leech Seed directly, we now have a relationship between Bulbasaur and the learning of a move, and a relationship between the learning of a move and Leech Seed, as shown below.

<img id="bulbasaur-6a" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-6a.svg" />

Now we can add as much information to that specific learning of a move as we want. Leech Seed is already one of them, and the level, via the `level` relationship,  is the second one:

<img id="bulbasaur-6b" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-6b.svg" />

We can do the same for the fact that Bulbasaur learns Vine Whip at level 13:

<img id="bulbasaur-final" src="https://pieterheyvaert.com/img/blog/kg-pkmn/bulbasaur-final.svg" />

Nice job! We already have a pretty decent knowledge graph. But we are not done yet: we still need to add semantics to the graph. We do this by explicitly defining what each relationship means, so that there is no doubt when others try to understand the data in our knowledge graph. For the relationships we used we can define the following:

- `type`: Pokémon belong to one or more types. When there is a `type` relationship between a subject and object, then this means that the subject is of the type represented by the object. The subject is always a Pokémon, such as Bulbasaur, and the object is always a type, such as Grass.
- `generation`: Pokémon are introduced in a specific generation. When there is a `generation` relationship between a subject and object, then this means that the subject is introduced in the generation represented by the object. The subject is always a Pokémon, such as Bulbasaur, and the object is a always a generation, such as <span class="serif">I</span>. 

- `learns`: Pokémon can learn new moves. This relationship is used between a Pokémon, the subject, and the representation of learning a specific move, the object. The subject can be for example Bulbasaur, and the object the learning of a move that is linked to Leech Seed. Note that the object of the `learns` relationship is not a move.

- `which move`: 
This relationship says which moves a Pokémon learns. The subject of this relationship is the learning of a specific move, and the object is that move which the Pokémon learns. The subject is for example the learning of a specific move by Bulbasaur, and the object is Leech Seed.

- `level`: 
When a Pokémon learns a specific move is often determined by the level they should have. The subject of this relationship is the representation of learning a specific move, and the object is the level that is required before that move can be learned. The subject is for example the learning of a specific move by Bulbasaur, and then the object is the 7.

By incorporating this information in the graph, we now have a real knowledge graph: we have the data together with the meaning of the data.
Note that in practice the meaning of the data is not described in plain text, but through the use of [ontologies](https://en.wikipedia.org/wiki/Ontology) (which are knowledge graphs themselves).

Great work trainer! This is the end of our example with Bulbasaur.
I hope you now have a better understanding of what knowledge graphs actually are. If you are eager to see more ~~Pokémon~~ knowledge graphs,
do not hesitate to check the examples with <a href="#charmander">Charmander</a> and <a href="#squirtle">Squirtle</a>.

If you have any questions or remarks, don’t hesitate to contact me via <a href="mailto:pieter.heyvaert@ugent.be">email</a> or via <a href="https://twitter.com/HeyPieter">Twitter</a>.

<h2 id="squirtle">Squirtle</h2>

Great! You picked the water-type Pokémon. Here are some facts about Squirtle:

> Squirtle is a water-type Pokémon introduced in Generation I.
  It is a starter in Pokémon Blue and Red and
  can be received in Pokémon Yellow from Officer Jenny after receiving the Thunder Badge. [source](https://bulbapedia.bulbagarden.net/wiki/Squirtle_(Pokémon))

Let's see how we can represent the information in this text as a knowledge graph. At the centre of our graph is Squirtle, as you can see below.

<img id="squirtle-0" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-0.svg" />

Graphs, including knowledge graphs, are formed of  [nodes](https://en.wikipedia.org/wiki/Vertex_(graph_theory)) and [edges](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge). Our graph contains one _node_: Squirtle. Now let's have a look at the first sentence:

> Squirtle is a water-type Pokémon introduced in Generation I.

This sentence can be split up in two bits of information:

- Squirtle is a water-type Pokémon.
- Squirtle is introduced in Generation <span class="serif">I</span>.

We represent a water-type Pokémon by the word "WATER" in a blue rectangle:

<img id="squirtle-1" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-1.svg" />

Now our graph contains two nodes: Squirtle and the water-type Pokémon. What is the relationship between these two? "Squirtle is a water-type Pokémon" means that there is a relationship between our two nodes. We add that information to our graph by drawing an _edge_ that connects the two nodes.

<img id="squirtle-2" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-2.svg" />

We are not done yet though. We know that there is a relationship,
but what kind of relationship is it? "Squirtle is a water-type Pokémon" means that Squirtle belongs to the group of water-type Pokémon, or that Squirtle is of the type water. Thus, we add "type" to the relationship.

<img id="squirtle-3" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-3.svg" />

Note that the direction of the arrow is from Squirtle to water and
not the other way around. If that were the case then our sentence would have been "A water-type Pokémon is Squirtle", or something like that. What doesn't make sense.

To add the second bit of information from the first sentence to the graph, we add a "<span class="serif">I</span>" to the graph that represents Generation <span class="serif">I</span>. Now there are three nodes in our graph.

<img id="squirtle-4" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-4.svg" />

Next, we draw an edge between Squirtle and <span class="serif">I</span> to show that there is a relationship between the nodes. Finally, we also add what kind of relationship it is. Here we add "generation" to the relationship.

<img id="squirtle-5" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-5.svg" />

The second sentence is

> It is a starter in Pokémon Blue and Red and
> can be received in Pokémon Yellow from Officer Jenny after receiving the Thunder Badge.

This sentence can be split up in three bits of information:

- Squirtle is a starter in Pokémon Blue.
- Squirtle is a starter in Pokémon Red.
- Squirtle can be received in Pokémon Yellow from Officer Jenny after receiving the Thunder Badge.

For the first bit of information, we add a new node for the game "Pokémon Blue" and add a `starter` relationship between Squirtle and Pokémon Blue.

<img id="squirtle-6" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-6.svg" />

We do the same for the second bit: a node for Pokémon Red and a `starter` relationship between Squirtle and that node.

<img id="squirtle-7" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-7.svg" />

Next, we add a new node for Pokémon Yellow too and a `receive` relationship between Squirtle and that node for the third bit for information.

<img id="squirtle-8" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-8.svg" />

Now, we want to add the fact that Squirtle is received from Officer Jenny in Pokémon Yellow. Again, we add a node for Officer Jenny, but where do we add the relationship? Do we add it between Squirtle and Officer Jenny?
Do we add it between Pokémon Yellow and Officer Jenny? This is possible, but what happens if a Squirtle can be received from different people in different games? How do you know from whom in which game? Actually, we want to say that that specific `receive` relationship only happens  in a specific game from a specific person (for Squirtle). Thus, we want to add Officer Jenny to the relationship between Squirtle and Pokémon Yellow. But that is not possible: extra information cannot be added to a relationship.
But don't despair trainer! If we alter our current graph we can still add that information where we want it.

We introduce a dedicated node for receiving something called "give away".
In our case the receiving of Squirtle from Officer Jenny in Pokémon Yellow. But instead of a relationship between Squirtle and Pokémon Yellow directly, we now have a relationship between Squirtle and the give away, and a relationship between the give away and Pokémon Yellow, as shown below.

<img id="squirtle-9" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-9.svg" />

Now we can add as much information to that give away as we want. Pokémon Yellow is already one of them, and Officer Jenny, via the `from` relationship, is the second one:

<img id="squirtle-10" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-10.svg" />

Finally, we can also add the fact that the Squirtle can only received if you have the Thunder Badge:

<img id="squirtle-final" src="https://pieterheyvaert.com/img/blog/kg-pkmn/squirtle-final.svg" />

Nice job! We already have a pretty decent knowledge graph. But we are not done yet: we still need to add semantics to the graph. We do this by explicitly defining what each relationship means, so that there is no doubt when others try to understand the data in our knowledge graph. For the relationships we used we can define the following:

- `type`: Pokémon belong to one or more types. When there is a `type` relationship between a subject and object, then this means that the subject is of the type represented by the object. The subject is always a Pokémon, such as Squirtle, and the object is always a type, such as Grass.

- `generation`: Pokémon are introduced in a specific generation. When there is a `generation` relationship between a subject and object, then this means that the subject is introduced in the generation represented by the object. The subject is always a Pokémon, such as Squirtle, and the object is always a generation, such as <span class="serif">I</span>. 

- `starter`: Certain Pokémon can be picked as a starter in the games. When there is a `starter` relationship between a subject and object, then this means that the subject can be picked as a starter in the object. The subject is always a Pokémon, such as Squirtle, and the object is always a game, such as Pokémon Blue.

- `receive`: Certain Pokémon can be received from characters in the games. When there is a `receive` relationship between a subject and object, then this means that the subject can be received according to the details described by the object. The subject is always a Pokémon, such as Squirtle, and the object is a representation of giving away a Pokémon.

- `game`: Pokémon can be received in specific games. This relationship is used between representation of giving away a Pokémon, the subject, and a game, the object. The subject can be for example the representation of giving away Squirtle, and the object Pokémon Yellow. Note that the subject of the `game` relationship is not a Pokémon.

- `from`: Pokémon can be received from specific characters in the games. 
This relationship is used between representation of giving away a Pokémon, the subject, and a character from which the Pokémon is received, the object. The subject can be for example the representation of giving away Squirtle, and the object Officer Jenny. 

- `requires`: Sometimes requirements have to fulfilled before Pokémon can be received in games. This relationship is used between representation of giving away a Pokémon, the subject, and a requirement that needs to be fulfilled, the object. The subject can be for example the representation of giving away Squirtle, and the object the Thunder Badge.

Great work trainer! This is the end of our example with Squirtle. I hope you now have a better understanding of what knowledge graphs actually are. If you are eager to see more ~~Pokémon~~ knowledge graphs, do not hesitate to check the examples with <a href="#charmander">Charmander</a> and <a href="#bulbasaur">Bulbasaur</a>.

If you have any questions or remarks, don’t hesitate to contact me via <a href="mailto:pieter.heyvaert@ugent.be">email</a> or via <a href="https://twitter.com/HeyPieter">Twitter</a>.

Pokémon and Pokémon character names are trademarks of Nintendo.