Blog

Wie nutzen wir Apache Zeppelin für Big Data?

Apache Zeppelin ist ein Framework, das verschiedene Interpreter zum Zweck der Datenanalyse unter einem Dach zusammenfasst. Das ist im Hinblick auf Big Data ausgesprochen nützlich, weil sich so Daten in ganz verschiedenen Sprachen und Darreichungsformen auslesen und analysieren lassen. Und das ist ja das erklärte Ziel von Big Data: Heterogene Daten aus ganz verschiedenen Quellen zu ernten und zu interpretieren.

Big-Data-Analyse als Erfolgsmotor

Ziel ist es, wie generell bei Big Data, große Datenmengen nutzbar zu machen, um daraus wichtige Informationen abzuleiten. Informationen etwa, die zur Prozessverbesserung beitragen oder die helfen, die Zielgruppe besser zu verstehen, Produkte oder Services besser auf deren Bedürfnisse anzupassen oder sogar neue Produkte und Geschäftsideen zu entwickeln.

Die wesentlichen Features von Apache Zeppelin umfassen folgende Services:

Multi-Purpose Notebook

Das webbasierte Mehrzweck-Notebook von Apache Zeppelin deckt alle Bedarfe ab: von der Datenaufnahme (Data Ingestion) über die Datenentdeckung (Data Discovery) und die Datenanalyse (Data Analytics) bis hin zur Datenvisualisierung (Data Visualization). Zusätzlich bietet Zeppelin Komfort-Features für die Kollaboration mit Kollegen, z. B. eine kommentierbare Versionierung der Notebooks.

Multiple Language Backend

Apache Zeppelin ist dank seines Interpreter-Ansatzes polyglott und erlaubt das Aufschalten von Datenverarbeitungssystemen in allen möglichen Programmiersprachen.. Zum jetzigen Zeitpunkt unterstützt das Framework die Interpreter Apache Spark, Python, (Spark)-SQL, (Spark)-R, Markdown und Shell.

Data Visualization

Apache Zeppelin wird bereits mit wesentlichen Grafik-, Diagramm- und Tabellenoptionen ausgeliefert. Grundsätzlich können alle tabellarischen Daten mit verschiedenen Diagrammarten visualisiert werden. Zusätzlich können mittels ggplot2 aus R viele bekannten und erkenntnissreiche Visualisierungen mit wenig Aufwand eingesetzt werden.

Jule Witte

Presse & Kommunikation
presse@micromata.de

Ein Beispiel zur Big-Data-Analyse mit Zeppelin

Was nun folgt, ist ein Anwendungsbeispiel, wie wir solche Daten mit Apache Zeppelin und unter Verwendung des Spark-Interpreters auslesen können. Der Fokus liegt dabei weniger auf der fachlichen Analyse der Daten. Stattdessen steht die Präsentation verschiedener Zeppelin-Features im Vordergrund.

Installation bzw. Ausführung

Apache Zeppelin ist ganz einfach lokal installierbar. Installationsanleitungen für verschiedene Szenarien finden sich hier [Link einsetzen] (https://zeppelin.apache.org/download.html). Noch einfacher ist es allerdings, wenn vorher Docker installiert wurde, dann reicht dieser Befehl, um eine neue Zeppelin-Instanz zu starten:

docker run -p 8080:8080 –rm -v $PWD/logs:/logs -v $PWD/notebook:/notebook -v $PWD:/data -e ZEPPELIN_LOG_DIR=’/logs‘ -e ZEPPELIN_NOTEBOOK_DIR=’/notebook‘ –name zeppelin apache/zeppelin:0.7.2

Alle zugehörigen Log-Dateien und Notebooks werden dann im aktuellen Verzeichnis des Benutzers gespeichert. Zum Einlesen von Daten geben wir das aktuelle Verzeichnis unter /data im Docker-Container frei. Nach erfolgreicher Ausführung (dies kann etwas dauern, da Zeppelin mit allen Interpretern recht groß ist) steht unter [http://localhost:8080](http://localhost:8080) die Zeppelin-Oberfläche zur Verfügung.

Unser Beispiel

Für unser Beispiel nutzen wir anonymisierte Bankdaten aus einem realen Bankprojekt im Bereich Machine Learning. Denn wir wollen Machine-Learning-Algorithmen testen. Dazu laden wir zunächst die betreffenden Daten unter http://archive.ics.uci.edu/ml/machine-learning-databases/00222/bank.zip herunter und entpacken sie in das lokale Verzeichnis.

Die Archivdatei besteht aus drei Dateien

bank-names.txt mit Informationen zur Historie und Erklärung des Formats
bank-full.csv mit allen Beispielen, nach Datum geordnet (von Mai 2008 bis November 2010)
bank.csv mit 10 % der Beispiele (4521), zufällig ausgewählt von bank-full.csv
Die CSV-Dateien haben die folgenden (der Dokumentation entnommenen) Attribute in den Spalten:

# general
01 – age (numeric)
02 – jo: type of job (categorical: „admin.“,“unknown“,“unemployed“,“management“,“housemaid“,“entrepreneur“,“student“,“blue-collar“,“self-employed“,“retired“,“technician“,“services“)
03 – marital: marital status (categorical: „married“,“divorced“,“single“; note: „divorced“ means divorced or widowed)
04 – education (categorical: „unknown“,“secondary“,“primary“,“tertiary“)
05 – default: has credit in default? (binary: „yes“,“no“)
06 – balance: average yearly balance, in euros (numeric)
07 – housing: has housing loan? (binary: „yes“,“no“)
08 – loan: has personal loan? (binary: „yes“,“no“) # related with the last contact of the current campaign:
09 – contact: contact communication type (categorical: „unknown“,“telephone“,“cellular“)
10 – day: last contact day of the month (numeric)
11 – month: last contact month of year (categorical: „jan“, „feb“, „mar“, …, „nov“, „dec“)
12 – duration: last contact duration, in seconds (numeric)
13 – campaign: number of contacts performed during this campaign and for this client (numeric, includes last contact)
14 – pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric, -1 means client was not previously contacted)
15 – previous: number of contacts performed before this campaign and for this client (numeric)
16 – poutcome: outcome of the previous marketing campaign (categorical: „unknown“,“other“,“failure“,“success“)
# success variable.
17 – y – has the client subscribed a term deposit? (binary: „yes“,“no“)

Im Bereich Machine Learning und Optimierung von Kampagnenplanung ist vor allem der Wert in Spalte 17 relevant: dieser gibt an, ob der beschriebene Kunde das Angebot der Bank angenommen hat.Im Bereich Machine Learning und Optimierung von Kampagnenplanung ist vor allem der Wert in Spalte 17 relevant: dieser gibt an, ob der beschriebene Kunde das Angebot der Bank angenommen hat.

Das Einlesen von Daten für die Big-Data-Analyse

Über

val bankText = sc.textFile(„/data/bank-full.csv“)

wird zunächst die CSV-Datei in das System eingelesen und steht als RDD zur Verfügung. Ein RDD (Resilient Distributed Dataset) ist dabei eine in Spark implementierte verteilte Datenstruktur, die über mehrere Rechner in einem Cluster (oder lokal auf mehrere Kerne) verteilt werden kann, um Berechnungen zu beschleunigen. In unserem Beispiel mit 40k Datensätzen ist dies zwar noch nicht relevant, aber der Charme von Spark ist, dass der gleiche Code auch benutzt werden kann, um viele Milliarden Datensätze zu analysieren. Somit kann aus Explorationscode recht einfach eine erste Version des Produktivcodes werden.

Anschließend definieren wir ein Objekt Bank zur Abbildung der Daten in Scala. Dieses Objekt typisiert Alter, Beruf, Familienstand, Ausbildung und Kontostand der Bankkunden:

case class Bank (age:Integer, job:String, marital:String, education:String, balance:Integer)

Wir haben aktuell also die Zeilen der CSV in einem RDD und eine Datenstruktur, in der diese abgelegt werden können. Nun folgt die Erstellung von Bank-Objekten durch das Umwandeln der Rohdaten , also das Parsen der CSV-Datei:

val bank = bankText.// Remove “ from source lines.map(s => s.replaceAll(„““, „“)).
// Transform line to single elements (which were separated with ;)map(s => s.split(„;“)).
// Remove first line. The first line starts with „age“.filter(s => s(0) != „age“).
// For each line, create a distinct object with the given fields.map(s => Bank(s(0).toInt,s(1),s(2),s(3),s(5).toInt))

RDDs enthalten verteilbare Daten, aber sagen wenig über diese aus. Als Ergänzung wurden in Spark deshalb so genannte Data Frames eingeführt. Data Frames, bekannt aus der Analyse-Sprache R, enthalten Meta-Informationen für tabellarische Informationen wie Spaltennamen und -typen. Als Vorbereitung auf die folgenden Schritte können wir die Daten einfach in ein Data Frame umwandeln:

val bankDF = bank.toDF()

Zur ersten Kontrolle geben wir die ersten zehn Einträge des Data Frames so aus:

bankDF.show(10)

Dies liefert uns folgendes Ergebnis:

+—+————+——–+———+——-+
|age| job| marital|education|balance|
+—+————+——–+———+——-+
| 58| management| married| tertiary| 2143|
| 44| technician| single|secondary| 29|
| 33|entrepreneur| married|secondary| 2|
| 47| blue-collar| married| unknown| 1506|
| 33| unknown| single| unknown| 1|
| 35| management| married| tertiary| 231|
| 28| management| single| tertiary| 447|
| 42|entrepreneur|divorced| tertiary| 2|
| 58| retired| married| primary| 121|
| 43| technician| single|secondary| 593|
+—+————+——–+———+——-+

Die Datensätze sind also scheinbar gut eingelesen.

Explorieren und Visualisieren

Gerade am Anfang ist eines der Primärziele ein „Gefühl für die Daten“ zu bekommen. Entsprechend sind Visualisierungen sehr hilfreich. Dazu registrieren wir zunächst das Data Frame als synthetische Tabelle über

bankDF.createOrReplaceTempView(„bank“)

Anschließend können SQL-Befehle auf der Tabelle bank ausgeführt werden. Uns interessiert z. B. die Verteilung des Alters:

%sqlselect age, count(1) from bank group by age order by age

Natürlich sind Einschränkungen möglich, z. B. auf alle Kunden unter 30 Jahre.

%sql
select age, count(1) from bank where age < 30 group by age order by age

Interaktive Dokumente sind ohne Programmierkenntnisse erstellbar- z. B. mit einem Drop-down zur Auswahl des Heiratsstatus der Kunden:

%sql
select age, count(1) from bank where marital="${marital=single,single|divorced|married}" group by age order by age

Weitere Features von Apache Zeppelin

Im Folgenden stellen wir drei von zahlreichen weiteren Zeppelin-Features vor, die aus unserer Sicht einen unmittelbaren Mehrwert für Ihr Unternehmen mit sich bringen.

Teilen von Analysen

Wenn ein Zeppelin-Server produktiv läuft und eine feste Server-Adresse hat, lassen sich Ergebnisse von Zeppelin-Dokumenten teilen, z. B. lässt sich die Altersstruktur als iframe in beliebige andere Webseiten einbinden und aktualisiert sich dann automatisch, wenn sich im Ursprungsdokument z. B. die Datenbasis ändert. Im folgenden Screenshot wurde die letzte Analyse über die im Browser dargestellte URL erreichbar gemacht und kann beliebig weiterverwendet werden. Die Sicherheit der Daten dann z.B. über vorgeschaltete Server-Authentifizierung, über Intranet-Firewall-Regeln oder Accounts.

Versionierung

In seiner aktuellen Version bietet Zeppelin automatisch Support für die oberflächengestütze Versionierung von Dokumenten:

Lokal werden dabei alle Notebooks in einem Git-Repository auf dem Server abgelegt: Entsprechend können wir zwischen Entwicklungsständen komfortabel hin- und herspringen. Mit Git-Bordmitteln sind außerdem lokal auch Aktionen wie Branches oder ein Backup in ein Remote-Repository etc. denkbar.

Lesbare Dokumentation

Programmcode allein ist oft nicht hilfreich. Besser ist es, wenn ergänzend weitere Dokumentation vorhanden ist. Empfehlenswert dafür ist beispielsweíse die Aufzweichnungssprache Markdown. Zeppelin bietet einen dedizierten Interpreter für den Markdown-Support, z. B. kann das erste Panel die oben beschrieben Bankdokumentation leserlich darstellen:

Fazit

Die Features und Funktionen von Zeppelin sind vielseitig, wir konnten hier nur einen ersten kleinen Einblick bieten. Durch die komfortablen Möglichkeiten, Analyse-Sprachen zu mischen und Ergebnisse zu visualisieren lassen sich nicht nur schnell ein Überblick über Daten gewinnen sondern auch wesentlich komplexere Analysen ausführen. Gleichzeitig ermöglicht die Verwendung von z. B. Spark und SparkSQL die produktive Transformation der gewonnenen Erkenntnisse in Programmcode, der fernab der rein explorativen Datenanalyse eingesetzt werden kann. Diese Mächtigkeit wird in einer komfortabel zu bedienenden Oberfläche versteckt, so dass auch nicht-Experten explorativ mit ihren Daten umgehen können.