Exercices de sémantisation de l'information
Annexe du tutoriel : +Cartographie des PAIR
Autre annexe intéressante : +Web distribu avec LDP
 

Intro

 
L'objectif de ce PAD est de partir d'informations simples et d'apprendre à les sémantiser dans différents formats/syntaxes RDF.
 
Ensuite, une fois que nous aurons une même information (triplet) sous tous les formats, nous apprendrons à le stocker en utilisant le protocole LDP sur un des serveurs de triplets.
 
Les serveurs possibles (pour l'Assemblée Virtuelle) :
  • Rwwplay! est un serveur LDP qui stocke les triplets sous forme de fichier sur le disque dans un répertoire appelé "container".
  • Semantic Forms : est un serveur SPARQL contenant une interface LDP. Il stocke les triplets dans sa base de donnée Blazegraph.
 
Une fois ces informations sémantisées en base, elles seront interopérables par n'importe quelle application qui en a besoin et qui respecte les normes du web sémantique.
 

Références pour approfondir

 
Pour ceux qui débutent, vous pouvez lire 
 
Les différentes syntaxes du web sémantique :
 
Outils de transformation de syntaxes
Il existe des outils en ligne ou en local pour effectuer la transformation d'une syntaxe vers une autre.
  • Ou raptor2 sur Linux : 
sudo apt-get install raptor2-utils
 
Exemples d'ontologies déjà existantes sur le web et très utilisées : 
 
Il faut donc comprendre que l'Assemblée virtuelle est en train d'écrire elle aussi une nouvelle ontologie appelée PAIR (Project, Actor, Idea, Resource), au même titre que FOAF ou Dublin Core qui ont été créées par d'autres acteurs du web d'une manière libre et spontanée ! :)
 

Exemple de base

 
Pour que l'exemple de base parle à tout le monde, et surtout aux membres de l'Assemblée Virtuelle, nous allons partir d'un cas d'utilisation simple, non ambigu, et adapté au contexte de ce tutoriel.
 
Phrase (sujet, verbe, complément) en français :
L'Assemblée virtuelle contribue au projet "Carto PAIR"
 
Analyse de la phrase en "objet, prédicat, objet" (linked data):
  • Sujet : <Assemblée_Virtuelle>
  • Prédicat : contribue à
  • Objet : <Carto PAIR>
 
 

Analyse de la sémantisation de l'exemple de base

Pour savoir comment sémantiser cet exemple, nous allons partir du travail qui a été réalisé sur  l'ontologie de l'AV par des membres de l'AV.
 
Analyse du sujet <Assemblée_Virtuelle>
Et plus précisément de la définition spécifique de "av:actor", les Acteurs (le "A" de PAIR).
 
Ce fichier définit le vocabulaire "av:actor" en utilisant le format "turtle".
Le format Turtle est un des nombreuses syntaxes du web sémantique pour représenter des du RDF (voir références plus haut)
 
On lit dans ce fichier actor.ttl que les acteurs peuvent être : 
  • des individus
  • des organisations
 
Dans notre exemple, l'Assemblée virtuelle est une organisation (et pas un individu). Il va falloir le préciser sémantiquement.
Nous allons donc utiliser cette partie/section de l'ontologie AV :
 
av:Organization a owl:Class ;
        rdfs:subClassOf foaf:Organization ;
        rdfs:subClassOf av:Actor ;
        rdfs:label "Organisation"@fr .
 
 
Traduction en français :
Nous déclarons que "av:Organization" est une classe qui est : 
  • une sous-classe de l'ontologie "foaf:Organization" (voir FOAF dans les références plus haut...)
  • une sous-classe de av:actor (définit au début du fichier)
  • qu'elle a pour "label" en français : "Organisation".
 
Ce qui donnera donc un premier triplet RDF comme ceci : 
<Assemblée_Virtuelle> a av:organization .
 
Analyse de l'objet <Carto_PAIR>
Il faut aussi préciser que "Carto PAIR" est un projet.
 
Pour cela, nous allons nous orienter vers une autre "partie"/"section" de l'ontologie AV, concernant les projets.
Ca tombe bien, il y a un fichier pour cela ! :)
On y explique ce que peut être un projet au sens de l'ontologie AV.
 
Notre triplet se résumera donc à : 
<Carto_PAIR> a av:project .
 
Analyse du prédicat "contribue à"
Enfin, nous allons rechercher un "vocabulaire", ou plutôt une "propriété" qui correspond à l'expression "contribue à".
 
Retournons dans le fichier des acteurs : https://github.com/assemblee-virtuelle/pair/blob/master/actor.ttl
 
(extrait)
av:contributes a owl:ObjectProperty ;
rdfs:label "contribue"@fr ;
rdfs:domain av:Actor ;
rdfs:range foaf:Project .
 
Traduction en français : 
Ce bout de turtle signifie que l'on déclare que "av:contributes" est une propriété (héritée de OWL) qui a pour label "contribue", et correspond à un prédicat dont la source (domain) part d'un acteur et va vers une destination (range) qui est un projet.
 
Parfait !  C'est ce qu'il nous faut pour notre exemple (c'est bien foutu quand même... ;-) )
 
Notre triplet RDF ressemblera donc à quelque chose comme cela : 
  • En français :               un acteur           contribue à                     un projet
  • En équivalent RDF : av:actor             av:contributes                av:project
 

Représentation Turtle

 
En compilant les 3 analyses ci-dessus, nous arrivons à la description suivante en turtle : 
 
<Assemblée_Virtuelle> a av:Organization .
<Carto_PAIR> a av:Project .
<Assemblée_Virtuelle> av:contributes <Carto_PAIR> .
<Carto_PAIR> av:project <Assemblée_Virtuelles> .
 
Remarque importante concernant les <URI>
Dans notre exemple ci-dessus en turtle, faut comprendre que : 
<Assemblée_Virtuelle> et <Carto_PAIR> représentent juste des URI.
Ils ne signifieront donc rien pour un humain. Nul part nous n'indiquons de libellé à ces URI.
 
En effet, cette première sémantisation ne définit donc pas que le sujet que nous souhaitons exprimer a pour libellé "Assemblée Virtuelle", ni que l'objet que nous souhaitons exprimer a pour libellé "Carto PAIR".
Mais seulement qu'il y a un "truc" qui est une organisation et un autre "truc" qui est un projet...
 
Et c'est déjà une bonne chose ! Nous verrons par la suite comment nous ajouterons ces "détails" pour que ces "concepts" s'affichent bien dans l'interface de la carto PAIR et soient "lisibles" par un humain.
 

Représentation N-triple

 
La syntaxe N-Triple est le plus simple à comprendre, car il affiche juste les triplets les uns en dessous des autres, mais vu qu'il n'y a aucun préfixe, la lisibilité n'est pas top...
 
Par exemple, nous allons remplacer <Assemblée_Virtuelle> par une uri de notre choix. Cette URi dépendra du serveur qui stockera les triplets RDF.
 
Ensuite, le petit mot "a" signifie en français "est de type...". C'est (comme dirait Jean-Marc) du sucre syntaxique pour simplifier l'écriture et la lecture.
Ce qui correspond à une propriété très utilisée : "rdf:type" 
 
Le premier triplet : 
<Assemblée_Virtuelle> a av:Organization .
est donc équivalent en N-Triple à : 
 
(Je vous laisse faire le reste vous même !)
 
 

Représentation JSON-D3

 
Lorsque nous allons vouloir afficher cette information dans une cartographie, nous allons devoir travailler la structure de cette information en Javascript, nous allons utiliser des objets (équivalents à du JSON).
Pour afficher des bulles et des liens, la librairie D3js attend en entrée un format spécial contenant : 
  • Un tableau de nœuds
  • Un tableau de liens
  • Le tout dans une enveloppe JSON.
 
Pour afficher une bulle "Assemblée Virtuelle", un lien "contribue à" lié à une autre bulle "Carto PAIR", nous devons donc générer 3 objets Javascript : 
  • un objet correspondant au noeud "Assemblée Virtuelle"
  • un objet correspondant au noeud "Carto PAIR"
  • un objet correspondant au lien "Contribue à"
 
Objet JS : "Assemblée virtuelle"
{"id" : "0", "type" : "actor", "label" : "Assemblée virtuelle", "identifier" : "http://fluidlog.com/node/0"}
 
Objet JS : "Carto PAIR"
{"id" : "1", "type" : "projet", "label" : "Carto PAIR", "identifier" : "http://fluidlog.com/node/1"}
 
Objet JS : "Contribue à"
{"id" : "0", "source" : "0", "target" : "1", "type" : "av:contributes"}
 
Ensuite, on met tout ça dans une enveloppe JSON avec un tableau de nœuds et un tableau de liens et nous obtenons le format JSON-D3 attendu.
 
JSON-D3 final (compatible dans du code JS)
 
var jsonD3 = {
"nodes" : [
{"index" : "0", "type" : "actor", "label" : "Assemblée virtuelle", "identifier" : "http://fluidlog.com/node/0"},
{"index" : "1", "type" : "projet", "label" : "Carto PAIR", "identifier" : "http://fluidlog.com/node/1"}
],
"edges" : [
{"index" : "0", "source" : "0", "target" : "1", "type" : "av:contributes"}
]
}
 
Vous pouvez d'ailleurs tester ce code dans la console de votre navigateur pour vérifier droite) que l'objet JS contient bien ce que vous attendez.
 
 
Mais nous voyons bien que cet objet JS n'est pas très "sémantique"... il lui manque des choses avant de pouvoir être envoyé à un serveur de triplet. Pour compenser cela, le W3C a ajouté une nouvelle spécification permettant de créer une syntaxe JSON pour le web sémantique au même titre qu'il existe une syntaxe XML/RDF pour le monde du XML.
 
Toute la difficulté sera donc de passer de données sémantisées à un JSON interprétable par D3js et inversement.
 
 

Représentation JSON-LD

 
Partons du site http:/json-ld.org  pour analyser son exemple.
 
Analyse de l'exemple "John Lennon"
Nous allons donc d'abord observer l'exemple de base donné sur le site.
 
{
  "name": "John Lennon",
  "born": "1940-10-09",
}
 
On voit ici 3 triplets décrivant une ressource (ici John Lennon) 
 
@id
Vous remarquerez que la ressource que l'on va définir est identifiée par une URi et une clé "@id".
@context
Une autre spécificité de JSON-LD est de définir un @context, permettant de créer des alias vers des URi des vocabulaires / ontologies que l'on va utiliser. Cela simplifie la lecture du JSON-LD.
Cet exemple utilise l'ontologie liées aux "personnes".
C'est à dire que "name", "born", "spouse" sont des propriétés définies dans ce context, et grâce à cela, nous ne sommes plus obligé de toujours ajouter le préfixe, une fois qu'il a été défini dans le contexte.
Remarque : vous pouvez tout à fait cliquer sur http://json-ld.org/contexts/person.jsonld et télécharger la définition de ce contexte.
On y trouve par exemple la clé : "born", qui fait référence à l'ontologie "schema.org" et plus particulièrement à la propriété : http://schema.org/birthDate
 
Une explication en français de ce JSON-LD serait : 
  • Le concept "a pour nom" : "John Lennon"
  • Le concept "est né le " : "09/10/1940"
  • Le concept "a pour épouse" : un autre concept...
 
(ce que nous appelons ici "concept" est représenté par une URi stocké sur dbpedia, qui est une base sémantisé d'un contenu de wikipedia).
 
Adaptation de notre exemple de base en JSON-LD
 
Pour faciliter la transformation en syntaxe JSON-LD, nous allons utiliser le "playground" en ligne : http://json-ld.org/playground/
Donc  à chaque fois que nous souhaiterons vérifier si notre JSON-LD est  correcte, nous n'aurons qu'à le copier/coller dans le playground et voir  s'il affiche des erreurs.
 
Essayons  déjà de représenter un seul noeud, ce qui sera déjà une bonne étape,  qui servira de point de départ, pouvant être testé. Ensuite, nous  ajouterons progressivement un deuxième noeud et le lien.
 
Triplet 1 : l'assemblée virtuelle est  une organisation
 
 
@id
Dans notre cas, l'@id n'est (a priori) pas obligé, mais surtout, il est dépendant des serveurs de triplets que l'on utilisera. Certains génèrent eux même les id, d'autres pas, mais nous sommes en train de creuser ça avec Jean-Marc et Sylvain.
 
@context
 
"@context" : {
}
 
Grâce à ce contexte, lorsque nous préciserons dans le JSON-LD : 
"av:organization", cela pointera directement sur la description hébergée sur "http://www.assemblee-virtuelle.org/ontologies/v1.owl#Organization"
 
Ce qui donnera un JSON-LD comme celui-ci :
 
{
  "@context":{
  },
  "rdf:type" : "av:Organization"
}
 
Ce JSON-LD semble être accepté sur http://json-ld.org/playground/
 
On peut aussi l'écrire :
 
{
  "@context":{
  },
  "type" : "av:Organization"
}
 
Voir même encore plus simplement, car le type est tellement souvent utilisé, que la norme JSON-LD a mis en place un @type, pour répondre au besoin.
 
{
  "@context":{
  },
  "@type" : "av:Organization"
}
 
Autre remarque importante (que je viens de comprendre...)
 
Le JSON-LD suivant n'est pas bon (au sens sémantique)
 
{
  "@context":{
  },
  "type" : "organization"
}
 
Ne veut pas dire la même chose, voir ne veut rien dire du tout, car il est équivalent à : 
Or, le texte "organization" ne signifie rien contrairement à "av:Organization", qui lui est défini à l'URI : http://www.assemblee-virtuelle.org/ontologies/v1.owl#Organisation
 
Le N-Triple que nous attendons est : 
 
 

Schéma de synthèse

 
 
 
Voir aussi +Web distribué avec LDP 
 
Il existe plusieurs sous-formats de représentation du JSON-LD.
 

Différents formats de JSON-LD

 
JSON-LD expended
 
[
  {
      {
        "@value": "av:Organization"
      }
    ]
  }
]
 
JSON-LD compacted
 
{
}
 
JSON-LD flattened
 
{
  "@graph": [
    {
      "http://www.w3.org/1999/02/22-rdf-syntax-ns#type ": "av:Organization"
    }
  ]
}
 
JSON-LD framed
 
{
  "@graph": [
    {
      "http://www.w3.org/1999/02/22-rdf-syntax-ns#type ": "av:Organization"
    }
  ]
}
 
Tous ces formats sont acceptés par la norme JSON-LD, il faudra juste s'assurer dans les librairies JS qui sérialisent le JSON-LD que tous ces formats (ou au moins celui qu'on utilise) sont prévus.
 

JSON-LD de "AV contribue au projet Carto PAIR"

 
Maintenant que nous avons sémantisé en JSON-LD un triplet, complexifions un peu.
 
Pour rappel, l'objectif est de stocker l'équivalent sémantique du fichier turtle suivant : 
 
<Assemblée_Virtuelle> a av:Organization .
<Carto_PAIR> a av:Project .
<Assemblée_Virtuelle> av:contributes <Carto_PAIR> .
<Carto_PAIR> av:projet <Assemblée_Virtuelles> .
 
Ici, <Carto_PAIR> est une nouvelle ressource. Le JSON-LD final sera donc constitué de deux partie : 
 - une définissant la ressource <Assemblée_Virtuelle>, soit : 
  
<Assemblée_Virtuelle> a av:Organization .
<Assemblée_Virtuelle> av:contributes <Carto_PAIR> .
 
- une autre définissant la ressource <Carto_PAIR>
<Carto_PAIR> a av:Project .
<Carto_PAIR> av:projet <Assemblée_Virtuelles> .
 
Pour terminer la sémantisation de la ressource AV,
 
Continuons avec la phrase "AV contribue à Carto PAIR"
 
{
  "@context":{
  },
}
 
Ce qui donnera un premier JSON-LD : 
 
{
  "@context":{
  },
  "@type" : "av:Organization"
}
 
Ensuite, la deuxième partie avec la phrase "Carto PAIR est un projet"
Ce qui donnera en JSON-LD : 
 
{
  "@context":{
  },
  "@type" : "av:Project"
}
 
Enfin, la phrase "Carto PAIR est un projet de l'AV"
 
{
  "@context":{
  },
}
 
Ce qui donne au final, un deuxième JSON-LD :
 
{
  "@context":{
  },
  "@type" : "av:Project",
}
 

JSON-LD final

 
 
[{
  "@context":{
  },
  "@type" : "av:Project",
},
{
  "@context":{
  },
  "@type" : "av:Organization",
}]
 
Pour apprendre à stocker ces informations dans un serveur de triplet en LDP, voir : 
 
Problème : Le problème principal est le fait que les ID sont / ou non, créé par le serveur LDP.
En effet, dans le cas ci-dessus, le stockage de "AV contribue au projet Carto PAIR" est dépendant du stockage de "Carto PAIR est un projet"...
 
Nous souhaiterions sauvegarder un graphe entier et non des ressources unitaires..
En effet, dans un premier temps, nous souhaitons stocker plusieurs graphs sur un container LDP.
Dans un second temps, nous réfléchierons à stocker une carto (un graph) de manière distribué sur plusieurs serveurs LDP.
 
Pour cela, voir :  +Web distribu avec LDP