Let’s Get Familiar with Some Basic owlready2 Commands
In our last installment of this Cooking with Python and KBpedia series, we learned some KBpedia terminology and loaded the main KBpedia knowledge graph file, kbpedia_reference_concepts.owl
. (Remember, do NOT use the kbpedia_reference_concepts.n3
since owlready2 does not support the Notation3 syntax.) You will need to navigate back to that file location again. One of the aspects of working with Jupyter Notebook is that, once you leave the application, you must re-load your files again whenever you return to the application. As you also recall, it is also necessary to Run the cells in order for a given notebook to restore the states that each cell needs.
In today’s installment we will start to get familiar with some basic commands in owlready2, the API to our OWL2 ontologies. We will then apply these basic approaches to starting efforts to manage these ontologies, which begins with our next installment.
Load and Import the Ontologies
Local File Option
As we instructed in the last installment, the best practice is to provide names to absolute file addresses to make sure you are getting and loading the files you need. Again, in this instance, we call name this file main
and we also add some code to verify the file was found by listing its contents:
= 'C:/1-PythonProjects/kbpedia/sandbox/kbpedia_reference_concepts.owl' main
with open(main) as fobj:
for line in fobj:
print (line)
After you shift+enter
to execute the cell contents, or pick Run from the main menu, you will see a rather long file listing. To clear it from the screen, run Cell → All Output → Clear.
The KBpedia full ontology also depends on (‘imports’) two other files: the KBpedia upper ontology, KKO (kko.owl
), and the SKOS language that we use for annotations (http://www.w3.org/2004/02/skos/core
). The KBpedia full ontology also depends on (‘imports’) two other files: the KBpedia upper ontology, KKO (kko.owl
), and the SKOS language that we use for annotations (http://www.w3.org/2004/02/skos/core
). As we described in the prior CWPK installment, you will need to download the raw version of kko.owl
, and store it in the same location as kbpedia_reference_concepts.owl
downloaded in the prior installment. There is no need to download the skos
file.
Again, we give names to their absolute file addresses, only this time we do not echo their file listings to screen:
= r'C:\1-PythonProjects\kbpedia\sandbox\kko.owl' kko_file
= 'http://www.w3.org/2004/02/skos/core' skos_file
Note one file (kko
) is on disk and we use the native Windows file path (with backward slashes) by invoking the ‘r
‘ (raw) command switch: r'C:\1-PythonProjects\kbpedia\sandbox\kko.owl'
. The other skos
file is found off of the Web.
MyBinder Option
If you are running this notebook online, do NOT run the above routines, since the load routines vary somewhat. Please use the following instructions.
= 'https://raw.githubusercontent.com/Cognonto/CWPK/master/sandbox/builds/ontologies/kbpedia_reference_concepts.owl' main
To view this file, run the next cell, otherwise, run the following cells to load all graphs.
import urllib.request
for line in urllib.request.urlopen(main):
print(line.decode('utf-8'), end='')
= 'https://raw.githubusercontent.com/Cognonto/CWPK/master/sandbox/builds/ontologies/kko.owl' kko_file
= 'http://www.w3.org/2004/02/skos/core' skos_file
Begin the Import
Now that our three files have been given logical names, we are ready to import them into our Jupyter Notebook. Run each of these cells (shift+enter
) in sequence:
from owlready2 import *
= get_ontology(main).load() onto
The asterisk (*) after the import statement means that we want to load all modules in the owlready2 package. One of those functions is get_ontology
. We have also given our main ontology the name of onto
= get_ontology(skos_file).load()
skos onto.imported_ontologies.append(skos)
= get_ontology(kko_file).load()
kko onto.imported_ontologies.append(kko)
We can also place all three commands into a single cell. Note, however, that if you run this consolidated command, that you will see double listings when you invoke print(onto.imported_ontologies)
below. In other words, while there is no harm to loading a file again, you are better off only doing the consolidated alone or the three separate loads alone.
You can run the command below to see this behavior. You should then log off or Kernal → Restart & Clear Output and then only load one set before proceeding further.
from owlready2 import *
= get_ontology(main).load()
onto
= get_ontology(skos_file).load()
skos
onto.imported_ontologies.append(skos)
= get_ontology(kko_file).load()
kko onto.imported_ontologies.append(kko)
Let’s now test to make sure the ontologies have been loaded OK by checking to see if the base IRIs for all graphs are recognized by the system:
print(onto.base_iri)
http://kbpedia.org/kbpedia/rc#
print(skos.base_iri)
print(kko.base_iri)
We can also confirm that the two additional ontologies have been properly imported:
print(onto.imported_ontologies)
Inspecting Ontology Contents
We can now start checking to see if the components of the ontologies have loaded properly. Let’s first check on the classes:
list(onto.classes())
Now, this listing above is interesting. You will see a few warning messages at the top of the listing. This is due to the fact that a very few KBpedia RCs share the same subClasses, making them essentially equivalent classes. The ones listed here are purposeful and do no harm; generally, however, you want to avoid such duplication.
Next, if you scroll down to the bottom you will see that the listing is actually truncated at the bottom with the [...]
indicator. If you were to copy the output listing to an editor you would see there are exactly 1000 items in this list, the default limit for such listings when you first install Jupyter Python. But we know there are more than 58,000 RCs (classes) in the system. To see a complete listing we will need to make a change to our notebook’s configuration file.
First, you need to exit this notebook and at your command line create an IPython config file if you don’t already have one:
ipython profile create
Once generated, this config file can be found in your user’s directory (C:\Users\mike.ipython\profile_default\ipython_config.py
in my case). Make sure and note the dot in the .ipython
directory. Navigate to your appropriate directory and edit this config file to remove the comment for this line and to set the value to ‘0’:
c.PlainTextFormatter.max_seq_length = 0
(which, again, is set to 1000 by default.)
Restart your notebook instance after making this change and run the cells above again. You will now see the full listing of RCs in KBpedia. (A hat tip to StackOverflow for this snippet.)
But, hmmm, where are the classes from the kko
and skos
imports? All we are showing in this list are the RCs from the default ontology of main
.
One of the interesting aspects of owlready2 is its use of what it calls ‘worlds’ to isolate given items into separate namespaces. This allows different projects to be held in memory at one time, including even different open and closed reasoning that may be applied. (A topic for a later installment.)
Now, it is the case that we loaded all three of our ontologies without specifying different ‘world’ namespaces. To see the three combined, let’s actually specify the ‘world’ that is currently active, which is called ‘default’ if not otherwise specified. Rather than our previous onto
namespace, let’s now explicitly refer to this default:
list(default_world.classes())
Note the full IRI listings for the kko
classes at the bottom of the listing. This signals a bit of a namespace recognition problem, that we will address in a few moments.
We can use this same dot approach of namespace.method
for other components in our system. (See Additional Documentation below for a listing of such methods available in owlready2.)
In the two examples below we list the annotation properties for both the main (onto
) and skos
namespaces:
list(onto.annotation_properties())
list(skos.annotation_properties())
Now, one of the RCs we see in our listing is for Eutheria, the technical name for mammals. Using the same format as above we want to get a listing of its subclasses, but adding our rc.
prefix in fact does not work:
list(rc.Eutheria.subclasses())
Hmmm, it is not immediately clear why we get the error that ‘rc
‘ is not defined.
If we look at the KBpedia Web site we see, in fact, that our prefix to individual RCs is actually http://kbpedia.org/kko/rc/
with the trailing ‘/’. owlready2 documentation indicates it uses the ‘#’ sign as its default separator for vocabulary terms. Since our system uses the ‘/’, perhaps something got screwed up in how owlready2 recognizes our namespace.
One way to deal with this potential problem explicitly is to make a direct assignment for what the IRI prefix should be. We do so via this command, where we are directing the prefix ‘rc
‘ to recognize our standard base IRI:
= onto.get_namespace('http://kbpedia.org/kko/rc/') rc
With this new namespace assignment, we run the command again:
list(rc.Eutheria.subclasses())
Voilà! We now have the proper registry of the namespace in our system.
Along with absolute file names that we reference via assigned names, it is also good practice to make sure that our namespaces are properly registered before beginning work with owlready2. (I may discover better tips as we move ahead that I will post when and if discovered.)
We can also check out the properties for this concept:
list(rc.Eutheria.get_class_properties())
And, pull out our definition for the concept:
print(rc.Eutheria.definition)
There is also the alternate IRI sytax for identifying a class, in this case to obtain all of the children, grandchildren, etc., of our Mammal concept (which produces a long list of mammals!):
'http://kbpedia.org/kko/rc/Mammal'].descendants() IRIS[
Since we have used the Python list
method quite a bit, we can get direct assistance about the method with the standard command:
help(list)
We can also conduct searches of our RCs, including with wildcards (*) in either the pre or post positions:
= "*Luggage*") onto.search(iri
Another helpful command in owlready2 is to instruct the system what paths to search when it looks for referenced names:
"C:/1-PythonProjects/kbpedia/sandbox") onto_path.append(
And, we can get a listing of all such paths registered:
list(onto_path)
Lastly, for this installment, we can close by saving the ontology we have been working on, being careful in this instance to give a different file name to prevent inadvertent overwriting of our initial input file:
file = "C:/1-PythonProjects/kbpedia/sandbox/owl-test.owl", format = "rdfxml") onto.save(
To properly exit the notebook, first pick File → Save and Checkpoint, then File → Close and Halt. This will return you to the main Jupyter files screen, from which you Quit and then close the tab. Return to the command window and finish shutting down the service with ctrl+c
. That will return you to the command prompt, from which you may again start up a ‘Jupyter Notebook
‘ instance.
Additional Documentation
Here is a listing of owlready2 ontology methods.
*.ipynb
file. It may take a bit of time for the interactive option to load.