Komplexe Relationen in RDF

Das einfache Subjekt-Prädikat-Objekt Datenmodell von RDF verführt dazu, Beziehungen und Verben als einfache Prädikate oder Eigenschaften/Properties zu behandeln.

Das wird der Realität aber oft nicht gerecht.

Wenn wir z.B. Daten über Arbeitsverhältnisse oder Projektauftragnehmer sammeln, ist ein erster Ansatz vielleicht:

@prefix : <http://example.org/data/example#> .
@prefix demo: <http://example.org/models/demo/> .
@prefix gist: <https://ontologies.semanticarts.com/o/gistCore> .
@prefix schema: <https://schema.org/> .
   
:_Meier schema:worksFor  ~:_Firma .

Und dann wollen wir vielleicht noch sagen, dass Herr Maier als Teamleiter arbeitet:

:_Meier schema:worksFor  ~:_Firma …
:_Meier schema:ocupationalCategory  :_Teamleiter .

Super. Aber vielleicht ist der Herr Maier ja Freiberufler, und arbeitet für zwei Firmen
zur gleichen Zeit
 

:_Meier schema:worksFor  ~:_FirmaA .
:_Meier schema:worksFor  ~:_FirmaB .
:_Meier schema:ocupationalCategory  :_Teamleiter .
:_Meier schema:ocupationalCategory  :_Projektleiter .

In welcher Firma ist er jetzt Teamleiter, in welcher Projektleiter? Oder wir wollen sagen, dass Maier seit 2012 für :_FirmaA arbeitet, wie geht das? 

RDF-Star wird ja gerne als Lösung für die Darstellung zeitlicher Gültigkeit gesehen, aber wie wir gleich sehen, bringt das nicht so viel, wie sich einige erhoffen:

<<:_meier schema:worksFor  :_Firma >> 
  gist:actualStartDateTime "2012-09-01T00:00:00" .
<<:_meier schema:worksFor  :_Firma2 >> 
  gist:actualStartDateTime "2012-09-01T00:00:00" .
<<:_meier schema:position  :_Teamleiter >> 
  gist:actualStartDateTime "2012-09-01T00:00:00" .
<<:_meier schema:position  :_Projektmanager >> 
  gist:actualStartDateTime "2012-09-01T00:00:00" .

RDF-Star kann uns hier nicht sagen, inwieweit diese vier Fakten zusammenhängen, auch wenn sie alle zur gleichen Zeit starten...
 

Ein altes Problem, eine bekannte Lösung

Dieses Problem, Verben und Adjektive in formale Logik zu überführen ist schon lange bekannt. 

Eine oft genutzte Lösung wurde zuerst von Donald Davidson in The Logical Form of Action Sentences (1967) beschrieben, nach ihm können alle Handlungen als Ereignisse beschrieben werden, und Ereignisse sind in seiner Theorie Gegenstände, oder im RDF-Jargon Entitäten.

Damit wird also aus schema:worksFor ein demo:Employment. Und an dieses  freiberufliche Arbeitsverhältnis können dann alle nötigen Informationen angehängt werden:

      :_MeiersArbeitsverhältnis_A a demo:Contract ;
      demo:auftraggeber :_FirmaA ;
      demo:auftragnehmer :_Meier ;
      demo:position :_Teamleiter ;
      gist:actualStartDateTime "ZeitpunktA"^^xsd:dateTime .
      
      :_MeiersArbeitsverhältnis_B a demo:Contract ;
      demo:auftraggeber :_FirmaB ;
      demo:auftragnehmer :_Meier ;
      demo:position :_Projektmanager ;
      gist:actualStartDateTime "ZeitpunktA"^^xsd:dateTime .

Und weil wir gerade dabei sind, fügen wir noch Informationen über seine Abteilung und den zugrundeliegenden Vertrag hinzu:

  :_MeiersArbeitsverhältnis_A a demo:Contract ;
  demo:auftraggeber :_FirmaA ;
  demo:auftragnehmer :_Meier ;
  demo:position :_Teamleiter ;
  demo:abteilung :_AbteilungA ;
  demo:vertrag :_VertragA ;
  gist:actualStartDateTime "ZeitpunktA"^^xsd:dateTime .
  
  :_MeiersArbeitsverhältnis_B a demo:Contract ;
  demo:auftraggeber :_FirmaB ;
  demo:auftragnehmer :_Meier ;
  demo:position :_Projektmanager ;
  demo:abteilung :_AbteilungB ;
  demo:vertrag :_VertragB ;
  gist:actualStartDateTime "ZeitpunktA"^^xsd:dateTime .

Damit haben wir deutlich mehr Informationen erfasst. Und sobald mehr Informationen zu einem solchen Arbeits-- und Vertragsverhältnis erfasst werden, desto mehr schwindet der Unterschied in den benötigten Tripeln, also in der Last auf den Triplestore.

Bei der einfachen Aussage ist der Unterschied ein zu drei Tripeln:

 :_Meier schema:worksFor :_FirmaA .
 
  # vs
  
  :_MaiersArbeitsverhältnis_a a demo:Contract ;
    demo:auftraggeber :_FirmaA ;
    demo:auftragnehmer :_Meier .

Und würden wir hier RDF-Star einsetzen, um den Zeitrahmen auszudrücken, brauchen wir für jeden Triple ein zusätzliches RDF-Star Statement und damit sind wir dann bei 8 zu 8 Tripeln und haben noch nicht einmal ausgedrückt, dass wir hier *ein* Vertragsverhältnis beschreiben.

Natürlich könnten wir jetzt noch einmal 4 RDF-Star-Statements hinzufügen, die auf den zugehörigen Vertrag verweisen, um diese Triple zusammenfassen zu können, aber damit wären wir schon bei 12 zu 8 Tripeln: ein deutlicher Vorteil für die Darstellung eines Verbs oder einer Property als "Ding", als Entität, als eigene
URL. 

"Reifizieren" ist im RDF-Kontext ein schlechter Ausdruck hierfür

Diese Technik wird gerne "Reifizieren" genannt: aus einer Eigenschaft ein "Ding" machen.

In RDF gibt es allerdings eine semantische Form die "Reification" genannt wird, mit der man einen Triple referenzieren kann. RDF-Star fing ein wenig als syntactic sugar für die Reification in RDF an, eine einfachere Syntax um eine Aussage über einen Triple zu machen.

Darum wird im Kontext von RDF "reifizieren" oft als dieses eher selten benutzte Vokabular interpretiert, was zu Missverständnissen führt.

Darum vermeide ich das Wort in diesem Zusammenhang und spreche nur von Ereignissemantik bzw. event semantics.

Abfragekomplexität

Abfragen über solch komplexeren Datenmodelle sind natürlich ihrerseits komplexer: sowohl die textuelle und konzeptionelle Abfrage an sich, als auch die Ausführung der Abfrage. Das ist ein Grund, warum wir so viele einfache Eigenschaften in Ontologien definiert sehen, obwohl vielleicht eine Entität sinnvoller gewesen wäre.

Suchen wir z.B. die Firmen, in denen Herr Maier gearbeitet hat in einem einfachen Modell:

select ?firma where {
   :_Maier schema:worksFor ?firma
}

Wunderbar, oder? So leicht können Wissensgraphen sein...

Nun aber mit der gleichen Beziehung als Ereignis ausgedrückt:

 select ?firma where {
   ?contract a demo:Contract ;
   demo:auftragnehmer :_Maier ;
   demo:auftraggeber ?firma
 }

Deutlich mühsamer zu schreiben, und auch der Triplestore muss hier zwei vollständige Triple und eine potentielles Set von Tripeln suchen und dann einen Join von den drei Tripeln machen um zu antworten - deutlich aufwändiger!

Hier fehlt jetzt noch ein kleiner Benchmark, ich hoffe den in nächster Zeit zu ergänzen.

Detaillierter geht immer

Natürlich können wir auch die Eigenschaften unsres demo:Contract wiederum als Dinge ansehen: vielleicht ändert sich die Position von Herrn Maier während der Laufzeit eines Vertrages. Dann reicht unsere demo:position nicht mehr, und wir müssen eine demo:Position einführen, mit dem demo:contract und einer Positionsbeschreibung Eigenschaften.

Und so weiter, und so weiter. Das kann fast beliebig komplex werden. Und jeden Triplestore (und jeden Kopf) überfordern.

Vorgeschlagenes Vorgehen

Aus meiner Sicht sollte man bei jeder Eigenschaft prüfen, ob sich dahinter ein Event verbirgt. Oder sagen wir: ob man an diese Eigenschaft mehr Informationen anhängen kann.

Nur so kommt man zu vollständigen Modellen.

Und dann sollte man überlegen, ob man diese Informationen *wirklich* nötig braucht!

Und dann abschätzen, was die verschiedenen Modelle für den eingesetzten Triplestore bedeuten, und hier hilft nur testen, testen, testen.

Testen mit synthetischen oder Livedaten, aber vor allem mit einer Menge an Daten, die der angestrebten Menge zumindest nahe kommt, maximal eine Größenordnung davon entfernt. Lieber maximal 50% davon entfernt.

Und mit diesen Informationen dann von Fall zu Fall entscheiden, welche Eigenschaft wie modelliert wird: als OWL property oder als OWL node bzw. Individuum.

Wobei "von Fall zu Fall entscheiden" oft von Performancemessungen unterfüttert werden sollte.
 

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.

We use cookies on our website to support technical features that enhance your user experience.

Es werden keine Dienste zur Analyse Ihres Verhaltens genutzt, wir tracken sie nicht.