Übungen: Wissensrepräsentation
Übungen zu EKI04: Wissensgraphen und ihre Bausteine, RDF-Tripel in Turtle-Notation (
;,,,a), URIs undPREFIX, sowie SPARQL-Queries lesen und schreiben (SELECT, Bedingungen, Joins über gemeinsame Variablen, DISTINCT). Alle Aufgaben basieren ausschliesslich auf dem Kapitelinhalt und dem TMDB-Wissensgraphen.
Beginner
Aufgabe 1 (Beginner) - Aufbau eines RDF-Tripels
Aus welchen drei Teilen besteht ein RDF-Tripel, und was kann jeder Teil sein?
a) Klasse - Instanz - Wert b) Subjekt - Prädikat - Objekt c) Knoten - Kante - Knoten d) PREFIX - SELECT - WHERE
Lösung anzeigen
Richtig ist b) Subjekt - Prädikat - Objekt.
| Teil | Was es sein kann |
|---|---|
| Subjekt | eine Resource |
| Prädikat | eine (weitere) Resource |
| Objekt | eine Resource oder ein Wert (string, int, float, date, ...) |
Ein Punkt . beendet das Tripel. Beispiel:
:Movie_453 :title "A Beautiful Mind" .
Hier ist :Movie_453 das Subjekt (Resource), :title das Prädikat (Resource) und "A Beautiful Mind" das Objekt (ein String-Wert / Literal).
- c) beschreibt eher die grafische Darstellung (Knoten - beschriftete Kante - Knoten), nicht die formale Tripel-Struktur.
- d) sind SPARQL-Schlüsselwörter, keine Tripel-Teile.
Siehe EKI04.
Aufgabe 2 (Beginner) - Objekte, Klassen und Beziehungen
Gegeben ist der Satz:
"A Beautiful Mind" ist ein Film, gedreht von dem Regisseur Ron Howard und gehört zu dem Genre Drama.
Ordne die folgenden Begriffe den drei Bausteinen von Wissen zu (Objekte/Instanzen, Klassen, Beziehungen): "A Beautiful Mind", Film, "gedreht von", Ron Howard, Genre, "ist ein", Drama, Regisseur, "gehört zu".
Lösung anzeigen
| Baustein | Zugeordnete Begriffe |
|---|---|
| Objekte / Instanzen (konkrete Individuen) | "A Beautiful Mind", Ron Howard, Drama |
| Klassen (Typen/Kategorien) | Film, Regisseur, Genre |
| Beziehungen (relations) | "ist ein", "gedreht von", "gehört zu" |
Tipp: Klassen sind allgemeine Typen (jeder Film ist ein "Film"), Instanzen sind konkrete Einzelfälle ("A Beautiful Mind" ist EIN bestimmter Film). Beziehungen verbinden diese Knoten und werden im Graphen zu benannten Kanten (Prädikaten).
Siehe EKI04.
Aufgabe 3 (Beginner) - Das Kürzel a in Turtle
Was bedeutet das a in der folgenden Turtle-Zeile?
:Movie_453 a :Movie .
a) Es ist ein Tippfehler und sollte ignoriert werden.
b) Es ist die Abkürzung für rdf:type und drückt die Instanz-Beziehung ("ist ein") aus.
c) Es steht für "attribute" und leitet ein Datentyp-Attribut ein.
d) Es markiert den Anfang eines neuen Tripels.
Lösung anzeigen
Richtig ist b).
Das a ist die Abkürzung für rdf:type und drückt die Instanz-Beziehung ("ist ein") aus. Die Zeile :Movie_453 a :Movie . bedeutet also: "Die Resource :Movie_453 ist eine Instanz der Klasse :Movie."
Im Wissensgraphen entspricht das der Kante a von der Instanz zur Klasse.
Tipp: Merke dir das Muster
:Instanz a :Klasse- links steht das konkrete Objekt, rechts sein Typ. Genau dieses Muster nutzt man in SPARQL im WHERE-Teil (?m a :Movie), um alle Instanzen einer Klasse zu finden.
Siehe EKI04.
Fortgeschritten
Aufgabe 4 (Fortgeschritten) - Turtle schreiben
Modelliere folgendes Wissen in Turtle-Notation. Nutze das Semikolon ; zur Verkettung und das Komma , für mehrere Objekte desselben Prädikats:
Der Film :Movie_77 ist eine Instanz der Klasse :Movie, hat den Titel "Inception", das Genre :Genre_28 und zwei Produktionsfirmen :Company_1 und :Company_2. Das Genre :Genre_28 ist eine Instanz von :Genre mit dem Namen "Action".
Lösung anzeigen
:Movie_77 a :Movie ;
:title "Inception" ;
:genres :Genre_28 ;
:production_companies :Company_1 , :Company_2 .
:Genre_28 a :Genre ;
:name "Action" .
Erklärung:
- Das Semikolon
;verkettet mehrere Tripel mit demselben Subjekt (:Movie_77). - Das Komma
,verkettet mehrere Objekte für dasselbe Subjekt-Prädikat-Paar (:production_companies :Company_1 , :Company_2). - Der Punkt
.beendet den Tripel-Block; danach beginnt ein neues Subjekt (:Genre_28). adrückt die Instanz-Beziehung aus.
Falle: Vor dem Wechsel zu einem neuen Subjekt muss ein Punkt
.stehen, nicht ein Semikolon. Innerhalb desselben Subjekts steht nach jedem Prädikat-Objekt-Paar (ausser dem letzten) ein Semikolon.
Siehe EKI04.
Aufgabe 5 (Fortgeschritten) - SPARQL lesen
Was liefert die folgende Query zurück? Beschreibe Ergebnisinhalt und -struktur (Spalten).
PREFIX : <https://www.themoviedb.org/kaggle-export/>
SELECT ?t ?o
WHERE {
?s a :Movie ;
:title ?t ;
:overview ?o .
}
Lösung anzeigen
Die Query liefert für jeden Film (Instanz von :Movie, der sowohl :title als auch :overview besitzt) ein Paar aus Titel und Handlungsbeschreibung (overview).
Ergebnisstruktur: eine Tabelle mit zwei Spalten - ?t (Titel) und ?o (overview) - und einer Zeile pro passender Zuweisung. Im Kapitel-Beispiel sind das 2992 Ergebnisse.
Ablauf im Detail:
?s a :Moviebindet?san alle Movie-Instanzen.:title ?tund:overview ?oholen für dasselbe?sTitel und Handlung.- Nur Filme, die beide Prädikate haben, erscheinen im Ergebnis.
Tipp: Die Variable
?sverbindet alle drei Tripel des Musters (gleiches Subjekt), taucht aber nicht im SELECT auf und wird deshalb nicht angezeigt. Nur Variablen im SELECT werden zu Spalten.
Siehe EKI04.
Aufgabe 6 (Fortgeschritten) - SPARQL schreiben: alle Filmtitel
Schreibe eine SPARQL-Query, die die Titel aller Filme zurückgibt. Verwende den PREFIX aus dem Kurs.
Lösung anzeigen
PREFIX : <https://www.themoviedb.org/kaggle-export/>
SELECT ?t
WHERE {
?m a :Movie ;
:title ?t .
}
Erklärung:
PREFIX : <...>definiert den base namespace, damit:Movieund:titleals Kurzform funktionieren.?m a :Moviebindet?man jede Movie-Instanz.:title ?tholt den Titel jedes solchen Films in die Variable?t.SELECT ?tgibt eine einspaltige Tabelle mit allen Titeln aus (im Kapitel-Beispiel 3000 Ergebnisse, z.B. "Cabin in the Sky", "The Women", "The Lost City of Z").
Tipp: Query-Variablen beginnen immer mit
?. Der Variablenname ist frei wählbar -?t,?title,?xliefern dasselbe, solange er konsistent verwendet wird.
Siehe EKI04.
Aufgabe 7 (Fortgeschritten) - DISTINCT verstehen
Dieselbe Query liefert ohne DISTINCT 7511 Ergebnisse, mit DISTINCT nur 20. Erkläre, warum, und wozu DISTINCT dient.
SELECT DISTINCT ?n
WHERE {
?m a :Movie ;
:title ?t ;
:genres ?g .
?g :name ?n .
}
Lösung anzeigen
DISTINCT vermeidet Duplikate im Ergebnis.
- Ohne DISTINCT: Für jede Film-Genre-Zuordnung entsteht eine Zeile. Da viele Filme dasselbe Genre haben, erscheint z.B. "Drama" sehr oft. Das ergibt 7511 Zeilen (eine pro Film-Genre-Paar).
- Mit DISTINCT: Doppelte Werte von
?nwerden zusammengefasst. Übrig bleiben nur die 20 eindeutigen Genre-Namen (Comedy, Drama, Family, Romance, Thriller, Action, ...).
DISTINCT ist also nützlich, wenn man die Menge der vorkommenden Werte will, nicht deren Häufigkeit.
Falle:
DISTINCTwirkt auf die gesamte selektierte Zeile, nicht auf eine einzelne Spalte. BeiSELECT DISTINCT ?t ?nwäre eine Zeile nur dann ein Duplikat, wenn Titel UND Genre-Name identisch sind.
Siehe EKI04.
Anspruchsvoll
Aufgabe 8 (Anspruchsvoll) - Join über eine gemeinsame Variable
Schreibe eine SPARQL-Query, die zu jedem Film seinen Titel und seinen Genre-Namen ausgibt. Erkläre, wie der Join zustande kommt.
Lösung anzeigen
PREFIX : <https://www.themoviedb.org/kaggle-export/>
SELECT ?m ?t ?g ?n
WHERE {
?m a :Movie ;
:title ?t ;
:genres ?g .
?g :name ?n .
}
Wie der Join funktioniert: Die Variable ?g wird an zwei Stellen verwendet:
:genres ?g- bindet?gan das Genre-Objekt eines Films.?g :name ?n- benutzt genau dieses?gals Subjekt, um den Genre-Namen zu holen.
Weil dieselbe Variable mehrfach vorkommt, erzwingt SPARQL bei jedem Vorkommen denselben Wert. Das verbindet die Film-Tripel mit den Genre-Tripeln - genau das ist ein Join. Ergebnis: Paare wie ("Cabin in the Sky", Fantasy), ("Cabin in the Sky", Music), ("The Women", Drama) - im Beispiel 7511 Ergebnisse.
graph LR
M["?m (Movie)"] -->|":genres"| G["?g (Genre)"]
G -->|":name"| N["?n (Name)"]
M -->|":title"| T["?t (Titel)"]
Tipp: Ein Join in SPARQL braucht kein eigenes Schlüsselwort (kein JOIN wie in SQL). Es genügt, dieselbe Variable an den zu verbindenden Stellen zu nennen.
Siehe EKI04.
Aufgabe 9 (Anspruchsvoll) - Turtle als Wissensgraph interpretieren
Gegeben sind diese fünf Tripel:
:Movie_453 a :Movie ;
:title "A Beautiful Mind" ;
:genres :Genre_18 .
:Genre_18 a :Genre ;
:name "Drama" .
a) Zeichne (als Mermaid-Graph) den zugehörigen Wissensgraphen. b) Welche Knoten sind Instanzen, welche Klassen, welche Literale (Werte)?
Lösung anzeigen
a) Wissensgraph:
graph LR
M453["#quot;:Movie_453#quot;"] -->|a| MOVIE["#quot;:Movie#quot;"]
M453 -->|":title"| T["#quot;A Beautiful Mind#quot;"]
M453 -->|":genres"| G18["#quot;:Genre_18#quot;"]
G18 -->|a| GENRE["#quot;:Genre#quot;"]
G18 -->|":name"| D["#quot;Drama#quot;"]
b) Einordnung der Knoten:
| Knoten | Typ |
|---|---|
:Movie_453, :Genre_18 | Instanzen (Objekte) |
:Movie, :Genre | Klassen |
| "A Beautiful Mind", "Drama" | Literale (String-Werte) |
Die Kanten :title, :genres, :name sowie a (= rdf:type) sind die Prädikate/Beziehungen.
Falle: Der Titel "A Beautiful Mind" ist ein reiner String-Wert (Literal), kein eigenständiges Objekt mit URI. Er steht am Ende einer Kante, hat aber selbst keine ausgehenden Kanten.
Siehe EKI04.
Aufgabe 10 (Anspruchsvoll) - Ergebnisformat und Bedingungen
a) Wie viele Zeilen und Spalten hat das Ergebnis einer SPARQL-Query grundsätzlich? b) Vervollständige die Query so, dass sie nur die overview des Films mit dem Titel "A Beautiful Mind" liefert.
PREFIX : <https://www.themoviedb.org/kaggle-export/>
SELECT ?o
WHERE {
?s a :Movie ;
:title ______ ;
:overview ?o .
}
Lösung anzeigen
a) Das Ergebnis ist eine Tabelle mit einer Spalte pro Query-Variable (den Variablen im SELECT) und einer Zeile pro Zuweisung, die auf das Muster im WHERE-Teil passt.
b) Die Lücke wird mit dem konkreten Wert "A Beautiful Mind" gefüllt:
PREFIX : <https://www.themoviedb.org/kaggle-export/>
SELECT ?o
WHERE {
?s a :Movie ;
:title "A Beautiful Mind" ;
:overview ?o .
}
Ein konkreter Wert anstelle einer Variablen wirkt als Bedingung: Statt alle Titel in ?t zu binden, wird nur der Film akzeptiert, dessen :title exakt "A Beautiful Mind" ist. Ergebnis: genau 1 Zeile - die overview dieses Films.
Tipp: Bedingungen entstehen in SPARQL, indem man an einer Musterstelle eine Variable durch einen festen Wert (oder eine feste Resource) ersetzt. Für komplexere Bedingungen (Vergleiche, Datentypen) gibt es zusätzlich
FILTER.
Siehe EKI04.
Klausur-Niveau
Aufgabe 11 (Klausur-Niveau) - Turtle-Ausschnitt analysieren
Betrachte diesen Ausschnitt aus TMDB.ttl:
:Movie_1 a :Movie ;
:id "1"^^xsd:integer ;
:budget "14000000"^^xsd:integer ;
:genres :Genre_35 ;
:original_language "en" ;
:title "Hot Tub Time Machine 2" ;
:production_companies :Company_4 , :Company_60 , :Company_8411 .
a) Nenne für das Tripel mit dem Prädikat :title jeweils Subjekt, Prädikat und Objekt und gib an, ob das Objekt eine Resource oder ein Wert ist.
b) Wie viele Produktionsfirmen hat dieser Film und welches Zeichen verkettet sie?
c) Wenn @base <https://www.themoviedb.org/kaggle-export/> gilt, wie lautet die volle URI von :Movie_1?
d) Was bedeutet "14000000"^^xsd:integer?
Lösung anzeigen
a) Tripel :Movie_1 :title "Hot Tub Time Machine 2":
- Subjekt:
:Movie_1(eine Resource) - Prädikat:
:title(eine Resource) - Objekt:
"Hot Tub Time Machine 2"- ein Wert (String-Literal), keine Resource.
b) Der Film hat drei Produktionsfirmen (:Company_4, :Company_60, :Company_8411). Sie werden durch das Komma , verkettet, das mehrere Objekte für dasselbe Subjekt-Prädikat-Paar (:production_companies) angibt.
c) Die volle URI ist:
<https://www.themoviedb.org/kaggle-export/Movie_1>
Der leere Präfix : wird durch die @base-URI ersetzt und der lokale Name Movie_1 angehängt.
d) "14000000"^^xsd:integer ist ein typisiertes Literal: der Wert 14000000 mit der Datentyp-Annotation xsd:integer (Ganzzahl). Das ^^ gibt den Datentyp an; so weiss der Triple Store, dass es sich um eine Zahl und nicht um einen beliebigen String handelt.
Tipp: Nur Subjekt und Prädikat müssen Resourcen sein. Das Objekt kann eine Resource sein (
:genres :Genre_35) ODER ein Wert (:title "...",:budget "14000000"^^xsd:integer).
Siehe EKI04.
Aufgabe 12 (Klausur-Niveau) - Query mit Join und DISTINCT entwerfen
Formuliere eine SPARQL-Query, die eine duplikatfreie Liste aller vorkommenden Genre-Namen liefert. Erkläre, welche zwei Sprachmittel du kombinierst und warum das Ergebnis dadurch von 7511 auf 20 Zeilen schrumpft.
Lösung anzeigen
PREFIX : <https://www.themoviedb.org/kaggle-export/>
SELECT DISTINCT ?n
WHERE {
?m a :Movie ;
:genres ?g .
?g :name ?n .
}
Kombinierte Sprachmittel:
- Join über
?g::genres ?gund?g :name ?nteilen sich die Variable?g. Dadurch wird jedes Genre-Objekt eines Films mit seinem Namen verknüpft. Ohne DISTINCT ergibt das eine Zeile pro Film-Genre-Paar - im Beispiel 7511. DISTINCT: entfernt doppelte Werte von?n. Da es nur 20 verschiedene Genre-Namen gibt (Comedy, Drama, Action, ...), bleiben genau 20 Zeilen übrig.
Der Join erzeugt also viele (redundante) Zeilen, DISTINCT reduziert sie auf die eindeutigen Werte.
Falle: Der Titel
?tist hier nicht nötig und wurde weggelassen. Hätte manSELECT DISTINCT ?t ?ngeschrieben, würde DISTINCT auf das Paar (Titel, Genre) wirken und das Ergebnis wäre wieder viel grösser - man bekäme nicht die 20 reinen Genre-Namen.
Siehe EKI04.
Aufgabe 13 (Klausur-Niveau) - SPARQL, RDF und Werkzeuge im Zusammenhang
a) Was ist SPARQL und wer standardisiert es?
b) Was ist RDF und in welcher Notation wird es in diesem Kurs geschrieben?
c) Welche Rolle spielt Apache Jena Fuseki, und unter welcher Adresse läuft der Server?
d) Wie führt man in Python mit rdflib eine SPARQL-Query aus (grober Ablauf)?
Lösung anzeigen
a) SPARQL (SPARQL Protocol And RDF Query Language) ist die Abfragesprache für RDF-Wissensgraphen. Sie wird vom W3C standardisiert; aktuelle Version ist 1.1.
b) RDF (Resource Description Framework) ist eine formale Sprache zur Repräsentation von Wissensgraphen, spezifiziert vom W3C als Teil der Semantic-Web-Initiative. In diesem Kurs wird die Notation Turtle (Terse RDF Triple Language) verwendet.
c) Apache Jena Fuseki ist ein SPARQL-Server: Er stellt die Tripel als SPARQL-Endpoint über HTTP bereit, hat eine Web-UI zum Anlegen von Datasets, Hochladen von .ttl-Dateien und Ausführen von Queries. Der Server läuft auf http://localhost:3030. (Beim Laden von TMDB.ttl entstehen rund 1.329.040 Tripel.)
d) Ablauf mit rdflib:
import rdflib
g = rdflib.Graph()
g.parse('data/TMDB.ttl', format='turtle') # Wissensgraph laden
query_result = g.query("""SELECT DISTINCT ?gg WHERE { ?m a :Movie ; :genres ?g . ?g :name ?gg . }""")
for row in query_result:
print(row[0]) # erste Variable pro Zeile
Man erzeugt einen Graph, lädt die Turtle-Datei mit g.parse(...), führt die Query mit g.query(...) aus (Ergebnistyp SPARQLResult) und iteriert über die Zeilen; mit row[0] greift man auf die erste Variable zu.
Falle: Im Kapitel-Beispiel fehlt im Python-Query-String das
PREFIX :, obwohl der leere Präfix:benutzt wird. Damit der Code läuft, muss der Default-Namespace zusätzlich bekannt gemacht werden (z.B. perPREFIXim Query oderinitNs).
Siehe EKI04.