Un moteur de transformation RDF basé sur SPARQL (2)

[la suite du billet précédent sur le manque d’outil pour effectuer des transformations sur un graphe RDF, et la pertinence de cette opération pour l’échange de données.]

Pourquoi faire ?

La problématique est la suivante : je veux échanger des données exprimées en RDF, d’un système de départ à un système d’arrivée; les ontologies de départ et d’arrivée sont différentes, je dois donc transformer les données de départ pour construire un graphe conforme à l’ontologie d’arrivée. Il sera possible que seule une partie m’intéresse, et que toute l’information ne soit pas transformée.

Chaque opération de transformation est exprimée sous la forme d’une requête CONSTRUCT en SPARQL (1), qui permet de construire un pattern dans le graphe d’arrivée en fonction d’un pattern dans le graphe de départ; la requête s’exécute sur le graphe de départ, et ses résultats sont insérés dans le graphe d’arrivée.

Il suffit donc de décrire les requêtes SPARQL à exécuter à chaque opération. A l’usage, un peu de « sucre syntaxique » ne sera pas complètement inutile; certaines opérations de transformations vont en effet souvent revenir, et des raccourcis pour les écrire seront les bienvenus :

  • recopier tous les statements RDF qui ont un prédicat donné (typiquement recopier tous les rdfs:label);
  • recopier tous les statements rdf:type qui ont une certaines valeur, éventuellement en changeant cette valeur si elle n’est pas dans mon ontologie d’arrivée;
  • etc;

Et maintenant… un exemple.

Retour vers le futur

SKOS, la format de publication de vocabulaires structurés, est en cours de finalisation, la recommandation finale du W3C devrait sortir dans les prochaines semaines. SKOS devrait accélérer la publication de vocabulaires structurés « à la sauce » semantic web. Et très certainement, certains vocabulaires déjà publiés dans une grammaire propriétaire vont vouloir/devoir migrer vers SKOS. L’exemple type est la publication RDF des catégories de l’Open Directory, un peu pionnière à l’époque, et carrément préhistorique maintenant (ça date quand même du XXème siècle).

Il y a un petit fichier d’exemple de cette publication; tellement préhistorique que le namespace RDF est faux, que toutes les catégories sont des blank nodes sans URI, et qu’on ne trouve nulle part d’ontologie; c’était les prémisses du RDF, alors il ne faut pas trop en demander; même pas une description textuelle de la grammaire… On en est réduit à des suppositions pour deviner la sémantique (2) :

Il y a une classe « Topic », qui est une catégorie de l’open-directory. Avec les propriétés suivantes :

  • rdf:id : l’ID de ce blank node
  • catid : L’ID de la catégorie
  • d:Description : La description de la catégorie (c’est une propriété Dublin Core)
  • d:Title : Le titre de la catégorie (c’est une propriété Dublin Core)
  • letterbar : Une sous-catégorie présentée dans une liste alphabétique par première lettre (A B C etc…)
  • narrow : Une sous-catégorie
  • narrow1 : Une sous-catégorie lorsque deux hiérarchies sont présentées sous celle-ci (hiérarchie 1)
  • narrow2 : Une sous-catégorie lorsque deux hiérarchies sont présentées sous celle-ci (hiérarchie 2)
  • related : Une catégorie reliée à celle-ci (« voir aussi »)
  • symbolic : Un « faux narrower » vers une autre catégorie dans une branche différente (référence à une ressource de type Alias) (groupe 1)
  • symbolic1 : Un « faux narrower » vers une autre catégorie lorsque plusieurs groupes de liens symboliques sont présents (groupe 2)
  • symbolic2 : Un « faux narrower » vers une autre catégorie lorsque plusieurs groupes de liens symboliques sont présents (groupe 3)
  • Et d’autres dont je vous fais grâce…

Un coup de baguette magique…

Bien, avec une petite idée de la sémantique de ce bazar (ou de ce bazar sémantique), on peut exprimer des règles de transformation simples pour transformer en SKOS la structure des catégories (je ne recopie pas les parties de prefix) :

1. On recopie tous les « rdf:id » des Topic (obligatoire sinon on ne pourra pas identifier les blank nodes puisqu’ils n’ont pas d’URI)

CONSTRUCT {
?x rdf:id ?y
}
WHERE {
?x a od:Topic .
?x rdf:id ?y
}

2. Tous les « Topic » deviennent des « skos:Concept »

CONSTRUCT { ?x a skos:Concept }
WHERE { ?x a od:Topic }

3. le « d:Title » des Topic devient le « skos:prefLabel » des concepts

CONSTRUCT {
?x skos:prefLabel ?y
}
WHERE {
?x a od:Topic .
?x dc:Title ?y
}

4. « narrow », « narrow1 » et « narrow2 » deviennent « skos:narrower »; on perdra donc l’information de la double hiérarchie (3);

CONSTRUCT {
?x skos:narrower ?y
}
WHERE {
{ ?x od:narrow ?y }
UNION
{ ?x od:narrow1 ?y }
UNION
{ ?x od:narrow2 ?y }
}

5. « related » devient « skos:related »;

CONSTRUCT { ?x skos:related ?y }
WHERE { ?x od:related ?y }

… et hop !

En appliquant ces 5 règles sur le fichier d’exemple importé dans Sesame, on obtient ceci. On est passé d’une grammaire à une autre en restant dans des technologies RDF.

Pour aller plus loin dans l’exemple, il faudrait d’une part arriver à exprimer des règles pour transformer toute la grammaire de départ, et d’autre part appliquer ces règles sur l’ensemble des catégories (600 Mo de RDF), ce qui pose des challenges de performance évidents.

Si des outils permettant ce genre de transformation existaient (sous-entendu d’une autre envergure que le bricolage décrit ici), cela faciliterait le rapprochement et l’agrégation de données de grammaires hétérogènes. Dans le contexte d’un web « localement sémantique », ou apparaissent des efforts de sémantisation des données utilisant chacun leur ontologie propre, et où les réutilisations d’ontologies (quand il y en a) ou de morceau d’ontologies restent limités, le fait de pouvoir transformer les données d’un format dans un autre en faciliterait l’échange.

Tous commentaires et remarques sont les bienvenus, et… la suite au prochain numéro.

_____

(1) : SPARQL qui est d’ailleurs une recommandation W3C depuis le 15 janvier dernier.

(2) : ce qui renvoie au débat du billet précédent : très certainement, les gens qui ont créé cette grammaire savait ce qu’elle voulait dire. Mais ils n’ont pas rendu publique la sémantique. Du coup je ne peux que faire des suppositions sur la façon de l’interpréter.

(3) : pour la garder il faudrait étendre SKOS avec 2 sous-propriétés de « skos:narrower »

Laisser un commentaire

Choisissez une méthode de connexion pour poster votre commentaire:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :