• Aucun résultat trouvé

Formalisation du raisonnement incrémental

4.2.1 Méthode générale . . . 66 4.2.2 Filtrage des règles . . . 67 4.2.3 Bufferisation et filtrage avancé . . . 68 4.3 Caractéristiques attendues du système . . . 69

4.3.1 Vue d’ensemble . . . 69 4.3.2 Exécution parallèle et passage à l’échelle . . . 71 4.3.3 Limitation des doublons . . . 71 4.3.4 Gestion de flux de données . . . 71 4.3.5 Agnosticisme au fragment . . . 72 4.4 Fonctionnement détaillé . . . 73 4.4.1 Distributeur général . . . 73 4.4.2 Buffers . . . 73 4.4.3 Exécuteurs de règle . . . 75 4.4.4 Distributeurs . . . 76 4.4.5 Triplestore . . . 77 4.4.6 Détection de la fin de l’inférence . . . 79 4.4.7 Exemple détaillé d’inférence avec notre architecture . . 80 4.5 Indépendance au fragment . . . 84

4.5.1 Graphe de dépendance des règles . . . 84 4.5.2 Définition et exécution des règles . . . 86

4.6 Paramètres de l’architecture . . . 87

4.6.1 Taille des buffers . . . 87 4.6.2 Timeout . . . 88 4.6.3 Fragment . . . 88 4.7 Modes d’inférence . . . 90

4.7.1 Mise en situation . . . 90 4.7.2 Raisonnement dirigé : la qualité d’abord . . . 91 4.7.3 Raisonnement à l’aveugle . . . 95 4.8 Bilan de la solution proposée . . . 98

Ce chapitre présente l’architecture de notre système de raisonnement incrémental. Nous commençons ce chapitre par situer le problème que nous abordons dans la section 4.1. Après avoir introduit le formalisme du raisonnement incrémental, nous donnons l’ensemble des critères qui nous ont amenés à proposer cette architecture (section 4.3) : exécution parallèle et passage à l’échelle, limitation de la propagation des doublons au plus tôt, gestion de flux de données et agnosticisme au fragment utilisé pour l’inférence. Par la suite, nous détaillons le fonctionnement de notre architecture (section 4.4) en donnant pour commencer une vue d’ensemble, suivie d’une description des différents modules qui la composent, pour terminer par un exemple illustrant comment le système se comporte de l’arrivée de nouveaux triples jusqu’à la fin de l’inférence. Nous revenons ensuite sur un aspect essentiel du raisonneur : sa capacité à s’adapter au fragment, en présentant le graphe de dépendance des règles, indispensable à l’initialisation de l’architecture, puis en détaillant la manière dont les règles sont effectivement appliquées. Nous présenterons après cela les trois paramètres de l’architecture : la taille des buffers, la valeur du timeout et le fragment lui-même. Pour finir, nous présentons deux modes d’inférence permettant d’adapter le fonctionnement de l’architecture à des contraintes temporelles (section 4.7). Le premier mode se place dans le cas de figure où l’utilisateur connaît les connaissances qu’il souhaite utiliser. Il peut, dans ce mode, prioriser ces connaissances afin qu’elles soient inférées en priorité. Le second propose une adaptation sans connaissance a priori sur l’utilisation des données.

4.1 Problématique

L’état de l’art a montré des solutions de raisonnement par lots permettant le passage à l’échelle de ce processus complexe et coûteux. Ces solutions ne permettent pas de maintenir la matérialisation des données inférées après l’ajout de nouvelles données, sans reprendre tout le processus de raisonnement. Le raisonnement incrémental répond à ce besoin en utilisant les matérialisations antérieures et en y appliquant des mises à jour. Les solutions existantes sont cependant peu nombreuses et peinent à passer à l’échelle pour des mises à jour importantes. Par exemple, la solution présentée dans [16] n’est efficace que lorsque les mises à jour ne dépassent pas 2% de l’ontologie de départ. Dans ce chapitre, nous décrivons notre architecture pour le raisonnement incrémen-tal. Nous avons centré nos efforts pour pallier les inconvénients des solutions que nous avons étudiées tout en intégrant les points clés décrits dans la section 3.4. Pour ré-pondre au problème posé de manière optimale, notre architecture a été définie afin de permettre le passage à l’échelle du processus de raisonnement incrémental, en gérant l’arrivée de nouvelles données sous forme de flux de triples. Les doublons sont gérés dès leur génération afin de limiter leur impact sur les performances. Enfin, le découpage de l’architecture en modules indépendants permet à notre solution d’être agnostique face au fragment utilisé pour le raisonnement. Chaque module est associé à une règle d’inférence afin d’améliorer la répartition de charge. La seule exigence nécessaire pour utiliser cette architecture est de disposer d’une implémentation de chaque règle d’inférence utilisée.

4.2 Formalisation du raisonnement

incrémental

4.2.1 Méthode générale

Nous décrivons dans cette section notre méthode permettant de rendre le raisonne-ment incréraisonne-mental.

Soit G un graphe RDF, représentant une base de connaissances avant la matérialisa-tion. Soit un système déductif |= et un graphe H tel que G |= H. H représente donc la matérialisation de G, c’est-à-dire la base de connaissances après inférence. On souhaite maintenant ajouter des triples dans H, regroupés dans un graphe ∆ et calculer la maté-rialisation sur H ∪ ∆. Le système déductif |= permet d’obtenir la matématé-rialisation F telle que H ∪ ∆ |= F . Puisque H est obtenu en appliquant |= à G, on a également G ∪ ∆ |= F . Le problème ici est qu’aucun parti n’est tiré de la matérialisation précédente. On cherche donc le système déductif |=tel que H |=F , qui ne calcule que la

matérialisa-tion entraînée par les nouveaux faits de ∆. Plus précisément, pour que les conclusions d’une règle soient ajoutées à la matérialisation, au moins une de ses prémisses doit appartenir à ∆.

Un système incrémental est donc un ensemble de systèmes déductifs {|= , |=1, . . . , |=

n} qui, pour un graphe G, un ensemble de mises à jour {∆1, . . . , ∆n} et un ensemble de graphes {H1, . . . , Hn}, est défini tel que :

• G |= H1;

• Hi|=iH(i+1) (1 ≤ i ≤ n).

L’algorithme 4.1 présente une adaptation de l’algorithme 2.1 permettant de passer de

Hià Hi+1. La première différence est que cet algorithme prend en entrée deux ensembles de triples : Hi contenant la matérialisation résultant du dernier raisonnement et ∆ contenant les nouveaux triples ajoutés à la base de connaissances. La seconde est que, comme précisé plus haut, seules les conclusions des règles dont toutes les prémisses sont dans Hi∪ ∆ et au moins une dans ∆, sont ajoutées à Hi+1. L’ensemble des prémisses peuvent toutes se trouver dans ∆.

Pour simplifier la notation, on définit ∈1 (au moins 1 dans) comme suit :

Algorithme 4.1 – Adaptation de l’algorithme 2.1 pour le raisonnement incrémental Données : Hi, Regles, ∆ Résultat : Hi+1 1 Hi+1← Hi∪ ∆ 2 do 30 ← ∅

4 pour regle ∈ Regles faire

5 pour regle.premices ∈ Hi ∪ ∆ et regle.premices ∈1∆ faire

60 ← regle.conclusions\Hi+1

7 Hi+1 ← Hi+1∪ regle.conclusions

8 fin

9 fin

10 ∆ ← ∆0

11 while ∆ , ∅;

4.2.2 Filtrage des règles

Dans l’algorithme 4.1, les prémisses de chaque règle d’inférence sont recherchées dans

Hi ∪ ∆. Plutôt que de faire cette recherche sur l’ensemble des règles, l’algorithme 4.2 filtre les règles dont au moins l’une des prémisses peut se trouver dans ∆. Pour cela, une règle n’est utilisée que si au moins un prédicat des triples de ∆ contient au moins l’un des prédicats présents dans les prémisses de la règle. Par exemple, la règle cax-sco ne sera utilisée que si au moins l’un des triples de ∆ a pour prédicat subClassOf.

On notera R l’ensemble des règles d’inférence. Pour des questions de lisibilité, on définit predicats(G) qui retourne la liste p ∈ U des prédicats contenus dans les triples de G. On définit une application Regles : 2U → 2R qui associe à un ensemble d’URI U le plus grand ensemble de règles R ∈ R tel que ∀r ∈ R, predicats(R) ∈ U .

L’algorithme 4.2 contient la modification de la boucle de parcours des règles (c.f. ligne 4) permettant de mettre en place le filtrage des règles.

Avec cette modification, un système |=, en plus de limiter les conclusions à ajouter à la base de connaissances, n’utilise qu’une partie des règles afin d’alléger le processus.

Algorithme 4.2 – Filtrage des règles d’inférence en fonction des triples utilisés pour l’inférence

Données : Hi, Regles, ∆

Résultat : Hi+1

1 Hi+1← Hi∪ ∆

2 do

30 ← ∅

4 pour regle ∈ Regles(predicats(G)) faire

5 pour regle.premices ∈ Hi∪ ∆ et regle.premices ∈1∆ faire

6 ∆ ← regle.conclusions\Hi+1

7 Hi+1← Hi+1∪ regle.conclusions

8 fin

9 fin

10 ∆ ← ∆0

11 while ∆ , ∅;

4.2.3 Bufferisation et filtrage avancé

La construction des conclusions de règles à partir des prémisses est une opération simple et linéaire. En revanche, la recherche de prémisses dans un ensemble de triples est l’opération la plus coûteuse de l’algorithme 4.2. Il est donc préférable de limiter cette recherche.

Dans cette optique, il est donc déconseillé d’utiliser l’algorithme 4.2 pour chaque nouveau triple. Il est plus intéressant et moins coûteux de ne lancer l’inférence que lorsque ∆ contient déjà un certain nombre de triples. Les triples en attente doivent donc être stockés dans une structure dédiée. Les buffers, ou espaces de mémoire tampon, sont les structures utilisées dans ce genre de situation. Il s’agit d’ensembles d’objets, ici de triples, déclenchant une action particulière, ici l’inférence, lorsque le nombre d’éléments présents dépasse un certain seuil.

Comme nous l’avons vu dans la section précédente, il est possible de savoir quels triples sont susceptibles d’être utilisés par une règle. Grâce à cela, le filtrage peut être amélioré en filtrant les triples par règle et non plus de manière globale. Ainsi, chaque règle peut disposer de son propre buffer, ne recevant que les triples qui peuvent être utilisés par cette règle. La quantité de triples dans laquelle les prémisses sont recherchées pour chaque règle est réduite et il en est donc de même pour le coût de l’opération.

Une fois l’inférence pour une règle donnée terminée, les conclusions générées ne seront envoyées qu’aux règles susceptibles de les utiliser.