672 lines
35 KiB
TeX
672 lines
35 KiB
TeX
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Setup des Dokuments
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\documentclass[12pt,DIV14,BCOR10mm,a4paper,twoside,parskip=half-,headsepline,headinclude]{scrreprt} % Grundgröße 12pt, zweiseitig
|
|
% Packages from template
|
|
\usepackage[headsepline,automark]{scrpage2} % Seitenköpfe automatisch
|
|
\KOMAoptions{headinclude} % Fix
|
|
\usepackage[german]{babel} % Sprachpaket für Deutsch (Umlaute, Trennung,deutsche Überschriften)
|
|
% Not needed anymore
|
|
% \usepackage{blindtext}
|
|
\usepackage{graphicx,hyperref} % Graphikeinbindung, Hyperref (alles klickbar, Bookmarks)
|
|
\usepackage{amssymb} % Math. Symbole aus AmsTeX
|
|
\usepackage[utf8]{inputenc} % Umlaute
|
|
% Custom packages
|
|
\usepackage[autostyle=true,german=quotes]{csquotes} % Anführungszeichen mit \enquote{}
|
|
\usepackage{textcomp} % Zusätzliches Package für °C
|
|
\usepackage{listings} % Codesnippets
|
|
\usepackage{scrhack} % Hack for lstlisting i suspect :-/
|
|
\usepackage{xcolor}
|
|
\usepackage{verbatim} % für comment-environment
|
|
% Setup für Codeblocks
|
|
\lstset{
|
|
% Optionen
|
|
breaklines=true,
|
|
breakatwhitespace=true,
|
|
breakautoindent=true,
|
|
frame=single,
|
|
%framexleftmargin=19pt,
|
|
inputencoding=utf8,
|
|
%language=awk,
|
|
%numbers=left,
|
|
%numbersep=8pt,
|
|
showspaces=false,
|
|
showstringspaces=false,
|
|
tabsize=1,
|
|
%xleftmargin=19pt,
|
|
captionpos=b,
|
|
% Styling
|
|
basicstyle=\footnotesize\ttfamily,
|
|
commentstyle=\footnotesize,
|
|
keywordstyle=\footnotesize\ttfamily,
|
|
numberstyle=\footnotesize,
|
|
stringstyle=\footnotesize\ttfamily,
|
|
}
|
|
% Hack für Sonderzeichen in Codeblocks
|
|
\lstset{literate=%
|
|
{Ö}{{\"O}}1
|
|
{Ä}{{\"A}}1
|
|
{Ü}{{\"U}}1
|
|
{ß}{{\ss}}1
|
|
{ü}{{\"u}}1
|
|
{ä}{{\"a}}1
|
|
{ö}{{\"o}}1
|
|
{°}{{${^\circ}$}}1
|
|
}
|
|
|
|
% Befehl für TODO-Markierungen
|
|
\newcommand{\todo}[1]{\textcolor{blue}{\emph{TODO: #1}}}
|
|
|
|
% Befehl für Entwürfe und grobe Pläne
|
|
\newenvironment{draft}{\par\color{orange}\begin{center}Entwurf / Konzept\end{center}\hrule}{\hrule\par}
|
|
|
|
% Broken citation needs broken command
|
|
\newcommand\mathplus{+}
|
|
|
|
% Festlegung Kopf- und Fußzeile
|
|
\defpagestyle{meinstil}{%
|
|
{\headmark \hfill}
|
|
{\hfill \headmark}
|
|
{\hfill \headmark\hfill}
|
|
(\textwidth,.4pt)
|
|
}{%
|
|
(\textwidth,.4pt)
|
|
{\pagemark\hfill Jan Philipp Timme}
|
|
{Version 0.1 vom \today \hfill \pagemark}
|
|
{Version 0.1 vom \today \hfill \pagemark}
|
|
}
|
|
\pagestyle{meinstil}
|
|
|
|
\raggedbottom
|
|
|
|
\renewcommand{\topfraction}{1}
|
|
\renewcommand{\bottomfraction}{1}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Beginn des Dokuments (Titelseite und der ganze Krempel)
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\begin{document}
|
|
|
|
% Titelseite
|
|
\thispagestyle{empty}
|
|
\includegraphics[width=0.2\textwidth]{res/Wortmarke_WI_schwarz.pdf}
|
|
{ ~ \sffamily
|
|
\vfill
|
|
{\Huge\bfseries Verarbeitung von Daten\-strömen im RDF-Format in Kombination mit Hin\-ter\-grund\-wis\-sen in der C-SPARQL-Engine}
|
|
\bigskip
|
|
|
|
{\Large Jan Philipp Timme
|
|
\\[2ex]
|
|
Bachelor-Arbeit im Studiengang "`Angewandte Informatik"'
|
|
\\[5ex]
|
|
\today
|
|
}
|
|
}
|
|
\vfill
|
|
~ \hfill
|
|
\includegraphics[height=0.3\paperheight]{res/H_WI_Pantone1665.pdf}
|
|
\vspace*{-3cm}
|
|
|
|
% Seite mit Personen und Selbstständigkeitserklärung
|
|
\newpage \thispagestyle{empty}
|
|
\begin{tabular}{ll}
|
|
{\bfseries\sffamily Autor} & Jan Philipp Timme \\
|
|
& 1271449 \\
|
|
& jan-philipp.timme@stud.hs-hannover.de \\[5ex]
|
|
{\bfseries\sffamily Erstprüfer} & Prof. Dr. Jürgen Dunkel \\
|
|
& Abteilung Informatik, Fakultät IV \\
|
|
& Hochschule Hannover \\
|
|
& juergen.dunkel@hs-hannover.de \\[5ex]
|
|
{\bfseries\sffamily Zweitprüfer} & N. N. \\
|
|
& Abteilung Informatik, Fakultät IV \\
|
|
& Hochschule Hannover \\
|
|
& ---@---.--
|
|
\end{tabular}
|
|
|
|
\vfill
|
|
|
|
% fett und zentriert in der Minipage
|
|
\begin{center} \sffamily\bfseries Selbständigkeitserklärung \end{center}
|
|
|
|
Hiermit erkläre ich, dass ich die eingereichte Bachelor-Arbeit
|
|
selbständig und ohne fremde Hilfe verfasst, andere als die von mir angegebenen Quellen
|
|
und Hilfsmittel nicht benutzt und die den benutzten Werken wörtlich oder
|
|
inhaltlich entnommenen Stellen als solche kenntlich gemacht habe.
|
|
\vspace*{7ex}
|
|
|
|
Hannover, den \today \hfill Unterschrift
|
|
|
|
\pdfbookmark[0]{Inhalt}{contents}
|
|
% Inhaltsverzeichnis
|
|
\tableofcontents
|
|
% Abbildungsverzeichnis
|
|
\listoffigures
|
|
% Codeverzeichnis
|
|
\lstlistoflistings
|
|
% Tabellenverzeichnis
|
|
\listoftables
|
|
|
|
\newpage
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
%%% Hier geht es richtig los mit dem Text!
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\chapter{Einleitung}
|
|
|
|
Diese Arbeit beschäftigt sich mit \enquote{Complex Event Processing} (CEP), also der Verarbeitung komplexer Ereignisse auf Ereignisdatenströmen in Kombination mit Do\-män\-en\-wis\-sen, und der praktischen Umsetzung dieses Vorhabens auf Basis von RDF-Datenströmen mit der CEP-Engine \enquote{C-SPARQL}.
|
|
|
|
\todo{Dem Dokument anpassen; Soll groben Ausblick auf Inhalte geben.}
|
|
|
|
Nach einem kurzen Einstieg in das Thema CEP soll der Leser einen Einblick in die Features von aktuellen CEP-Engines erhalten und am Beispiel der Engine C-SPARQL\footnote{Mehr Informationen zu C-SPARQL und Download unter \url{http://streamreasoning.org/resources/c-sparql}} die Verarbeitung von Ereignisströmen im RDF-Format in Kombination mit Hintergrundwissen im Detail kennenlernen.
|
|
An einem Beispielszenario soll dann der Praxiseinsatz von C-SPARQL erklärt werden, in dem einige der vorgestellten Funktionen Anwendung finden. Im Abschluss wird ein kurzer Ausblick auf die technischen Möglichkeiten des \enquote{Reasoning} gegeben --- eine Technik, die es erlaubt auf den vorhandenen und eingehenden Daten logische Operationen und Schlussfolgerungen durchzuführen um daraus neues Wissen abzuleiten.
|
|
|
|
|
|
\section{Motivation}
|
|
|
|
\begin{itemize}
|
|
\item Situation: offene Systeme mit RDF-Datenströmen
|
|
\item Vorhaben: Auf den Daten dieser Systeme CEP fahren unter Integration von bereits vorhandenem Domänenwissen
|
|
\item Ziel: Relevante komplexe Ereignisse aus (Mustern von) einfachen Ereignissen extrahieren
|
|
\item Bonusziel: Erkenntnisse aus den Ereignisströmen extrahieren
|
|
\item Mittel zum Weg: CSPARQL (Erweiterung von SPARQL um Befehle für Datenströme)
|
|
\end{itemize}
|
|
|
|
\todo{Ausformulieren}
|
|
|
|
\subsection{Beispielszenario für diesen Kontext}
|
|
|
|
Autoverleih?
|
|
|
|
|
|
\chapter{Grundlagen}
|
|
|
|
|
|
\section{RDF und das semantische Web}
|
|
|
|
\begin{itemize}
|
|
\item Was ist RDF?
|
|
\item Warum überhaupt RDF?
|
|
\item RDF vs RDBMS?
|
|
\item Kleinster gemeinsamer Nenner für Informationen
|
|
\item Events als Quadrupel (wegen Timestamps)
|
|
\item Einführung des Begriffs CSPARQL als SPARQL mit Erweiterungen für Ereignisverarbeitung
|
|
\item Beispielhafter CSPARQL-Query
|
|
\item Erläuterung der einzelnen Bestandteile?
|
|
\item Vorteile bei der Nutzung von CSPARQL?
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{RDF im semantischen Web}
|
|
|
|
Das Ressource Description Framework (RDF) wird bereits im semantischen Web zur Erfassung und Verknüpfung von Wissen verwendet. RDF-Daten bestehen aus einer Menge von Tripeln, welche sich aus den drei Komponenten Subjekt, Prädikat und Objekt zusammensetzen. Ein Subjekt wird durch eine eindeutige URI identifiziert; über Prädikate können diesem Subjekt mit Spezifikation im Objekt-Teil des Tripels bestimmte Attribute mit Werten zugesprochen werden oder Verknüpfungen mit anderen Subjekten hergestellt werden. Aufgrund der Flexibilität dieser Struktur ist es möglich, nahezu jede Art von Informationen auf Tripel abzubilden, wie Listing~\ref{lst:sample_rdf_data} an einem Beispiel zeigt.
|
|
|
|
\begin{lstlisting}[caption={RDF-Daten beschreiben zwei Geschwister},label={lst:sample_rdf_data}]
|
|
:personA rdf:type :person
|
|
:personA :isGender :female
|
|
:personA :hasName "Marie"
|
|
|
|
:personB rdf:type :person
|
|
:personB :isGender :male
|
|
:personB :hasName "Max"
|
|
|
|
:personB :hasSibling :personA
|
|
\end{lstlisting}
|
|
|
|
Da innerhalb des semantischen Web angestrebt wird, in RDF vorliegende Informationen gemeinsam zu nutzen, miteinander zu kombinieren und vernetzen zu können, werden RDF-Tripel meist als Quadrupel gehandhabt, in denen als zusätzliche Information der sogenannte Graph genannt wird, in dem sie enthalten sind. Ein Graph wird durch eine URI identifiziert und dient somit als Namensraum für die Tripel, die er enthält. Dies vereinfacht die gleichzeitige Nutzung von mehreren Datenquellen, da jedes Tripel eindeutig einem Graphen zuzuordnen ist und innerhalb von Abfragen spezifisch Tripel aus verschiedenen Graphen kombiniert werden können.
|
|
|
|
Zusätzlich werden im semantischen Web in OWL (Web Ontology Language) formulierte Ontologien als \enquote{Strukturgerüst} verwendet. Eine Ontologie definiert ein Vokabular mit logischen Domänenobjektklassen und bestimmt für diese Objektklassen Prädikate und Attribute, um bestimmte Sachverhalte eindeutig abbilden zu können. Eine Ontologie für Listing~\ref{lst:sample_rdf_data} würde beispielsweise eine Objektklasse \enquote{person} definieren, auf welches die eigenen Prädikate \enquote{isGender}, \enquote{hasName} und \enquote{hasSibling} angewandt werden können. Mit eigenen Attributen für das Prädikat \enquote{isGender} und spezifischen Regeln dafür, welche Attribute ein Prädikat wie \enquote{hasSibling} in Frage kommen können, werden Daten aus der Welt einer Ontologie --- ähnlich wie bei einem relationalen Datenbankschema --- eindeutig strukturiert. Hierbei ist jedoch wichtig hervorzuheben, dass für in RDF abgebildete Daten die Annahme gilt, dass diese Daten nicht vollständig sind. Diese Annahme verhindert, dass in Ontologien Regeln über nicht vorhandene Fakten definiert werden, da die Abwesenheit von Fakten keine feste Bedeutung zugeschrieben bekommt.
|
|
|
|
Weiterhin ist es möglich, beliebig viele verschiedene Ontologien gleichzeitig zu verwenden. Diese Flexibilität ermöglicht beispielsweise, dass eine bereits in RDF abgebildete Person durch beliebige Informationen mit weiteren Ontologien ergänzt werden kann, oder dass die Informationen einer abgebildeten Person in verschiedenen, für andere Parteien geläufigen Strukturen verfügbar gemacht werden können. Auch kann innerhalb einer Ontologie auf Objektklassen und Attribute zurückgegriffen werden, die in anderen Ontologien definiert werden. Dies ermöglicht neben Erweiterungen für spezifische Zwecke auch das Übersetzen von Wissen zwischen verschiedenen Ontologien.
|
|
|
|
|
|
\subsection{Abfrage von RDF-Daten via SPARQL}
|
|
|
|
\begin{itemize}
|
|
\item SPARQL als Abfragesprache
|
|
\item Vorteil gegenüber relationalen Abfragesprachen?
|
|
\item Mächtigkeit durch Flexibilität der RDF-Daten
|
|
\item RDF-Daten meist verlinkt, SPARQL muss dem folgen können
|
|
\end{itemize}
|
|
|
|
Die Abfrage von RDF-Daten erfolgt über die Sprache SPARQL (\enquote{SPARQL Protocol And RDF Query Language}), welche in diesem Abschnitt grob erläutert wird. Eine detaillierte Beschreibung von SPARQL ist unter \cite{w3c:sparql} nachzulesen.
|
|
|
|
Im Gegensatz zu Abfragesprachen von relationalen Datenbanksystemen wie SQL ist es mit SPARQL möglich, Daten über verschiedene Datenquellen wie Tripel- oder Quadstores hinweg miteinander zu verknüpfen. Auch ist im Gegensatz zu SQL keine spezielle Anpassung der Abfragen an ein Datenbankschema notwendig; lediglich die Art und Weise, wie die angeforderten Daten miteinander in Verbindung stehen, ist für SPARQL-Abfragen wichtig. Im Folgenden zeigt Listing~\ref{lst:sample_sparql_query} eine einfache Abfrage auf den Daten aus Listing~\ref{lst:sample_rdf_data}.
|
|
|
|
\begin{lstlisting}[caption={Abfrage des Namens des Bruders von Marie aus Daten von Listing~\ref{lst:sample_rdf_data}},label={lst:sample_sparql_query}]
|
|
SELECT ?nameOfBrother
|
|
WHERE {
|
|
?marie rdf:type :person .
|
|
?marie :hasName "Marie" .
|
|
?marie :hasSibling ?brother .
|
|
?brother :hasName ?nameOfBrother .
|
|
}
|
|
\end{lstlisting}
|
|
|
|
Listing~\ref{lst:sample_sparql_query} zeigt, dass SPARQL in der groben Grundstruktur eine Ähnlichkeit zu SQL aufweist; allerdings sind bedingt durch die Struktur der Daten (Relationen bei SQL gegenüber Tripel und Quadrupel bei SPARQL) große Unterschiede in der Gestaltung der Abfragen --- speziell in der \texttt{WHERE}-Klausel --- zu finden: Hier werden Tripel mit Platzhaltern verwendet, um aus dem vorhandenen Datenbestand die Tripel zu isolieren, die auf das angegebene Muster passen. So wird in diesem Beispiel ein beliebiges Subjekt (gekennzeichnet durch \texttt{?marie}) gesucht, welches gleichzeitig vom Typ Person ist, den Namen \enquote{Marie} trägt und einen bisher unbekannten Bruder (\texttt{?brother}) hat, der einen noch unbekannten Namen (\texttt{?nameOfBrother}) trägt. Für jedes Subjekt, auf welches diese Beschreibung passt, ergibt sich nun ein Ergebnis, welches die in der \texttt{SELECT}-Klausel angegebenen Felder zurückgibt --- in diesem Fall also lediglich ein Ergebnis mit dem Wert \enquote{Max}.
|
|
|
|
Neben \texttt{SELECT} unterstützt SPARQL auch das Schlüsselwort \texttt{CONSTRUCT}. Dieses ermöglicht die direkte Konstruktion von neuen Tripeln aus vorgegebenen Tripeln mit Platzhaltern, welche mit den Ergebnissen der Abfrage gefüllt werden. Listing~\ref{lst:sample_sparql_construct} zeigt die Erzeugung von Tripeln für Geschwister, die auf ihren jeweilige Schwester (\enquote{isSisterOf}) beziehungsweise ihren jeweiligen Bruder (\enquote{isBrotherOf}) zeigen.
|
|
|
|
\begin{lstlisting}[caption={Konstruktion von Tripeln über das Bruder/Schwester-Verhältnis von Personen},label={lst:sample_sparql_construct}]
|
|
CONSTRUCT {
|
|
?sister :isSisterOf ?brother .
|
|
?brother :isBrotherOf ?sister .
|
|
} WHERE {
|
|
?sister rdf:type :person .
|
|
?sister :isGender :female .
|
|
?sister :hasSibling ?brother .
|
|
?brother :isGender :male .
|
|
}
|
|
\end{lstlisting}
|
|
|
|
|
|
\subsection{Schlussfolgerungen auf RDF-Daten}
|
|
|
|
\begin{itemize}
|
|
\item Was ist Reasoning?
|
|
\item Welche Ebenen gibt es? ((OWL, RDFS?) \todo{Ist der Unterschied zwischen den Beiden fürs erste sehr wichtig oder führt das zu weit?})
|
|
\item Warum ist es von Vorteil?
|
|
\item Mögliche Schwierigkeiten dabei?
|
|
\item Ontologien beschreiben Zusammenhänge zwischen Objektklassen und Klassen, die auf bestimmte Sachverhalte zutreffen.
|
|
\item Naja, jedenfalls kann man da schonmal autocomplete-mäßig rechnen (RDFS)
|
|
\item Und dann kann man noch reguläre Schlussfolgerungen fahren in der Richtung OWL
|
|
\item Warum ist Reasoning überhaupt wichtig und sinnvoll?
|
|
\end{itemize}
|
|
|
|
Durch den Einsatz von Ontologien ergibt sich die Möglichkeit, auf RDF-Daten Ontologie-gestützt Schlussfolgerungen anstellen zu können (\enquote{Reasoning}). In diesem Prozess werden aus den in RDF-Daten vorhandenen Fakten (Terminology Box, kurz: TBox) und den in den verwendeten Ontologien definierten Objektklassen, Regeln und Zusammenhängen (Assertion Box, kurz: ABox) neues Wissen abgeleitet \cite{hsh:integrating} und die lokale Datenbasis damit angereichert. So können beispielsweise implizite Klassentypen errechnet werden (Ein Kind ist eine Person), oder regelbasierte Attribute ermittelt werden: Max fährt ein Fahrzeug + das Fahrzeug ist ein Kran $\Longrightarrow$ Max ist ein Kranführer.
|
|
|
|
Enthält eine Ontologie Informationen über verschiedene Verwandtschaftsgrade in Familien, so ist es beispielsweise möglich auf Basis der Daten aus Listing~\ref{lst:sample_rdf_data} zusätzliche Verbindungen wie \enquote{isBrotherOf} und \enquote{isSisterOf} zu errechnen. Limitiert werden diese Möglichkeiten lediglich durch die OWA (Open World Assumption), also die Annahme einer offenen Welt, über die unvollständiges Wissen vorliegt. Deshalb dürfen für Reasoning nur explizit bekannte Fakten genutzt werden: Nur weil in Listing~\ref{lst:sample_rdf_data} keine Informationen über Eltern vorhanden sind, heißt das erst einmal nicht, dass Max und Marie wirklich Waisenkinder sind. Weiterführende Beispiele zu den Möglichkeiten von OWL Reasoning finden sich unter \cite{man:owl}.
|
|
|
|
Da Ontologien auch genutzt werden können, um Wissen aus den Strukturen einer Ontologie in die Struktur einer anderen Ontologie zu übersetzen, kann ein Reasoner die daraus resultierende Übersetzung direkt errechnen und der lokalen Datenbasis hinzufügen. Dadurch steht Abfragen, die schon auf die Ziel-Ontologie zugeschnitten sind, ein viel größerer Informationspool zur Verfügung, aus dem das Abfrageergebnis berechnet werden soll.
|
|
|
|
Diesen Vorteil erkauft man sich durch einen nicht unerheblichen Einsatz von Rechenleistung, da im Prozess des Reasoning eine Menge von zusätzlichen Daten entsteht, für die zusätzlich zu den bereits vorhandenen Daten die Regeln aller genutzten Ontologien berücksichtigt werden müssen. Behandelt man lediglich statische Daten, die sich kaum bis garnicht ändern, so ist der nötige Aufwand für Reasoning übersichtlich und liegt auch für große Mengen von Daten und Ontologien in einem akzeptablem Rahmen. Ändern sich jedoch häufig Daten, so muss für das Subset der sich geänderten Daten der Reasoning-Prozess erneut durchgeführt werden um eine vollständig aktuelle Datenbasis zu erhalten.
|
|
|
|
|
|
\section{Einführung in Complex Event Processing}
|
|
|
|
\begin{itemize}
|
|
\item Definition von CEP
|
|
\item Ereignisse und Hintergrundwissen/Domänenwissen
|
|
\item Beispielhafter, fiktiver Ereignisstrom mit Hinweis auf Zeitachse
|
|
\item Kurzer Exkurs in Richtung Mustererkennung
|
|
\end{itemize}
|
|
|
|
Im folgenden Abschnitt wird ein kurzer Einstieg in das Konzept von Complex Event Processing (CEP) gegeben. Eine detailreiche Erläuterung von CEP und die beispielhafte Anwendung der CEP-Engine \enquote{Esper} wird in \cite{hsh:cep} beschrieben.
|
|
|
|
Wie der Begriff \enquote{Complex Event Processing} schon andeutet, geht es bei CEP um die Verarbeitung von komplexen Ereignissen --- konkret: Die Erkennung und Erfassung von komplexen Ereignissen aus Datenströmen von primitiven Ereignissen. Von Messereignissen aus mit Sensoren ausgestatteten Geräten über Transaktionen im Handel bis hin zu Benutzerinteraktionen auf Webseiten entstehen täglich unzählig viele, primitive Ereignisse, die abhängig von ihrem Kontext für einen bestimmten Zeitraum ein Stück der echten Welt korrekt abbilden.
|
|
|
|
Die in diesen primitiven Ereignissen enthaltenen Informationen stellen nur einen momentanen Zustand dar; sie haben für sich alleine betrachtet keinen Kontext und somit vorerst bedeutungslos. Betrachtet man beispielsweise ein Ereignis \enquote{Die gemessene Temperatur beträgt 42°C.}, so ist zunächst nicht zu erkennen, was es mit dieser Temperatur auf sich hat. Hier kommt das für die Verarbeitung bereits bekannte \emph{Hintergrundwissen} (auch Domänenwissen) ins Spiel, welches das Ereignis in einen bekannten Kontext stellen kann. Es kann uns beispielsweise verraten, dass die Ereignisquelle ein Temperatursensor ist, der sich in einem PKW auf dem Motorblock befindet. Das Hintergrundwissen kann zu der bekannten Umgebung des Sensors viele weitere Angaben enthalten: Das konkrete Fabrikat des PKW, dessen Höchstgeschwindigkeit und die maximal zulässige Betriebstemperatur des Motors. Dieses Wissen ermöglicht schon eine genaue Einordnung der Informationen des Ereignisses; allerdings werden doch noch weitere Informationen benötigt, um ein eindeutiges Bild der Gesamtsituation zu erhalten. Kombiniert man das Temperaturereignis mit den Meldungen des im PKW installierten Geschwindigkeitssensors, so ergibt sich die Möglichkeit herauszufinden, ob für den aktuellen Betriebszustand des PKW die gemessene Motortemperatur.
|
|
|
|
Ein weiterer, wichtiger Faktor ist der Zeitraum in dem bestimmte Ereignisse auftreten. Um dies näher zu erläutern, betrachten wir den gegebenen Ereignisstrom aus Listing~\ref{lst:sample_eventstream}.
|
|
\begin{lstlisting}[caption={Exemplarischer Ereignisstrom: Motortemperatur eines PKW},label={lst:sample_eventstream}]
|
|
[Event #1] Temperatur: 40°C
|
|
[Event #2] Temperatur: 48°C
|
|
[Event #3] Temperatur: 61°C
|
|
[Event #4] Temperatur: 84°C
|
|
\end{lstlisting}
|
|
Auf den ersten Blick ist ersichtlich, dass die Messwerte einen sehr starken Temperaturanstieg abbilden, jedoch fehlt eine Angabe darüber, wie viel Zeit zwischen diesen Ereignissen vergangen ist. Dadurch ist die Interpretation dieser Ereignisse nicht mehr eindeutig möglich: Liegen zwischen den Messereignissen beispielsweise etwa 30-60 Minuten, so könnte es sich um einen normalen Betrieb bei hoher Geschwindigkeit handeln. Sollten jedoch nur wenige Minuten zwischen den Messereignissen vergangen sein, so lassen die Messwerte auf einen Defekt schließen und ein Motorschaden wäre eine mögliche Folge. Die Zeitachse darf somit bei der Ereignisverarbeitung nicht vernachlässigt werden.
|
|
|
|
Ein weiterer Kernaspekt von CEP ist die Mustererkennung in Ereignissen. Aus bestimmten primitiven Ereignissen, die in einer bestimmten Abfolge auftreten, soll ein konkreter Sachverhalt abgeleitet werden. Treten bei einem PKW beispielsweise in kurzer Zeit nacheinander die Ereignisse \enquote{Motor abgeschaltet}, \enquote{Fahrzeug verriegelt} und \enquote{PKW beschleunigt} auf, so könnte der Fall eingetreten sein, dass ein gerade abgestelltes Fahrzeug losgerollt ist und es sollte unverzüglich eine Reaktion darauf gestartet werden.
|
|
|
|
Insgesamt liegt die Herausforderung von CEP darin, in kürzester Zeit große Datenströme von Ereignissen mit Hintergrundwissen anzureichern, diese zu höherwertigen Ereignissen zu kombinieren und bestimmte Muster zu finden, sowie die Ergebnisse mit möglichst geringer Verzögerung in Echtzeit ausgeben zu können oder Reaktionen einzuleiten.
|
|
|
|
|
|
\chapter{Gegenüberstellung existierender CEP-Engines}
|
|
|
|
Es gibt bereits einige Technologien um Ereignisströme zu verarbeiten.
|
|
Im Folgenden stelle ich nun ein paar bekannte CEP-Systeme kurz vor.
|
|
|
|
Grobe Eckpunkte zur Orientierung:
|
|
\begin{itemize}
|
|
\item Woher kommt sie, wie sieht die Entwicklung zur Zeit aus?
|
|
\item Eckdaten über Implementierung
|
|
\item Fähigkeiten und Funktionen?
|
|
\end{itemize}
|
|
|
|
|
|
\section*{Anforderungen an CEP-Engines}
|
|
|
|
\todo{Eventuell fliegt die Section raus; Es sind mehr Kriterien/Features als Anforderungen, mal sehen was damit geschehen wird}
|
|
|
|
\begin{itemize}
|
|
\item Verarbeitung von mehreren Ereignisströmen
|
|
\item Kombination von Ereignissen \enquote{Join}
|
|
\item Konstruktion neuer Ereignisse
|
|
\item Sliding/Tumbling Windows
|
|
\item Mustererkennung (Abfolge, Präsenz/Absenz von Ereignissen [zeitlicher Abstand])
|
|
\item \enquote{COMPUTE EVERY} (Neuberechnung in festen Intervallen)
|
|
\item Ausführen von benutzerdefiniertem Code
|
|
\item Integration von Hintergrundwissen [aus weiteren Quellen]
|
|
\item Aggregationsfunktionen über mehrere Ereignisse (Sum, Avg, ...)
|
|
\item Vergleichsoperatoren für Selektionskriterien
|
|
\item Bonuspunkte: Reasoning (Logikoperationen und Schlussfolgerungen)
|
|
\end{itemize}
|
|
|
|
|
|
\section{EP-SPARQL}
|
|
|
|
\begin{itemize}
|
|
\item FZI Research Center for Information Technology (Karlsruhe, Deutschland)
|
|
\item Karlsruhe Institute of Technology (Karlsruhe, Deutschland)
|
|
\item Stony Brook University (New York, USA)
|
|
\item 2011? \cite{ep:unified}[Da kam zumindest diese Quelle raus]
|
|
\item \enquote{Event Processing SPARQL} \cite{ep:unified}
|
|
\item In Prolog implementierter Prototyp \cite{ep:unified}
|
|
\item Kann scheinbar Reasoning (nur RDFS, kein OWL?) \cite{ep:etalis}
|
|
\end{itemize}
|
|
|
|
|
|
\section{CQELS}
|
|
|
|
\begin{itemize}
|
|
\item Institut für Telekommunikationssysteme an der TU-Berlin (Berlin, Deutschland)
|
|
\item Insight Centre for Data Analytics an der National University of Ireland (Galway, Irland)
|
|
\item Institute of Information Systems an der Vienna University of Technology (Wien, Österreich)
|
|
\item 2015? \cite{cqels:stream}[Da kam zumindest diese Quelle raus]
|
|
\item \enquote{Continuous Query Evaluation over Linked Stream}
|
|
\item Soll sehr schnell sein
|
|
\item Zugriff auf lokales RDF-Wissen via IRI möglich (also ganz klassisch)
|
|
\item CSPARQL auf RDF-Strömen
|
|
\item Feeder können CSV lesen und zu RDF-Strömen machen, die der Engine zugeführt werden
|
|
\item Listener können aus SPARQL-Query-Ergebnissen CSV produzieren
|
|
\item In Java implementiert
|
|
\item Kein Reasoning?
|
|
\item CQELS\footnote{Unter \url{http://graphofthings.org/debs2015/cqels.zip} ist ein VirtualBox-Image zum Ausprobieren von CQELS erhältlich.}
|
|
\end{itemize}
|
|
|
|
|
|
\section{C-SPARQL}
|
|
|
|
\begin{itemize}
|
|
\item Woher kommt sie, wie sieht die Entwicklung zur Zeit aus?
|
|
\item Eckdaten über Implementierung
|
|
\item Fähigkeiten und Funktionen?
|
|
|
|
\item Verarbeitet Ströme im RDF-Format. Kann Hintergrundwissen im RDF-Format einbeziehen. In Java implementiert und entsprechend auch recht einfach in Java-Projekte zu integrieren.
|
|
\item Timestamp-Funktionalität zur Zeit mit einem Bug versehen, aber generell immernoch nutzbar.
|
|
\item Integration von Hintergrundwissen und Abfragen über mehrere Streams kombiniert möglich.
|
|
\item Reasoning zur Zeit nicht enthalten, aber es gibt Papers zu den Themen
|
|
\end{itemize}
|
|
|
|
\chapter{CEP auf RDF-Datenströmen (Konzept)}
|
|
|
|
Hier kommt der Part hin mit der abstrakten CQL für die Situation + C-SPARQL-Queries
|
|
|
|
\section{Ereignisse als RDF-Datenstrom}
|
|
|
|
Um Ereignisse aus verschiedenen Quellen gemeinsam zu verarbeiten ist RDF als kleinster gemeinsamer Nenner für Informationen das Mittel der Wahl. Hierbei werden die Ereignisse gegebenenfalls vorher in das RDF-Format transformiert und als Datenstrom aus RDF-Quadrupeln der CEP-Engine zugeführt. Die Quadrupel führen neben den ereignisrelevanten Informationen zusätzlich noch den Zeitstempel mit, zu dem das Ereignis ausgelöst wurde.
|
|
Als Abfragesprache für die RDF-Datenströme kommt eine erweiterte Form von SPARQL --- im Folgenden \enquote{CSPARQL} --- zum Einsatz, welche Erweiterungen und Funktionen speziell für die Verarbeitung von RDF-Datenströmen mitbringt. CSPARQL kann die eingehenden RDF-Datenströme in sogenannten \enquote{Sliding Windows} erfassen und ermöglicht die Berücksichtigung der Zeitstempel der Ereignisse innerhalb der Abfrage durch die Bereitstellung von zusätzlichen Sprachkonstrukten und Funktionen. Dabei besteht weiterhin die Möglichkeit, lokal in Form von RDF-Daten vorhandenes Domänenwissen in die Abfrage einzubeziehen und mit den Ereignisdaten zu verknüpfen.
|
|
|
|
In Listing~\ref{lst:sample_rdf_event} aufgeführt sind RDF-Tripel, die ein beispielhaftes Zustands-Ereignis aus einem PKW zeigen.
|
|
\begin{lstlisting}[caption={Ereignis im RDF-Format},label={lst:sample_rdf_event}]
|
|
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#carID http://myexample.org/cars#8
|
|
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#currentTemperature "27"^^http://www.w3.org/2001/XMLSchema#integer
|
|
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#currentSpeed "13"^^http://www.w3.org/2001/XMLSchema#integer
|
|
\end{lstlisting}
|
|
|
|
\todo{Noch ein wenig auf das Listing eingehen, URIs und die fiktiven Prädikate etwas erläutern}
|
|
|
|
|
|
\section{SPARQL-Erweiterung zur Verarbeitung von RDF-Datenströmen}
|
|
|
|
Der große Vorteil bei der Ereignisverarbeitung mit SPARQL auf RDF-Daten liegt in der Mächtigkeit dieser Abfragesprache: Innerhalb einer einzigen SPARQL-Abfrage ist es möglich Ereignisse aus verschiedenen Quellen miteinander zu kombinieren, direkt mit Hintergrundwissen zu kombinieren, nach eigenen Kriterien zu filtern, einfache Berechnungen anzustellen und aus dem Ergebnis neue Ereignisse beliebiger Struktur zu erzeugen.
|
|
Somit muss der Anwender neben SPARQL keine weiteren Sprachen lernen oder sich anderweitig mit der Implementierung der Engine auseinandersetzen, sondern kann sich komplett auf die zu analysierenden Ereignisse konzentrieren. Listing~\ref{lst:sample_combine_events_sparql} zeigt einen SPARQL-Query, in dem zwei aufeinanderfolgende Ereignisse mit Angaben zur Momentangeschwindigkeit eines Autos zu einem komplexeren Beschleunigungsereignis kombiniert werden.
|
|
|
|
\begin{lstlisting}[caption={Kombination von Ereignissen mit SPARQL},label={lst:sample_combine_events_sparql}]
|
|
REGISTER QUERY ConstructAcceleratingCars AS
|
|
PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#>
|
|
PREFIX cars: <http://myexample.org/cars#>
|
|
CONSTRUCT {
|
|
[] cars:carID ?car;
|
|
cars:acceleratedBy ?deltaSpeed .
|
|
}
|
|
FROM STREAM <http://myexample.org/cars> [RANGE 5s STEP 1s]
|
|
WHERE {
|
|
?e1 cars:carID ?car ;
|
|
cars:currentSpeed ?speed1 .
|
|
?e2 cars:carID ?car ;
|
|
cars:currentSpeed ?speed2 .
|
|
BIND (?speed2 - ?speed1 AS ?deltaSpeed)
|
|
FILTER(f:timestamp(?e1,cars:carID,?car) < f:timestamp(?e2,cars:carID,?car))
|
|
FILTER(?speed1 < ?speed2)
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\todo{Streaming-Erweiterungen aus dem Listiung ein wenig hervorheben}
|
|
|
|
|
|
\section{Resoning auf RDF-Datenströmen?}
|
|
|
|
\begin{itemize}
|
|
\item Immer noch ein Forschungsgebiet
|
|
\item sehr hoher Datendurchsatz (viele kleine Ereignisse in geringem Zeitraum)
|
|
\item Ereignisinformationen ändern sich sehr häufig, sind nie sehr lange gültig und nicht immer relevant zur einer Abfrage
|
|
\item Aber: Ergebnisse sollen möglichst schnell vorliegen
|
|
\item $\Longrightarrow$ große Menge Rechenaufwand
|
|
\item Einer der möglichen Ansätze: Reasoner errechnet für die Ereignisse Tripel mit begrenzter Lebensdauer
|
|
\end{itemize}
|
|
|
|
|
|
\chapter{Nutzung der Engine C-SPARQL (Implementation)}
|
|
|
|
In diesem Kapitel wird die C-SPARQL-Engine konkret vorgestellt und verwendet.
|
|
\begin{itemize}
|
|
\item RDF-Datenströme
|
|
\item Beispielszenario
|
|
\item Umsetzung mit C-SPARQL
|
|
\item Nötiger Code für das Grundsetup der Engine, Generatoren und co
|
|
\item Konkreter Blick auf die CSPARQL-Queries
|
|
\item Ergebnisse der Abfragen
|
|
\end{itemize}
|
|
|
|
|
|
\section{Nutzung der C-SPARQL Engine in Java}
|
|
|
|
Im Folgenden wird auf die praktische Anwendung der C-SPARQL-Engine in einem Java-Projekt eingegangen.
|
|
|
|
|
|
\subsection{Initialisieren der Engine}
|
|
|
|
Erst einmal die Instanz der Engine erzeugen und initialisieren (mit true, damit f:timestamp zur Verfügung steht).
|
|
\begin{lstlisting}
|
|
CsparqlEngine engine = new CsparqlEngineImpl();
|
|
engine.initialize(true);
|
|
\end{lstlisting}
|
|
|
|
|
|
\subsection{Stream-Generatoren}
|
|
|
|
Über den StreamGenerator muss ich etwas mehr erzählen, hier mal der grobe Code:
|
|
\begin{lstlisting}
|
|
public class StreamGenerator extends RdfStream implements Runnable {
|
|
private volatile boolean keepRunning = false;
|
|
|
|
public StreamGenerator(String iri) {
|
|
super(iri);
|
|
}
|
|
|
|
public void pleaseStop() {
|
|
keepRunning = false;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
this.keepRunning = true;
|
|
while (this.keepRunning) {
|
|
long currentTime = System.currentTimeMillis();
|
|
// Generate RdfQuadruple from data and hand it over to the engine
|
|
this.put(new RdfQuadruple(
|
|
someSubject,
|
|
somePredicate,
|
|
someObject,
|
|
currentTime
|
|
)
|
|
);
|
|
// Maybe sleep or do a simulation step
|
|
}
|
|
}
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\begin{itemize}
|
|
\item eigener Thread, also diesbezüglich wachsam bleiben
|
|
\item Aufgabe: Konstruktion von Quadrupeln + deren Übergabe an die Engine via \texttt{this.put()}
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{StreamGenerator an der Engine registrieren und starten}
|
|
|
|
Einen StreamGenerator erzeugen (im Konstruktor die IRI für alle generierten Quadrupel), an der Engine registrieren und starten
|
|
\begin{lstlisting}
|
|
RdfStream streamGenerator = new StreamGenerator("http://myexample.org/cars");
|
|
engine.registerStream(streamGenerator);
|
|
final Thread t = new Thread((Runnable) streamGenerator);
|
|
t.start();
|
|
\end{lstlisting}
|
|
|
|
|
|
\subsection{Query an der Engine registrieren}
|
|
|
|
|
|
Jetzt einen Query an der Engine registrieren; Ergebnis ist ein ResultProxy, an den Observer angeklemmt werden können um die Query-Ergebnisse weiter zu verarbeiten.
|
|
\begin{lstlisting}
|
|
String query = "%%% SPARQL QUERY %%%";
|
|
CsparqlQueryResultProxy resultProxy = null;
|
|
try {
|
|
resultProxy = engine.registerQuery(query, true);
|
|
} catch (ParseException e1) {
|
|
// handle exception
|
|
}
|
|
// Print results to console
|
|
resultProxy.addObserver(new ConsoleFormatter());
|
|
\end{lstlisting}
|
|
|
|
|
|
\subsection{Laufen lassen und abwarten}
|
|
|
|
Der Part ist einfach ;-)
|
|
Im Main-Thread einfach etwas Thread.sleep() callen und in den am ResultProxy angehangenen Observern die Ergebnisse entsprechend auswerten und weiter verarbeiten.
|
|
|
|
|
|
\subsection{Engine herunterfahren}
|
|
|
|
Ab hier läuft das ganze ab, bis es gestoppt wird. Um es abzubauen, wird zunächst der Query deregistriert.
|
|
\begin{lstlisting}
|
|
engine.unregisterQuery(resultProxy.getId());
|
|
\end{lstlisting}
|
|
|
|
// Jetzt noch den StreamGenerator stoppen und von der Engine abkoppeln, fertig.
|
|
\begin{lstlisting}
|
|
((StreamGenerator) streamGenerator).pleaseStop();
|
|
engine.unregisterStream(streamGenerator.getIRI());
|
|
\end{lstlisting}
|
|
|
|
|
|
\section{Einspeisung von Ereignissen}
|
|
|
|
\begin{itemize}
|
|
\item Ereignisse werden über StreamGenerators eingespeist
|
|
\item Diese laufen in einem eigenen Thread und schieben Quadrupel (Tripel + Systemzeit) in die Engine rein
|
|
\item Vor dem Start müssen sie an der Engine registriert werden
|
|
\end{itemize}
|
|
|
|
Spezielle Betrachtung der StreamGenerators und wie sie funktionieren, Anmerkungen darüber, dass hier Daten von außen gezogen und ggf. konvertiert werden können.
|
|
|
|
|
|
\section{Einspeisung von statischem Hintergrundwissen aus Dateien}
|
|
Wie und wo werden Dateien in welchen Formaten abgelegt, müssen sie zuvor in der Engine registriert werden und wie wird im Query darauf zugegriffen?
|
|
|
|
|
|
\section{CSPARQL-Queries}
|
|
|
|
\begin{itemize}
|
|
\item simpler Zugriff auf Eventdatenstrom
|
|
\item Zugriff auf mehrere Ereignisströme
|
|
\item Für jeden Datenstrom ein eigenes Sliding/Tumbling Window
|
|
\item Aggregation von Ereignissen zu neuen Ereignisströmen
|
|
\item Kombination von Ereignissen mit lokalem Hintergrundwissen
|
|
\end{itemize}
|
|
|
|
|
|
\section{Bewertung/Ergebnis}
|
|
|
|
\begin{itemize}
|
|
\item (Konnten die gestellten Anforderungen erfüllt werden?)
|
|
\item Was konnte erreicht werden?
|
|
\item Was konnte nicht erreicht werden?
|
|
\item Gab es Schwierigkeiten? [Guter Zeitpunkt, um hier f:timestamp() vs Tripel mit Literals zu erwähnen]
|
|
\item Wie hoch war der Aufwand?
|
|
\item Wie steht es um die Qualität der Ergebnisse?
|
|
\item Eventuell ein Blick auf die Performance?
|
|
\end{itemize}
|
|
|
|
|
|
\chapter{Fazit}
|
|
|
|
\begin{itemize}
|
|
\item Bewertung der Ergebnisse im Abgleich mit den Anforderungen und dem Aufwand?
|
|
\item Ist es für die Anforderungen (und mehr) praxistauglich?
|
|
\item Oder gibt es zur Zeit bessere Alternativen?
|
|
\end{itemize}
|
|
|
|
|
|
\chapter{Ausblick}
|
|
|
|
\begin{itemize}
|
|
\item Kann man mit der Engine in Zukunft noch mehr schaffen?
|
|
\item Wie steht es um Reasoning? Geht das? Wenn ja, nur RDFS oder auch OWL? \todo{Ist der Unterschied zwischen den Beiden fürs erste sehr wichtig oder führt das zu weit?}
|
|
\end{itemize}
|
|
|
|
Vielleicht geht das mit dem Reasoning später ja noch besser --- aktueller Stand ist noch limitiert, aber es wird fleißig daran geforscht \dots
|
|
|
|
\chapter*{Dummy-Kapitel für Tests}
|
|
|
|
\textcolor{red}{Dieses Kapitel fliegt am Ende natürlich raus.}
|
|
|
|
Sil-ben ge-trenn-t mit ei-nem Strich
|
|
|
|
C--SPARQL (Zwei Striche ergeben einen Bindestrich)
|
|
|
|
Und dann --- neben vielen anderen Zeichen --- gibt es mit drei Strichen den Gedankenstrich.
|
|
|
|
Mit \enquote{enquote} wird Text in Anführungszeichen gesetzt, aber manchmal ist vielleicht der Einsatz von \texttt{texttt} sinnvoll. Im \textbf{Notfall} kann auch \textbf{textbf} genutzt werden. Dann gibt es noch \textit{textit}, \textsc{textsc}, \textsf{textsf} und \textsl{textsl}.
|
|
|
|
|
|
Quellenreferenzen
|
|
\begin{itemize}
|
|
\item \cite{hsh:cep}[Einstieg in CEP mit Beispielen aus Esper-Welt]
|
|
\item \cite{hsh:integrating}[Esper vs C-SPARQL CEP ohne Reasoning]
|
|
\item \cite{barbieri:reasoning}[Ansatz für Reasoning auf RDF-Strömen mit C-SPARQL]
|
|
\item \cite{barbieri:querying}[Grundlagen C-SPARQL für CEP]
|
|
\item \cite{cqels:stream}[CQELS-Paper]
|
|
\item \cite{ep:etalis}[ETALIS-Paper]
|
|
\item \cite{ep:unified}[EP-SPARQL-Paper]
|
|
\item \cite{man:owl}[Owl Reasoning Examples]
|
|
\item \cite{w3c:sparql}[W3C zu SPARQL]
|
|
\item \cite{iao:esper}[Marktübersicht Real-Time Monitoring Software]
|
|
\end{itemize}
|
|
|
|
% Referenz auf Bibtex mit Kommentar
|
|
% \cite{robbins:gawk}[Siehe ab S.95]
|
|
|
|
% Einbinden von Tex-Files
|
|
%\input{abkuerz.tex}
|
|
%\input{einfuehrung.tex}
|
|
|
|
% Einbinden von größeren Tex-Files, z.B. Kapiteln
|
|
%\include{normen}
|
|
%\include{aufbau}
|
|
%\include{zitieren}
|
|
%\include{form}
|
|
%\include{allgtips}
|
|
|
|
%%% Ende inhaltlicher Inhalt! %%%
|
|
|
|
% Literaturverzeichnis
|
|
% Schlüssel als Buchstaben
|
|
\bibliographystyle{alpha}
|
|
\bibliography{Literaturverweise}
|
|
|
|
\end{document}
|
|
% Nothing beyond this line!
|