1.2 SparqlLib
1.2.2 Exemple d’utilisation
Nous allons maintenant présenter un exemple d’utilisation du projet SparqlLib pour
interroger un SPARQL endpoint. Prenons comme exemple la requête SPARQL suivante :
SELECT ?a ?b ?c
WHERE
{
?a ?b ?c.
}
LIMIT 10
Cette requête est très basique puisqu’elle permet d’obtenir la liste des 10 premiers triplets
récupérés, sans condition sur ces triplets. Les SPARQL endpoints ne garantissant pas
l’ordre des réponses, sauf si un ordre est stipulé dans la requête. Les 10 premiers triplets
d’une même base peuvent donc être différents lors de plusieurs exécutions. Cette requête
est souvent utilisée pour vérifier si la base contient des triplets.
Le code 8 présente la création et l’éxécution de la requête présentée précédemment.
Les lignes 3 et 4 présentent la création d’un SparqlProxy pour le SPARQL endpoint :
"http ://SPARQL.endpoint.url/". Les lignes 5 et 6 présentent la création de la requête.
1
public static void main(String[] args)
2
{
3
SparqlProxy spIn =
4
SparqlProxy.getSparqlProxy("http://SPARQL.endpoint.url/");
5
SparqlSelect query = new SparqlSelect("?a ?b ?c", "?a ?b ?c.");
6
query.setLimit(10);
7
try
8
{
9
for(JsonNode jnode : spIn.getResponse(query))
10
{
11
System.out.println("new triple : ");
12
System.out.println("\t subject : "+
13
jnode.get("a").get("value").asText());
14
System.out.println("\t predicate : "+
15
jnode.get("b").get("value").asText());
16
System.out.println("\t object : "+
17
jnode.get("c").get("value").asText());
18
}
19
}
20
catch (SparqlQueryMalFormedException ex)
21
{
22
System.err.println("Query mal formed ...");
23
}
24
catch (SparqlEndpointUnreachableException ex)
25
{
26
System.err.println("SPARQL endpoint unreachable ...");
27
}
28
}
Nous définissons ici une requête de type "SparqlSelect" dont le constructeur nécessite en
premier argument les variables de la requête et en deuxième argument le contenu de la
clause WHERE de la requête. La ligne 6 précise la limite pour n’obtenir que les 10 premiers
triplets. Les lignes 9 à 18 présentent le traitement du résultat. La requête est exécutée
sur le SPARQL endpoint à la ligne 9, grâce à l’instruction : "spIn.getResponse(query)".
La réponse est un tableau (de type ArrayList) de JsonNode. Un JsonNode est un objet
JSON représenté grâce à la librairie Jackson
93. La ligne 9 permet donc de parcourir
tous les résultats retournés par la requête. Pour chaque résultat, le triplet obtenu est
affiché. Nous observons qu’il est possible de récupérer la valeur de la variable "a" grâce à
l’instruction :
jnode.get("a").get("value").asText();
D’un résultat ("jnode"), nous récupérons l’objet JSON associé à la clef du nom de la
variable (ici "a") avec la méthode : "jnode.get("a"). Le format de retour JSON recommandé
par le W3C propose de retourner non seulement la valeur de la variable mais aussi son
type s’il existe. Nous traitons les résultats en considérant que tous les résultats sont de
type chaîne de caractères. C’est pour cela que nous récupérons la valeur de la variable
avec la méthode "asText()". Néanmoins, nous aurions pu ajouter un traitement du type
de variable pour appliquer un traitement spécifique suivant les types attendus. De cette
manière, nous aurions pu obtenir une variable de type entier si le résultat retourne une
variable de ce même type.
2. Interface Seals
Comme nous l’avons vu dans le processus de fusion, il est nécessaire de pouvoir aligner
chaque paire de SKB (Cf. section4.2du chapitreIII). Ces alignements permettent ensuite
de générer les candidats sommets. Pour cela, nous avons montré dans l’état de l’art
(Cf. section2 du chapitreII) que le système disponible le plus adapté à nos besoins est
LogMap. Ce projet propose une interface en Java permettant l’utilisation de ce système
d’alignement dans un projet
94. Les systèmes d’alignements sont en constante évolution.
Nous pouvons notamment citer la campagne d’évaluation de l’OAEI sur laquelle nous
nous sommes appuyés pour nos analyses des systèmes d’alignements. Cette campagne
propose chaque année de comparer les différents systèmes d’alignements existants avec
des résultats différents tous les ans. Il est possible qu’à l’avenir, le système LogMap ne
soit plus le système le mieux adapté à nos besoins. Il est donc souhaitable de proposer
un moyen de changer simplement de système d’alignement. C’est dans cette optique
que nous avons réutilisé le projet Seals qui est une interface permettant une utilisation
transparente d’un système d’alignement.
La campagne de l’OAEI impose que chaque système participant utilise le projet Seals
95.
Ce projet propose une interface et une organisation particulière des systèmes d’alignement,
93. https://github.com/FasterXML/jackson
94. https://code.google.com/p/logmap-matcher/wiki/LogMapFromApplications
permettant leur utilisation uniformisée. Nous avons donc utilisé ce projet dans Muskca.
De cette manière, nous pouvons utiliser un système d’alignement à travers le projet Seals.
Ainsi, Muskca pourra facilement s’adapter à tous les systèmes d’alignement évalués par
l’OAEI.
Prenons l’exemple présenté dans l’algorithme 9 permettant d’aligner deux bases de
connaissances.
1
File f1 = new File("out/temp/"+fileNameS1);
2
File f2 = new File("out/temp/"+fileNameS2);
3
4
OClient c = new OClient("logmap2");
5
URL ret = c.align(f1.toURL(), f2.toURL());
6
7
RDFAlignReader reader = new RDFAlignReader(ret);
8
Set<MappingObjectStr> mappings = reader.getMappingObjects();
Algorithm 9:Utilisation de l’interface Seals
Le code présenté dans l’algorithme 9 implémente l’utilisation du projet Seals. Nous
utilisons ici la classe OClient présente dans l’API proposée par Seals. Le constructeur de
cette classe a besoin d’une chaîne de caractères représentant le dossier dans lequel est
présent le système d’alignement que nous souhaitons utiliser ; nous utilisons "logmap2".
Dans ce dossier doivent être présents les fichiers permettant l’exécution du système
d’alignement en question. Ils doivent respecter une organisation particulière spécifiée par
Seals. Le détail de cette organisation est présenté ici :http://oaei.ontologymatching.
org/2011.5/tutorial/tutorialv3.pdf. La classe "OClient" s’appuie sur la valeur d’une
variable d’environnement pour savoir où sont stockés les systèmes d’alignement disponibles
sur le disque dur. Nous exécutons alors Seals dans un sous-processus pour lui passer la
valeur de cette variable. Le projet SealsAligner.jar implémente l’utilisation de la librairie
Seals pour aligner les sources. Une fois le sous-processus terminé, nous récupérons un
fichier contenant les alignements entre les deux bases de connaissances. Ce fichier est
au format RDFAlignement
96. Nous pouvons parcourir ce fichier pour récupérer les
alignements associés.
Nous voyons dans l’algorithme 9 qu’il est très simple de changer le système
d’ali-gnement. En effet, il suffit d’ajouter le dossier contenant l’implémentation du nouveau
système d’alignement au format Seals dans le projet Muskca et changer le paramètre du
constructeur "OClient". Pour simplifier encore plus cette transition, nous avons défini
cette variable comme paramètre de Muskca. De cette manière, il est possible de changer
de système d’alignement sans toucher au code source de Muskca.
Un autre fait notable sur l’utilisation de cette interface est la récupération des bases de
connaissances à aligner. En effet, nous pouvons voir dans l’algorithme que les deux bases
de connaissances sont récupérées comme deux fichiers. Comme nous l’avons montré
précé-demment, nous utilisons un Sparql endpoint pour stocker les SKB à aligner. Néanmoins,
nous avons aussi vu qu’il est possible de récupérer tout le contenu d’un jeu de données
contenu dans un Sparql endpoint par une requête spécifique. Nous effectuons cette tâche
ici. Nous récupérons, pour chaque source, l’intégralité du contenu des SKB à aligner
que nous enregistrons dans des fichiers temporaires. Une fois les alignements récupérés,
nous pouvons supprimer ces fichiers puisque nous continuons ensuite d’interagir avec les
SKB par l’intermédiaire de requêtes Sparql. L’implémentation de cette interface dans
l’outil Muskca a été réalisée grâce à l’aide d’Elodie Thieblin, stagiaire à l’IRIT lors du
développement.
3. Solveur Choco
Comme nous l’avons vu dans la section4.5.4 du chapitre III, nous utilisons un modèle
de contraintes à résoudre pour réussir à obtenir une extension à partir du graphe
d’in-compatibilités. Ce graphe permet la représentation des incompatibilités entre candidats
sommets. Le modèle de contraintes à résoudre que nous avons présenté dans cette section
est présenté au format GMPL car il permet une représentation lisible du modèle. Afin de
trouver une solution à ce modèle de contraintes, nous utilisons un solveur. Un solveur
permet de trouver une solution à partir d’un modèle et des données passées en paramètres.
Un solveur particulièrement rapide et permettant l’interprétation d’un modèle GMPL
est GLPK
97. Bien que ce solveur propose une librairie pouvant faire l’interface entre
une application Java et le solveur, il n’en reste pas moins particulièrement complexe à
installer et à utiliser. Pour simplifier l’utilisation de Muskca, nous avons fait le choix
d’utiliser un solveur implémenté en Java : Choco
98. De cette manière, l’utilisation de
Muskca ne nécessite aucune installation supplémentaire et nous préservons le caractère
multi-plates-formes du projet. De plus, sur trois des quatre catégories de la campagne
d’évaluation MiniZinc
99, le solveur Choco est classé troisième sur 12 participants.
Le solveur Choco ne permet pas de traiter directement un modèle exprimé en GMPL.
Il propose une syntaxe qui lui est particulière pour implémenter le modèle. Nous avons
donc dû réécrire le modèle sous cette forme pour pouvoir exploiter ce solveur
100.
Lors de l’implémentation, nous avons été contraint de modifier les valeurs des scores
de confiance des candidats (sommets et arcs). Ces valeurs sont des décimaux compris
entre 0 et 1. Si nous essayons de résoudre le modèle en considérant des valeurs décimales,
alors nous passons à une catégorie de problèmes non-linéaires. Pour éviter ce problème,
nous avons d’abord arrondi ces valeurs à deux décimales après la virgule, puis nous avons
multiplié ces valeurs par 100. De cette manière, nous obtenons uniquement des entiers à
manipuler. Cela ne change pas le résultat obtenu puisque la fonction objective cherche à
maximiser la somme des valeurs des scores de confiance.
97. https://www.gnu.org/software/glpk/
98. http ://www.choco-solver.org/
99. http://www.minizinc.org/challenge2014/results2014.html
100. https://github.com/Murloc6/Muskca/blob/master/src/MultiSources/Solver/ ExtensionChocoSolver.java