Exploiter RDF avec Jena
Transcript of Exploiter RDF avec Jena
O.Curé [255 ]
Exploiter RDF avec Jena
5
O.Curé [256 ]
JENA : Présentation
● Plateforme Java pour le Web sémantique
● Open-source● Développé par un laboratoire de
Hewlett-Packard
O.Curé [257 ]
JENA : URL
● La page d'accueil de JENA :– http://jena.sourceforge.net/downloads.html
● Un groupe de discussions :– http://groups.yahoo.com/group/jena-dev/
● La javaDoc– http://jena.sourceforge.net/javadoc/index.html
O.Curé [258 ]
JENA : éléments
● Un analyseur RDF : ARP – Another RDF Parser
● un langage de requêtes pour RDF : RDQL – RDF Query Language
● Persistence des données, en particulier avec les SGBD (Oracle, MySQL, PostgreSQL)
● Support de RDF, RDFS, OWL● Inférence
O.Curé [259 ]
Modèle
● L'architecture de JENA est centrée sur la notion de modèle (model) : l'ensemble des déclarations qui composent un document, graphe ou instanciation d'un vocabulaire.
● A partir de JENA2.0, on doit créer un modèle en s'aidant de ModelFactory.
O.Curé [260 ]
ModelFactory : code
import java.util.Iterator;import com.hp.hpl.jena.rdf.model.*;public class EtudRDF { private String etudNS ="file:/home/olive/_mesCours/
kr/etudIns2.rdf"; public static void main(String[] args) {
EtudRDF etudRDF= new EtudRDF();
etudRDF.load();
}public void load() {
Model model = ModelFactory.createDefaultModel();
model.read(etudNS);
model.write(System.out);
}}
O.Curé [261 ]
Création / Enrichissement d'un modèle (1)
model = ModelFactory.createDefaultModel();jean = model.createResource(familleURI+"jean");marie = model.createResource(familleURI+"marie");dominique = model.createResource(familleURI+"dominique");alexandra = model.createResource(familleURI+"alexandra");baptiste = model.createResource(familleURI+"baptiste");pierre = model.createResource(familleURI+"pierre");
enfantDe = model.createProperty(relationshipURI,"childOf");parentDe = model.createProperty(relationshipURI,"parentOf");epouseDe = model.createProperty(relationshipURI,"spouseOf");
dominique.addProperty(parentDe, baptiste);dominique.addProperty(parentDe, pierre);alexandra.addProperty(parentDe, baptiste);alexandra.addProperty(parentDe,pierre);alexandra.addProperty(epouseDe, dominique);
O.Curé [262 ]
Création / Enrichissement d'un modèle (2)
Statement statement = model.createStatement(dominique, enfantDe, jean);
model.add(statement);statement = model.createStatement(dominique, enfantDe,
marie);model.add(statement);
Property prop = model.createProperty(relationshipURI,"knowsOf");
//Création d'un noeud vide Resource blank = model.createResource( ) .addProperty(prop, "personne1") .addProperty(prop, "personne2") .addProperty(prop, model.createLiteral("personne3", "fr")); // Affichage du document RDF au format RDF/XML (par défaut) model.write(new PrintWriter(System.out));
O.Curé [263 ]
Accès aux données
● On peut accéder aux données :– à l'aide de programmes en s'appuyant sur
les méthodes et classes de l'API– À l'aide de langage de requêtes RDQL.
O.Curé [264 ]
Via les données : code
// Ensemble des déclarations
StmtIterator iter = model.listStatements();
while (iter.hasNext()) {
Statement stmt = (Statement) iter.next();
System.out.println(stmt.getSubject()+"("+stmt.getPredicate()+")>"+stmt.getObject().toString());
}
O.Curé [265 ]
Via les données : code (2)// Connaitre les parentsResIterator parents =
model.listSubjectsWithProperty(parentDe);while (parents.hasNext()) {personne = parents.nextResource();System.out.println(personne.getLocalName()+ " > URI
="+personne.getURI());}// Encore des parents avec enfantDeNodeIterator parentsSuite =
model.listObjectsOfProperty(enfantDe);while (parentsSuite.hasNext()) {Resource person = (Resource) parentsSuite.nextNode();System.out.println( person.getLocalName()+ " > URI
="+person.getURI());}
O.Curé [266 ]
Via les données : code (3)System.out.println("Les ens :");NodeIterator itNode = model.listObjectsOfProperty(estEns);
while (itNode.hasNext()) {RDFNode node = (RDFNode) itNode.next();System.out.println("Enseignant ="+node.toString());
// on veut le nomProperty nom = model.createProperty("http://www.univmlv.fr/~ocure/etudSchema.rdf#possedeNom");
NodeIterator itNom = model.listObjectsOfProperty((Resource)node,nom);
while (itNom.hasNext()) {System.out.println("Nom = "+itNom.next());}}
O.Curé [267 ]
Exercice 1
● A partir du fichier RDF sur les cours, enseignants et etudiants :– Afficher la liste des cours– Afficher les enseignants, dans un premier
temps le nom local des enseignants puis la valeur de l'attribut possedeNom de chaque enseignant.
O.Curé [268 ]
RDQL : présentation● Syntaxe proche de SQL.
● Influence : SquishQL, RDFDB QL
● Les clauses sont : SELECT, WHERE, USING
● Les variables débutent par un “?”.
● Orienté données : les données explicites du modèle (pas implicites).
● Jena Tutorial : “RDF provides a graph with directed edges - the nodes are resources or literals. RDQL provides a way of specifying a graph pattern that is matched against the graph to yield a set of matches. It returns a list of bindings - each binding is a set of name-value pairs for the values of the variables. All variables are bound (there is no disjunction in the query).”
O.Curé [269 ]
RDQL : le langage (1)● BNF de RDQL à la page :
http://jena.sourceforge.net/tutorial/RDQL/rdql_grammar.html
● Exemple : SELECT * WHERE (?s,?p,?o)
● (s, 129d96a8:10160ffc9cc:8000) (p, http://purl.org/vocab/relationship#knowsOf) (o, personne2)
● (s, 129d96a8:10160ffc9cc:8000) (p, http://purl.org/vocab/relationship#knowsOf) (o, personne3~fr)
● (s, http://www.univmlv.fr/~ocure/rdf/famille#alexandra) (p, http://purl.org/vocab/relationship#parentOf) (o, http://www.univmlv.fr/~ocure/rdf/famille#pierre)
● (s, http://www.univmlv.fr/~ocure/rdf/famille#alexandra) (p, http://purl.org/vocab/relationship#parentOf) (o, http://www.univmlv.fr/~ocure/rdf/famille#baptiste)
● (s, http://www.univmlv.fr/~ocure/rdf/famille#dominique) (p, http://purl.org/vocab/relationship#parentOf) (o, http://www.univmlv.fr/~ocure/rdf/famille#pierre)
● (s, http://www.univmlv.fr/~ocure/rdf/famille#dominique) (p, http://purl.org/vocab/relationship#parentOf) (o, http://www.univmlv.fr/~ocure/rdf/famille#baptiste)
● ...
O.Curé [270 ]
RDQL : le langage (2)
● SELECT * WHERE (?s,<rel:parentOf>,?o) USING rel FOR <http://purl.org/vocab/relationship#>
● SELECT ?s WHERE (?s,<rel:parentOf>,?o) USING rel FOR <http://purl.org/vocab/relationship#>
● Résultats :
alexandra parent de pierre
alexandra parent de baptiste
dominique parent de pierre
dominique parent de baptiste
O.Curé [271 ]
RDQL : le langage (3)
● "SELECT ?o, ?o2 WHERE (?s,<rel:childOf>,?o), (?s,<rel:parentOf>,?o2) USING rel FOR rel FOR <http://purl.org/vocab/relationship#>
● Résultats :
marie parent de pierre
marie parent de baptiste
jean parent de pierre
jean parent de baptiste
O.Curé [272 ]
RDQL : filtre
● On peut filtrer les valeurs des variables à l'aide de la clause AND.
● Exemple : AND ?age > 18
● On apeut aussi profiter des expressions régulières (“=~” egalité et “!~” différence).
● Exemple :
● SELECT * WHERE (?s,<rel:parentOf>,?o) AND ?s =~ /dominique/i USING rel FOR <http://purl.org/vocab/relationship#>
dominique parent de pierre
dominique parent de baptiste
Insensible à la casse
O.Curé [273 ]
RDQL :programmation Java
● Mode de fonctionnement :
– On passe la requête à un objet instancié de la classe Query.
– On passe alors l'objet à un objet du type QueryEngine.
– Les résultats se trouvent dans un objet du type QueryResults
– On accède aux résultats via la classe ResultBinding
Query qr1 = new Query("SELECT * WHERE (?s,?p,?o)");
qr1.setSource(model);QueryEngine qe = new
QueryEngine(qr1);QueryResults results = qe.exec();for(it=results; it.hasNext();) {
ResultBinding res = (ResultBinding)it.next() ;
String x = (res.get("s").toString());
String y = res.get("o").toString();
System.out.println(x.substring(x.indexOf('#')+1) +" parent de "+y.substring(y.indexOf('#')+1));
}
O.Curé [274 ]
Exercice 2
● Toujours le fichier RDF de l'exercice 1, rédiger les requêtes RDQL suivantes :– Afficher les cours– Afficher les étudiants– Afficher les enseignants– Afficher l'enseignant du Cours1
O.Curé [275 ]
Opérations sur les modèles
● On peut réaliser les opérations ensemblistes suivantes sur les modèles : union, intersection et différence.
● Exemple pour l'unionModel modelI = ModelFactory.createDefaultModel();modelI.read(instNS);Model modelS = ModelFactory.createDefaultModel();modelS.read(schemaNS);Model model = modelS.union(modelI);model.write(System.out);● Idem pour intersection et difference
O.Curé [276 ]
Inférence
● Jena propose de nombreuses fonctionnalités pour réaliser des inférences.
● Lire le document “Inference engine user manual” accessible depuis la page Documentation du site de Jena.
O.Curé [277 ]
Exercice 3
● Sur le fichier RDFS (schemaEtud.rdf) afficher toutes les sous-classes de la classe Personne
● Rédiger une classe “Thesard”, sous-classe de la classe “Etudiant”.
● Demander à nouveau les sous-classes de la classe Personne.
O.Curé [278 ]
Exercice 4
● Réaliser l'union du modèle du schéma RDF et du modèle des instances RDF.
● Ecrire le code permettant d'obtenir les instances de la classe Etudiant puis Enseignant.
● Ecrire un modèle permettant l'inférence et écrire le code permettant d'obtenir les instances de la classe Personne.
O.Curé [279 ]
SPARQL
O.Curé [280 ]
Introduction
● Query language for RDF data● Basic graph pattern matching● Result forms:
– SELECT, CONSTRUCT, DESCRIBE, ASK
● with filters to restrict values● Solution modifiers:
– ORDER BY, LIMIT/OFFSET, DISTINCT, REDUCED
O.Curé [281 ]
Patterns
● Variables are prefixed with a '?'● Patterns use triple forms● Example:
SELECT ?s ?p ?o
WHERE {?s ?p ?o}
● A pattern is a conjunction of triples:
{?x rdf:type ex:Person.
?x ex:nom ?name}
O.Curé [282 ]
Example
@prefix person: <http://example/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
person:A foaf:name "Alice" .
person:A foaf:mbox <mailto:[email protected]> .
person:B foaf:name "Bob" .
PREFIX person: <http://example/person/>PREFIX foaf: <http://xmlns.com/foaf/0.1/>SELECT ?nameWHERE { ?x foaf:name ?name }
name "Bob" "Alice"
O.Curé [283 ]
Example (2)
@prefix person: <http://example/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
person:A foaf:name "Alice" .
person:A foaf:mbox <mailto:[email protected]> .
person:B foaf:name "Bob" .
PREFIX person: <http://example/person/>PREFIX foaf: <http://xmlns.com/foaf/0.1/>SELECT ?nameWHERE { ?person foaf:mbox
<mailto:[email protected]> .?person foaf:name ?name . }
name "Alice"
O.Curé [284 ]
Example (3a)@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix stock: <http://example.org/stock#> .
@prefix inv: <http://example.org/inventory#> .
stock:book1 dc:title "SPARQL Query Language Tutorial" .
stock:book1 inv:price 10 .
stock:book1 inv:quantity 3 .
stock:book2 dc:title "SPARQL Query Language (2nd ed)" .
stock:book2 inv:price 20 ; inv:quantity 5 .
stock:book3 dc:title "Moving from SQL to SPARQL" .
stock:book3 inv:price 5 ; inv:quantity 0 .
stock:book4 dc:title "Applying XQuery" .
stock:book4 inv:price 20 ; inv:quantity 8 .
O.Curé [285 ]
Example (3b)
PREFIX dc: <http://purl.org/dc/elements/1.1/>PREFIX stock: <http://example.org/stock#>PREFIX inv: <http://example.org/inventory#>SELECT ?book ?titleWHERE { ?book dc:title ?title . ?book inv:price ?price . FILTER ( ?price < 15 ) ?book inv:quantity ?num . FILTER ( ?num > 0 ) }
book | title stock:book1 | "SPARQL Query Language Tutorial"
O.Curé [286 ]
Example (4)
PREFIX foaf: <http://xmlns.com/foaf/0.1/>SELECT ?name ?nick{ ?x foaf:name ?name . OPTIONAL {?x foaf:nick ?nick } }
name | nick "Alice" | "Aonline" "Bob |
@prefix person: <htp://example/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
person :a foaf:name "Alice" .
person :a foaf:nick "A-online" .
person:b foaf:name "Bob" .
t
O.Curé [287 ]
OWLWeb Ontology Language
6
O.Curé [288 ]
OWL
● Une recommendation du W3C pour représenter des ontologies pour le Web Sémantique.
● Influences : RDF, DL et les frames
● OWL est un langage pour structurer l'information dans des ontologies : définir les concepts d'un domaine et les relations liant ces concepts.
● OWL permet également de définir les instances.
O.Curé [289 ]
OWL
● OWL possède 3 sous-langages : OWL Lite, OWL DL and OWL Full
● OWL propose plusieurs syntaxes : RDF, OWL/RDF, abstract syntax.
● Termes utilisés avec OWL :
– Concepts = classes
– Rôles = propriétés
O.Curé [290 ]
Influences de OWL
O.Curé [291 ]
OWL comme une DL
O.Curé [292 ]
Syntaxe
● OWL/RDF syntax
<owl:Class rdf:ID="Cat"><rdfs:subClassOf rdf:resource="#Animal"/>
</owl:Class>
● Abstract syntax
Class (a:Cat partial a:Animal)
O.Curé [293 ]
OWL Lite
● OWL Lite ressemble aux Frames : supporte la classification hiérarchique des classes et propriétés, des contraintes simples
● OWL Lite possède moins de constructeurs que OWL DL
– Descriptions dans des descriptions
– Unions, OneOf, etc..● OWL Lite correspond à DL SHIN(Dn)
– Qui est décidable
– Avec des implémentations efficaces.
O.Curé [294 ]
OWL DL
● Expressivité riche en gardant la complétude computationelle et la décidabilité.
● Ne permet pas toute la liberté syntaxique de RDF :– Ex : une classe ne peut être une propriété
ou une instance, une propriété ne peut être une classe ou une instance.
● Correspondence avec la DL SHOIN(D)
O.Curé [295 ]
OWL DL (2)
● 40 primitives : 16 pour les classes et 24 pour les propriétés.
● Classes pour définir des classes et des restrictions :– owl:Class = spécialisation de rdfs:Class– owl:Restriction = spécialisation de
owl:Class pour définir des restrictions sur des classes (existencielle, universelle, “number restrictions”), etc.).
O.Curé [296 ]
Eléments du langage
● Classes pour définir des propriétés :– owl:ObjectProperty, owl:DatatypeProperty,
owl:TransitiveProperty, owl:SymmetricProperty, owl:FunctionalProperty, owl:InverseFunctionalProperty (une sous classe de ObjectProperty pour OWL Lite et DL, également une sous-classe de datatype Property pour OWL Full) sont des spécialisations de rdf:Property
O.Curé [297 ]
Eléments du langage (2)
● Classes pour déclarer l'inégalité entre individus :– owl:AllDifferent pour spécifier que des
individus sont différents. – Nécessaire car OWL ne suppose pas UNA– Donc 2 définitions d'individus avec des
identifiants différents peuvent correspondre au même individu.
O.Curé [298 ]
Eléments du langage (3)
● Classes pour l'énumération de types de données :
– owl:DataRange pour énumérer des données avec des valeurs prédéfinies.
● Classes prédéfinies : owl:Thing et owl:Nothing
● Classes pour la description d'ontologie : owl:Ontology
● Version des ontologies : owl:DeprecatedClass, owl:DeprecatedProperty
O.Curé [299 ]
Eléments du langage (4)
● Propriétés pour définir des classes dans OWL Lite :
– owl:intersectionOf : le codomaine est restreint aux identifiants de classes et restrictions sur les propriétés.
– Restriction :● owl:AllValuesFrom● owl:SomeValuesFrom● owl:cardinality, owl:minCardinality,
owl:maxCardinality avec des valeurs de 0 ou 1.
O.Curé [300 ]
Eléments du langage (6)
● Propriétés pour définir des classes dans OWL DL:
– owl:intersectionOf, owl:unionOf, owl:complementOf (négation) sont sans restriction sur le codomaine.
– owl:OneOf pour définir des collections d'individus
● Restrictions :
– Entier naturel pour les cardinalités
– owl:hasValue
O.Curé [301 ]
Eléments du langage (7)
● Pour OWL Lite :– owl:inverseOf pour définir l'inverse d'une
propriété– owl:sameAs, owl:equivalentClass,
owl:equivalentProperty, owl:sameIndividualAs pour définir des équivalences entre des ressources, des classes, des propriétés et des individus.
– owl:differentFrom pour définir que 2 individus sont différents
O.Curé [302 ]
Eléments du langage (8)
● Pour OWL Lite :– owl:distinctMembers. A utiliser avec
owl:AllDifferent pour définir une liste d'instances où les éléments sont différents les uns des autres.
● Pour OWL DL :– owl:disjointWith pour définir que des
classes sont disjointes.
O.Curé [303 ]
O.Curé [304 ]
OWL Full
● Très expressif (méta-classes, classes comme valeur d'object property).
● Profite de toute la liberté syntaxique de RDF– Une classe peut être traitée comme un
ensemble d'individus et comme une classe.
● Pas d'algo efficace pour le raisonnement.
O.Curé [305 ]
Defining n-ary relations
● Problem: how to represent n-ary relations in RDF/OWL
● 2 different patterns :– introduce a new class for a relation– using lists of arguments in a relation.
O.Curé [306 ]
New class for a relation
● For example :
O.Curé [307 ]
New class for a relation
● This approach is useful in the case of – additional attributes describing a relation– different aspects of the same relation– n -ary relation with no distinguished
participants, e.g. someone buys in a particular book, in a shop, at a given price for a specific purpose.
O.Curé [308 ]
Lists for arguments of a relation
● Caution : using the rdf:List vocabulary in OWL would have put the ontology in OWL Full.
O.Curé [309 ]
Lists for arguments of a relation (2)
● The following ontology is in OWL Lite:
O.Curé [310 ]
Outils pour concevoir des ontologies
● Open-source :– KAON , OilEd, OntoEdit, Ontolingua,
OntoSaurus, Protégé, WebODE, WebOnto
O.Curé [311 ]
Protégé
O.Curé [312 ]
Introduction
● Un éditeur d'ontologies et de bases de connaissances
● Open-source● Disponible à l'URL :
http://www-protege.stanford.edu/● Développé à l'Université de Stanford en
Java● Supporte de nombreux plug-ins.
O.Curé [313 ]
Historique● Début des années 90 : Protégé II
– Environnement pour l'ingénierie des connaissances permettant de définir des modèles et de générer des GUI. Version pour NeXTSTEP.
● Milieu des 90s : ProtégéWin
– Version pour Windows● Fin des 90s : Protégé2000
– Version Java, Open-source
– Développement de plug-ins● 2003 : Protégé (à partir de la version 2.0)
– Support de OWL.
O.Curé [314 ]
Plateforme pour plug-ins
● Communauté très active. On trouve des plug-ins pour :– La visualisation– L'inférence– Import et export de formats (XML, RDF,
DAML+OIL, OWL, CLIPS, Topic Maps).– Conception d'IHM– etc..
O.Curé [315 ]
Notre environnement
● Le plug-in OWL– Une extension de Protégé pour permettre :
le chargement, l'enregistrement de fichiers OWL, l'édition graphique d'expressions OWL, l'accès à des fonctionnalités liées à l'inférence (classifier)
● Racer
O.Curé [316 ]
Démonstration
● Créer des classes, des propriétés, des instances
● Lancer la classification avec Racer.● Ecrire et exécuter des requêtes en
RDQL.● Visualisation de graphes
O.Curé [317 ]
Exercice
● Ecrire la terminologie complète de l'ontologie Personne :
O.Curé [318 ]
Exercice 1● Ecrire un programme Java qui va afficher les déclarations
de la base de connaissances (Personne)
● Ecrire une nouvelle méthode qui va permettre d'afficher les sous-classes de la classe Man.
● Ecrire une méthode qui va permettre d'afficher toutes les instances de la Abox.
● En vous aidant des tutoriaux sur les inférences avec Jena (que vous devriez déjà avoir étudié) et « using a DIG reasoner with Jena » (DIG = Description Logic Implementation Group), intégrez le raisonneur Racer dans le programme et chargez notre base de connaissances.
O.Curé [319 ]
Exercice 1 (2)
● Afficher les instances qui sont des hommes (« Man »).
● Afficher les instances qui sont des oncles (« uncle »). Le graphe des instances (générée avec Rice) se trouve à l'adresse : www.univ-mlv.fr/~ocure/Ex1PersonDLInst.png). Les données sur les oncles ne sont pas explicites. Regarder le code OWL pour comprendre l'inférence : définition de la classe « Uncle », des classes associées et des instances impliquées.
● Définir à l'aide de manière programmatique en Java la classe suivante « HappyFather » définie comme un père ayant au moins un garçon et une fille.
O.Curé [320 ]
Exercice 1 (fin)
● Modifier la classe « HappyFather » et ajouter une contrainte supplémentaire : n'a qu'un seul enfant. La base de connaissances contient maintenant une classe inconsistante. A l'aide du tutoriel, programmer l'afficher des classes inconsistances.