Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Constructeurs et restrictions, propriétés de classes

Introduction

Dans ce chapitre, nous verrons comment manipuler l’ensemble des constructeurs OWL en Python avec Owlready. Nous verrons aussi les différents raccourcis que propose Owlready pour faciliter l’utilisation des constructeurs et en particulier des restrictions.

Créer des constructeurs

Les constructeurs OWL permettent de définir des constructions logiques à partir de classes, d’individus et de propriétés (voir chapitre Les ontologies OWL, section Restrictions et section Union, intersection et complément).

Les restrictions sont créées avec la syntaxe propriété.type(valeur), en utilisant les mêmes mots-clefs pour les types que dans Protégé :

  • propriété.some(Classe) pour une restriction existentielle

  • propriété.only(Classe) pour une restriction universelle

  • propriété.value(individu ou donnée) pour une restriction de valeur (role-filler)

  • propriété.exactly(cardinalité, Classe) pour une restriction de cardinalité exacte

  • propriété.min(cardinalité, Classe) et

  • propriété.max(cardinalité, Classe) pour les restrictions de cardinalité minimale ou maximale

Les opérateurs logiques NON, ET et OU (complément, intersection et union) sont obtenus de la manière suivante :

  • Not(Classe)

  • And([Classe1, Classe2,...]) ou Classe1 & Classe2 & ...

  • Or([Classe1, Classe2,...]) ou Classe1 | Classe2 | ...

Un ensemble d’individus est obtenu de la manière suivante :

  • OneOf([individu1, individu2,...])

L’inverse d’une propriété est obtenu de la manière suivante :

  • Inverse(Propriété)...

Accéder aux paramètres des constructeurs

Les propriétés suivantes permettent d’accéder aux informations contenues dans les principaux constructeurs (pour la liste complète des constructeurs et de leurs propriétés, se référer au manuel de référence en annexe, section Constructeurs (classe ClassContruct et descendantes)) :

  • Opérateurs logiques ET et OU (intersection et union, classe And et Or respectivement) :

  • Attribut Classes : la liste des classes sur lesquelles portent l’intersection ou l’union

  • Restrictions (classe Restriction) :

  • Attribut property : la propriété sur laquelle porte la restriction

  • Attribut type : le type de la restriction (une valeur parmi les constantes SOME, ONLY, VALUE, MAX, MIN et EXACTLY)

  • Attribut value : la valeur sur laquelle porte la restriction (une classe pour les types SOME, ONLY, MAX, MIN et EXACTLY, un individu ou une valeur pour le type VALUE)

  • Attribut cardinality : le nombre de relations concernées (uniquement disponible pour les restrictions de type MAX, MIN et EXACTLY)

Par exemple, si l’on reprend la classe Streptocoque et sa définition équivalente, nous pouvons l’analyser de la manière suivante :

>>> onto.Streptocoque.equivalent_to[0]  
  bacterie.Bactérie  
& bacterie.a_pour_forme.some(bacterie.Ronde) ...

Restrictions comme propriétés de classe

Owlready permet d’accéder à l’ensemble des constructeurs OWL, comme nous l’avons vu dans les deux sections précédentes. Cependant, la création des constructeurs ou l’accès aux informations qui y sont contenues est souvent complexe et laborieux. C’est pourquoi Owlready propose également plusieurs raccourcis pour faciliter l’utilisation des constructeurs. Nous avons déjà vu un exemple de raccourci pour accéder aux restrictions existentielles comme s’il s’agissait de propriété de classe, au chapitre Accéder aux ontologies en Python, section Restrictions existentielles.

En effet, les restrictions sont souvent utilisées pour représenter les relations entre classes. Les relations entre deux classes sont plus complexes que celles entre deux individus. Dans ce dernier cas, soit la relation existe (ce qui correspond à un triplet dans le quadstore), soit elle n’existe pas. Au contraire, une classe rassemble plusieurs individus, ce qui conduit à plusieurs cas de figure :

  • Tous les individus de la première classe sont en relation avec au moins un individu de la seconde classe : c’est la restriction existentielle (« some » dans Protégé).

  • Tous les individus de la première classe sont en relation avec uniquement des individus de la seconde classe : c’est la restriction universelle (« only » dans Protégé).

  • Chaque individu de la première classe est en relation avec chaque individu de la seconde classe : OWL ne permet pas directement de créer ce type de relation entre classes, cependant il est possible d’obtenir un résultat équivalent en réifiant la propriété, c’est-à-dire en la transformant en une classe associée à deux propriétés.

Owlready permet de traduire les relations entre deux classes en propriétés de classe, et vice versa. Cela permet de créer ou de lire facilement des constructeurs correspondant aux formes suivantes :

  • (Propriété some Classe)

  • (Propriété value individu)

  • (Propriété only (Classe or ... ))

  • (Propriété only ({ individu,... }))...

Classes définies

Owlready permet également d’utiliser les propriétés de classe pour créer des classes définies, avec des définitions de la forme suivante :

Classe_parente1 and Classe_parente2 ...  
and (Propriété some Classe) ...  
and (Propriété value individu) ...  
and (Propriété only (Classe ... or { individu,... })) 

Pour cela, Owlready utilise l’annotation booléenne spéciale defined_class pour indiquer qu’une classe est définie. Si cette annotation est vraie (True) pour une classe, Owlready générera une définition à partir des propriétés de classe, à la place des restrictions vues à la section précédente. La valeur par défaut est faux (False) pour cette annotation.

L’exemple suivant crée une nouvelle classe définie de Bactérie :

>>> with onto:  
...     class Corynebacterium(onto.Bactérie):  
...         defined_class = True  
...         gram_positif = False  
...         a_pour_forme = onto.Allongée  
...         a_pour_regroupement = [onto.EnAmas] 

Notez la première ligne du corps de la classe, « defined_class = True », qui indique qu’il s’agit...

Exemple : créer l’ontologie des bactéries en Python

Le programme suivant, donné à titre d’illustration, permet de recréer l’ontologie des bactéries de zéro, entièrement en Python, en utilisant des constructeurs. La création d’une ontologie en Python peut sembler plus laborieuse qu’avec Protégé, mais elle présente aussi des avantages : en particulier, il est possible de copier-coller des définitions, ce qui permet de créer rapidement des classes similaires.

# Fichier creer_onto.py  
from owlready2 import *  
onto = get_ontology("http://lesfleursdunormal.fr/static/ \ 
                    _downloads/bacterie.owl#")  
  
with onto:  
   class Forme(Thing): pass  
   class Ronde(Forme): pass  
   class Allongée(Forme): pass  
 
   AllDisjoint([Ronde, Allongée])  
   class Regroupement(Thing): pass  
   class Isolé(Regroupement): pass  
   class ParDeux(Regroupement): pass  
   class EnAmas(Regroupement): pass  
   class EnChaîne(Regroupement): pass  
   class EnChaînette(EnChaîne): pass  
   class EnFilament(EnChaîne): pass  
 
   AllDisjoint([Isolé...

Exemple : peupler une ontologie avec des classes définies

Dans cet exemple, nous allons reprendre le peuplement de l’ontologie des bactéries. Nous effectuerons cette fois-ci un peuplement avec des classes (comme au chapitre précédent, section Peuplement par des classes), mais en utilisant des définitions avec des relations d’équivalence. Nous réutiliserons le même fichier CSV que précédemment (appelé peuplement_classes.csv) :

images/p67.png

Le peuplement peut être réalisé de deux manières : soit en utilisant les propriétés de classe (ce qui est l’option la plus simple), soit en utilisant les constructeurs (ce qui est plus compliqué, mais peut être nécessaire si vous souhaitez créer des définitions plus complexes que celles générées par Owlready).

1. Peuplement en utilisant les propriétés de classe

Le programme suivant utilise les propriétés de classe pour peupler l’ontologie des bactéries avec des classes définies, à partir des données du fichier CSV ci-dessus :

# Fichier peuplement_classes_definies1.py  
from owlready2 import *  
import csv, types  
 
onto = get_ontology("bacterie.owl").load()  
 
onto.gram_positif.class_property_type = ["some"]  
onto.a_pour_forme.class_property_type = ["some", "only"] 
onto.a_pour_regroupement.class_property_type = ["some"]  
 
onto_classes = get_ontology("http://lesfleursdunormal.fr/static/ \ 
                            _downloads/bacterie_classes_definies.owl") 
onto_classes.imported_ontologies.append(onto)  
 
f = open("peuplement_classes.csv")  
reader = csv.reader(f)  
next(reader)  
 
with onto_classes:  
   for ligne in reader:  
       identifiant, parent, gram_positif, forme, regroupement = ligne  
 
       if parent: parent = onto[parent]  
       else: parent = Thing  
 
 ...