Herzlich willkommen auf dem Blog der exensio GmbH

exensio ist ein unabhängiges Software-Unternehmen von erfahrenen IT Beratern und Architekten. Zu unseren Kunden zählen namhafte deutsche Großunternehmen.

exensio verbessert das Kommunikations- und Informationsmanagement von Unternehmen. Auf Basis sinnvoller und zweckmäßiger Technologien erarbeiten wir flexible und übergreifende Lösungen für webbasierte Informationssysteme. Abhängig von den Kundenanforderungen realisieren wir Web Applikationen sowie Lösungen auf Basis von Web Content Management- und Portalsystemen. Integrativ, wirtschaftlich und anwenderfreundlich!

Hier gelangen Sie zur exensio GmbH.

Montag, 15. Dezember 2014

Eindrücke von der GGX in London

Vom 11. bis 12.12. konnte ich an der Groovy & Grails Exchange in London teilnehmen. Im Vergleich zum Jahr 2012 hatte das Programm weniger Besucher angezogen und bei den Keynotes blieben einige Stühle leer. Dies hatte aber nichts mit der Qualität des Programm zu tun. Es waren fast alle Core-Entwickler von Groovy und Grails mit Vorträgen präsent.

Den Reigen eröffnete Guillaume Laforge, der die aktuelle Groovy Version vorstellte und auf die Roadmap für die Zukunft einging. Neben Anpassungen für Java8 sind in der Version 2.3 vor allen Dingen die Themen Traits sowie die schnelle Implementierung des JSON-Parsers erwähnenswert.

Anschließend gab es über den Tag verteilt zwei parallele Session mit verschiedenen Themengebieten. Besonders interessant fand ich den Vortrag von Geb-Lead Marcin Erdmann über das Betreuen von Open-Source-Projekten. Er zeigte auf, dass ein erfolgreiches Open-Source-Projekt viel mehr erfordert wie das reine Programmieren. Die Details können im aufgezeichneten Video entnommen werden.

Bei der Panel-Diskussion am Ende des ersten Tages stellten sich die Kern-Entwickler den Fragen des Plenums. Es wurde unter anderem darüber diskutiert, warum die Frameworks Geb und Spock noch nicht in der Version 1.0 vorliegen. Beide Frameworks sind seit Jahren stabil und können nach mehrheitlicher Meinung schon längst im Status eines Major-Releases sein. Dieser psychologische Schritt würde einen zusätzlichen Schub für Groovy und die Frameworks selbst bedeuten, da damit auch der Einsatz in Unternehmen einfacher zu vertreten sein wird. Wir dürfen gespannt sein, ob sich in den nächsten zwei Monaten hierzu etwas tut.

Der zweite Tag wurde von Graeme Rocher mit seiner Keynote zu Grails 3.0 eröffnet. Vermutlich schon im Januar 2015 wird der erste Meilenstein verfügbar sein. Das neue Grails-Release wird eng mit Springboot verzahnt sein und damit auch die dort verfügbaren Features einfach einbinden können. Eine weitere große Umstellung wird das Build-System sein, das zukünftig auf Gradle basieren wird. Damit dürfte eine Integration mit Entwicklungsumgebungen deutlich einfacher sein.

Ein weiteres Highlight am zweiten Tag war das testgetriebene Vorgehen beim Entwicklen einer Springboot-Applikation mit dem Einsatz des Test-Frameworks Cucumber. Hierbei wurde innerhalb von 45 Minuten eine kleine auf Springboot basierende Anwendung entwickelt.

Ich konnte während der zwei Tage in London wieder einige noch nicht bekannte Dinge aus dem Groovy-Öko-System aufschnappen, die sich in dem ein oder anderen Projekt sinnvoll einsetzen lassen werden.

Montag, 24. November 2014

Präparate Datenbank erzeugt IFA Preismeldungen

Quelle: IFA GmbH
exensio hat für einen namhaften Pharmahersteller eine Software Lösung zur Verwaltung von vertrieblichen und medizinischen Daten seiner Präparate umgesetzt. Diese Präparate-Datenbank (PIM System), die schon seit mehreren Jahren erfolgreich in Betrieb ist, wurde dieses Jahr um den IFA Preismelde- Workflow erweitert.

Die IFA (Informationsstelle für Arzneispezialitäten) erhebt und pflegt Information zu Arzneimitteln und apothekenüblichen Waren. Sie vergibt dabei die sogenannten PZN (Pharmazentralnummer), die einen Artikel eindeutig kennzeichnet. Hersteller können die Neuaufnahme sowie Änderungen der Daten an die IFA mitteilen. Hierfür existiert ein Verfahren basierend auf sogenannten EAD Dateien, die zur IFA geschickt und dort verarbeitet werden. Zurück kommt eine Bestätigung ggf. mit Korrekturen.

Preisänderungen  sind insbesondere für Generika Anbieter kritisch, da sie für den Absatz ein sehr entscheidendes Kriterium sind. Ein stabiler Workflow zur Durchführung und Übertragung der Preisänderungen ist daher erfolgskritisch.

Die Präparate-Datenbank von exensio ist nun in der Lage, basierend auf Preisanpassungen aus SAP, die durch einen SOX konformen Prozess freigegeben wurden, entsprechende IFA Meldungen automatisch zu erzeugen. Die von der IFA vorgegebenen EAD Dateien werden pro Firma des Konzerns automatisch erzeugt und rechtzeitig vor Ablauf der Einreichungsfrist an die IFA per Email verschickt.

Die IFA wiederum schickt eine Bestätigungs-Email mit Datei als Anhang zurück. Die Datei wird automatisiert in der Präparate Datenbank eingelesen und die Daten werden mit den an die IFA gesendeten Werten abgeglichen. Bei Übereinstimmung werden die geänderten Preise als von der IFA bestätigt übernommen. Bei Abweichungen werden entsprechende Warnmeldungen und Alerts erzeugt, um Folgeaktivitäten auszulösen. Alle Informationen werden an SAP zurückgespielt, um dort den fachlichen Workflow schließen zu können.

Fazit

Mit der Automatisierung gewinnt der komplette Ablauf eine hohe Sicherheit. Manuelle Schritte und damit potentielle Fehlerquellen entfallen. Die Präparate-Datenbank als Lieferant hochwertiger produktbezogener Informationen für alle Informations-Kanäle liefert damit garantiert korrekte Preisinformationen – ob in geschlossene Bereiche im Internet oder andere Intranet-Systeme.

Donnerstag, 13. November 2014

Datenanalyse mit R

Ziel dieses Blogposts ist es, an einem Beispiel zu zeigen, dass es möglich ist, aus der Programmiersprache R auf die in Elasticsearch gespeicherten Daten zuzugreifen, diese zu verarbeiten und die Ergebnisse für eine Java-Anwendung zugreifbar zu machen. Hierfür wird auf die durch Sensoren erfassten Wetterdaten zugegriffen, die bereits in diesem Blog vorgestellt.

Was ist R?

R beschreibt sich selbst als "a free software environment for statistical computing and graphics" [1]. Es bietet die Möglichkeit, Probleme aus Bereichen wie Statistik und Data Mining schnell zu lösen oder Prototypen zu bauen. R ist jedoch nicht für jedes Problem in diesen Bereichen eine gute Wahl [2]. Unsere Erfahrung mit den Wetterdaten bestätigt diese Einschätzung. Als interpretierte Sprache ist R auch nicht besonders schnell - abgesehen von den eingebauten Vektor/Matrixoperationen(hinter denen BLAS/LAPACK o.ä. steht). Um dieses Problem zu umgehen, enthalten viele R-Pakete C, C++ oder Fortran-Code, in den die rechenintensiven Operationen ausgelagert sind. Beispielsweise hat R Probleme, wenn nicht alle Daten gleichzeitig in den RAM geladen werden können.
Für die prototypische Anwendung soll der Temperaturverlauf in einem Raum für den nächsten Tag vorhergesagt werden. Es wurde hierfür der Serverraum ausgewählt.

Zugriff auf Elasticsearch

Der Zugriff auf Elasticsearch erfolgt über die REST-Schnittstelle. Um aus R HTTP-Requests senden zu können, wird das Paket RCurl verwendet. RCurl ist ein Wrapper um libcurl. Um den Response, der als JSON vorliegt, in R-Objekte zu parsen, wird das Paket RJSONIO verwendet. Das Paket jsonlite, das den selben Zweck erfüllt und besser aufgebaute R-Objekte liefert, wird nicht verwendet, da es sich als wesentlich langsamer erwiesen hat (selbst wenn man die Ausgaben von RJSONIO nachträglich umformatiert) und daher für die vorliegende Datenmenge nicht geeignet ist.
Will man R professionell an Elasticsearch anbinden, könnte es sich lohnen, aus libcurl und einem geeigneten JSON-Parser einen Client zu bauen, um das Parsen von JSON und Abbilden in R-Objekte gezielt auf Elasticsearch zu optimieren. Anhand der Abfrage weiß man im Wesentlichen, wie das zurückgegebene JSON aufgebaut ist. Da dies mit größerem Aufwand verbunden ist, wurde für die hier beschriebenen Experimente darauf verzichtet.
Nachfolgend ist die an Elasticsearch gesendete Aggregations-Query und ihre Verarbeitung dargestellt.
device <- "ex-raspberrypi-01"
type <- "indoor"
request <- paste('{
                 "query": {
                  "bool": {
                   "must": [
                    {
                     "term": { 
                      "device": "', device, '"
                     }
                    }, 
                    {"term": {"type": "', type, '"} },
                    { 
                     "range": {
                      "created" : {
                       "gte": "2014-01-01T11:00:00",
                       "lte": "2015-01-01T12:00:00"
                      }
                     }
                    },
                    { 
                     "range": {
                      "temperature": {
                       "gte": 10.0,
                       "lte": 35.0
                      }
                     }
                    }
                   ]
                  }
                 },
                 "aggs": {
                  "device_count": {
                   "terms": {
                    "field":"device"
                   },
                   "aggs": {
                    "splitminute": {
                     "date_histogram":{
                      "field":"created",
                      "interval":"hour"
                     },
                     "aggs": {
                      "avg_degrees": {
                       "avg":{
                        "field":"temperature"
                       }
                      }
                     }
                    }
                   }       
                  }
                 },
                 "from" : 0,
                 "size":1 
                }', sep='')
headers <- list('Accept' = 'application/json', 'Content-Type' = 'application/json')

h <- basicTextGatherer()

response <- curlPerform(url="http://exensiosearch02:9201/sensorraspberry/_search?pretty", postfields=request, 
                        writefunction = h$update,httpheader=headers, curl = curlhandle)
x <- h$value()

# x ist jetzt eine Zeichenkette mit der Antwort (json) - muss geparst werden.
y <- fromJSON(x)

# y besser struktieren / als data.frame zurückgeben.
data <- y$aggregations$device_count[[1]]
data <- data[[1]]$splitminute$buckets

temp <- numeric(length(data))
time <- numeric(length(data))
for(i in 1:length(data)) {
  temp[i] <- data[[i]]$avg_degrees
  time[i] <- data[[i]]$key
}
rawInput <- data.frame(created=time,  temperature=temp)
Zur Vorhersage wird ein zweischichtiges künstliches neuronales Netz verwendet. Eingaben sind die mittlere Temperatur jeder der letzten 10 Stunden und die Tageszeit/Stunde, für die vorhergesagt werden soll. Ausgeben wird die prognostizierte Temperatur für die nächste Stunde. Um beispielsweise den Temperaturverlauf über einen gesamten Tag vorzusagen, wird die Vorhersage selbst als Input verwendet, damit die Temperatur in der nachfolgenden Stunde vorhergesagt wird. Zur Erzielung besserer Ergebnisse werden die Eingabedaten geeignet skaliert.
Zum Training des neuronalen Netzes wird das Paket nnet und die Daten bis zum 1. September 2014 verwendet. Die Daten seit dem 1. September dienen zur Evaluation. Die untenstehende Abbildung zeigt die tatsächliche (rot) und die vorhergesagte Temperatur (blau) . Die Vorhersage wurde jeweils um Mitternacht auf Basis der am vergangenen Tag beobachteten Daten für den gesamten Tag erstellt. Es zeigt sich, dass die Vorhersage im letzen Drittel des Oktobers abrupt wesentlich schlechter wird. Dies liegt vermutlich an der Änderung des Standorts des Sensors im Serverraum. Vor der Umpositionierung stand der Sensor in der Nähe eines verfälschenden Abluftstrom eines Gerätes. Für diese neue Situation wurde das neuronale Netz nicht trainiert.

Ergebnisse

Es hat sich gezeigt, dass der Parameter maxit, der die Anzahl der Iterationen während des Trainings begrenzt, große Bedeutung hat: Wird maxit zu groß gewählt, neigt das Netz zu starkem overfitting, d.h. der Fehler auf den Trainingsdaten ist zwar sehr klein, aber die Vorhersagen auf dem Evaluationsdatensatz sind schlecht. Der mittlere Fehler auf den Evaluationsdaten (d.h. ab dem 1. September) beträgt 0.81 Grad Celsius.

Vorhersage aus Java abrufen

Eine Möglichkeit R von Java aus aufzurufen ist rServe. Dieses Paket ermöglicht es, R als Server zu betreiben und mittels eines Java-Clients anzusprechen. Will man R nicht als Server betreiben, sondern direkt einbinden, bietet sich alternativ RNI an. Mit rServe sieht der Java-Code wie folgt aus:
RConnection c = new RConnection();
// R-Skript einlesen und ausführen:
// - Trainingsdaten aus elasticsearch abfragen und in Variable "rawInput" speichern.
// - diverse Hilfsfunktionen zum Trainieren des neuronalen Netzes ("trainNet"), 
//    Erstellen der Prognose ("getPrognose") etc. definieren.
c.voidEval("source('.../setupPrediction.R')");
// Neuronales Netz trainieren und der Variable "knn" zuweisen.
c.voidEval("knn <- trainNet(rawInput=rawInput)");
//Das sind die mittleren Temperaturen der letzten 10 Stunden
// werden als Input für Prognose benötigt.
double[] lastTemperatures = new double[]{26.63763, 26.60047, 26.62897, 26.63891, 26.58628, 
                                         26.55079, 26.44443, 26.52929, 26.48949, 26.37};
// Werte aus Java nach R kopieren und in Variable "lastvalues" speichern.
c.assign("lastvalues", lastTemperatures);
// Temperaturprognose berechnen
// Da KNN auf skalierten Werten arbeitet, muss man Input skalieren ("scaleServerTemp") 
//  und Ergebnis zurückskalieren ("rescaleServerTemp")
REXP x = c.eval("rescaleServerTemp(getPrognose(knn, scaleServerTemp(rev(lastvalues)), 0))");
// Werte aus R wieder in Java kopieren und ausgeben.
double[] result = x.asDoubles(); 
for(int hour = 0; hour < 24; hour++) {
  System.out.println("" + hour + ":00 - " + (hour+1) + ":00 : Vorhersage: " + result[hour]);
}
Die Ausgabe sieht dann folgendermaßen aus:
0:00 - 1:00 : Vorhersage: 26.313316185020042
1:00 - 2:00 : Vorhersage: 26.275947152882623
2:00 - 3:00 : Vorhersage: 26.251989278387292
3:00 - 4:00 : Vorhersage: 26.246811159392138
4:00 - 5:00 : Vorhersage: 26.25657048628711
5:00 - 6:00 : Vorhersage: 26.279495173271123
6:00 - 7:00 : Vorhersage: 26.297577826042687
7:00 - 8:00 : Vorhersage: 26.326254511775634
8:00 - 9:00 : Vorhersage: 26.364349490351472
9:00 - 10:00 : Vorhersage: 26.39934045980503
10:00 - 11:00 : Vorhersage: 26.431707850819965
11:00 - 12:00 : Vorhersage: 26.461165964549796
12:00 - 13:00 : Vorhersage: 26.48547429218186
13:00 - 14:00 : Vorhersage: 26.503398807877936
14:00 - 15:00 : Vorhersage: 26.51429011947722
15:00 - 16:00 : Vorhersage: 26.518425475695256
16:00 - 17:00 : Vorhersage: 26.51439402371549
17:00 - 18:00 : Vorhersage: 26.501447900578995
18:00 - 19:00 : Vorhersage: 26.479813409022864
19:00 - 20:00 : Vorhersage: 26.44911167010077
20:00 - 21:00 : Vorhersage: 26.40898653790765
21:00 - 22:00 : Vorhersage: 26.35936238134047
22:00 - 23:00 : Vorhersage: 26.300194063174178
23:00 - 24:00 : Vorhersage: 26.231449480426715

Fazit

Die entwickelte Prognosefunktionalität ist sicher noch verbesserungsfähig, vor allem was die Eingaben in das neuronale Netz angeht. Es ist etwa anzunehmen, dass die Außentemperatur zumindest im Sommer einen Einfluss auf die Innentemperatur hat. Dies war jedoch nicht das Hauptziel: Es konnte gezeigt werden, dass R, Elasticsearch und Java-Anwendungen kombiniert werden können und wie man dabei vorgehen kann.

Links

[1] R-Project
[2] Joseph Adler: R In a Nutshell. Second Edition. O'Reilly. 2012

Freitag, 17. Oktober 2014

Elasticsearch und IoT

Beim Search Meetup Karlsruhe mit dem Thema "Elasticsearch Performance in a Nutshell" durfte ich neben dem Hauptvortrag von Patrick Peschlow Anwendungsszenarien zu "Elasticsearch und IoT" vorstellen.



Weitere Detail-Informationen können in der Blogpost-Reihe "Szenarien für den Einsatz von IoT und BigData" gefunden werden:

Mittwoch, 15. Oktober 2014

Big Data Expertenrunde bei Dr. Hornecker in Freiburg

Letzten Mittwoch hatte ich die Gelegenheit, bei Dr. Hornecker Software-Entwicklung und IT-Dienstleistungen über Elasticsearch im Kontext von Big Data zu referieren.

Hierbei habe ich die Vorteile von Elasticsearch und NoSQL aufgezeigt. In diesem Zusammenhang möchte ich darauf hinweisen, dass man bereits mit kleinen (strukturierten bzw. unstrukturierten) Datenmengen sinnvolle Anwendungen realisieren kann, die mit der gealterten SQL-Technologie nicht so einfach - wenn überhaupt - umsetzbar sind.



Des Weiteren habe ich folgende Einsatzszenarien für Elasticsearch skizziert:

  • NoSQL Document Store (JSON)
    • Bigdata mittels Sharding
    • Keine Transkationen im Vergleich zu MongoDB
  • Query Engine für strukturierte Daten
    • Daten werden in SQL DB gespeichert
    • Abfragen laufen über Elasticsearch
    • Vereinfachung von komplexen SQL Queries (insb. bei hierarchischen Abfragen)
  • Volltextsuche bzw. Facettierte Suche 
    • Wissensportale
    • Suche in strukturierten (Datenbanken, CRM, ERP, …) sowie unstrukturierten Daten (Content, Dokumente)
  • Geo-Suche (viel einfacher als bei Oracle DB)
    • PLZ-Umkreissuche (Filialen)
    • Flottenmanagement
    • Logistik
  • Logfile-Analyse
    • IT-Forensik
    • Sortimentslücken entdecken
  • Business Analytics (schneller und kostengünstiger vgl. mit DW)
    • Competitive Intelligence (Search Engine sehr gut geeignet, wenn Mapping über eindeutige Id wie EAN Code nicht möglich)
    • Datawarehouse (Aggregationen ersetzen Dimensionen im Star-Schema)
  • Alerts (Percolator -> indiziertes Dokument passt zu gespeicherter Query)
    • News Alerts
    • Internet Of Things (Alarm bspw. Temperatur steigt über Schwellwert)
    • Preis-Monitor
    • Online-Werbung 
Die weiteren Vorträge kamen von Dr. Michael Jachan (Brain Products) über die Grundlagen maschinellen Lernens. Und Dr. Achim Hornecker ergänzte die Runde mit dem dritten Vortrag. Er skizzierte die Entwicklung, die sich in den vergangenen Monaten ausgehend von Hadoop hin zur interaktiven Verarbeitung von großen Datenmengen bis zu Echtzeitanwendungen getan hat.

Weitere Infos auf der Homepage von Dr. Hornecker.

Dienstag, 7. Oktober 2014

Competitive Intelligence mit Elasticsearch und Kapow

In diesem Blog-Post möchte ich über ein interessantes Vorhaben - in das wir aktuell mit einer Machbarkeitsstudie involviert sind - eines bekannten deutschen Handelskonzerns berichten. In aller Kürze: Es handelt sich um die Analyse von Online-Webshops des Wettbewerbs. Ich habe - auch weil ich gerne Wein trinke :-) - für den Blog-Post als Beispiel die Konkurrenz-Beobachtung von Online-Wein-Händlern herangezogen.

Für dieses Szenario  gilt, dass die zu vergleichenden Produkte nicht über einen eindeutigen Kenner, wie bspw. den Barcode (EAN / GTIN) verglichen werden können. Dies ist der Grund, dass das Matching über eine Suchmaschine erfolgt. Das Fehlen eines unverkennbaren Identifikators wie bei Wein ist auch bei Tee oder Kaffee gegeben. Die Betrachtung von elektronischen Geräten kann hingegen fast ausschließlich mittels EAN-Code erfolgen.



Was ist Competitive Intelligence genau genommen?

In Wikipedia findet sich eine besonders brauchbare Erklärung hierfür. Bedeutsam ist hierbei die Abgrenzung von Competitive Intelligence (CI) zu Business Intelligence (BI) inklusive des Vergleichs von strukturierten (BI) zu unstrukturierten Informationen (CI). Für die Speicherung von unstrukturierten Daten bietet sich hier vorzüglich NoSQL bzw. Elasticsearch [1] - wie in unserem Fall - an.

Auszug aus Wikipedia-Artikel [2]:
»Die Begriffe Competitive Intelligence und Business Intelligence sind zwei unterschiedliche Ansätze, die sich ergänzen. Während Competitive Intelligence überwiegend Daten über Unternehmen analysiert, die außerhalb eines Unternehmens zu finden sind, befasst sich Business Intelligence fast ausschließlich mit der Auswertung firmeninterner Daten. Competitive Intelligence nutzt auch die internen Daten eines Unternehmens, wie etwa Zahlen aus dem Jahresabschluss, die der breiten Öffentlichkeit zur Verfügung gestellt werden. Es bedient sich jedoch überwiegend der unstrukturierten Daten aus dem Internet, oder anderer öffentlicher Informationsquellen. Business Intelligence wiederum basiert fast ausschließlich auf Zahlen aus dem Unternehmen und weniger auf unstrukturierten Daten. Es gibt Bestrebungen auch hier mehr Daten von außerhalb des Unternehmens einzubinden und durch die Einbettung von unstrukturierten Daten, sei es aus dem Unternehmen, oder von außerhalb des Unternehmens, den Zahlen einen Kontext zu verschaffen, kausale Erklärungen für bestimmte Kennzahlen anzubieten.«

Web-Crawling mit Kapow

Es gibt unzählige Tools, die für das Web-Crawling benutzt werden können. Kapow [3] besticht hier vor
allem mit seiner intuitiven Oberfläche, die mit einer kurzen Einarbeitungszeit rasch - für die Umsetzung von Robots - angewendet werden kann. Zusätzlich unterstützt Kapow, im Vergleich zu alternativen Produkten, besonders effektiv JavaScript. Dies ist existentiell, da heutzutage fast jede Web-Seite JavaScript verwendet. Die Workflow-Eigenschaften von Kapow sollten nicht unerwähnt bleiben. Von Projekt zu Projekt muss dann entschieden werden, ob Kapow auch im Bereich Workflow einsetzbar ist. Ein weiterer bedeutender Punkt ist die Normalisierung der Daten. So heißt es „Weißwein“ in einem Shop und in einem anderen „Weisswein“. Mit Kapow ist es – vergleichbar mit einem ETL-Tool von einem Data-Warehouse – machbar, die Daten über die einzelnen Shops hinweg zu normalisieren. Als zusätzliches Beispiel könnte man die Vereinheitlichung von Bewertungen aufführen, die in einem Shop mit 5 Sternen und in einem anderen mit Prozentzahlen angegeben werden.

Warum eine Suchmaschine - wie Elasticsearch - verwenden?

Für den Vergleich von Preisen über unterschiedliche Shops hinweg ist eine eindeutige Kennung notwendig. Hierzu wird bspw. der EAN / GTIN Code benutzt. Die einzelnen Wein-Shops benutzen in unserem Fall allerdings proprietäre Kundennummern. Unter Zuhilfenahme einer Suchmaschine ist es jedoch machbar, die Artikel anhand ihres Artikelnamens - der während der Indizierung eine Trennung der Wörter durchführt - zu finden. Des Weiteren bietet eine Suchmaschine die Möglichkeit, eine Facettierte Suche – wie von Amazon bekannt – bereitzustellen. Eine Facettierte Suche mit blankem SQL aufzubauen ist ein äußerst aufwändiges Unterfangen, da SQL nicht für hierarchische Abfragen entwickelt wurde. Zusätzlich kann eine Suchmaschine wie Elasticsearch auch ausgesprochen umfangreiche Datenmengen (Big Data) verwalten. Auch sollte hierbei nicht vergessen werden, dass dieser Lösungsansatz das Projektbudget im Vergleich zu einer reinen Business-Intelligence-Lösung weniger belastet.

Facettierte Suche

Im nebenstehnden Bild sieht man auf der linken Seite die facettierte Suche. Mit dieser besteht die Möglichkeit
Weine auf Shop-Ebene, Kategorie, Herkunftsland, Anbauregion, Winzer, Preise usw. zu filtern. Zusätzlich ist es denkbar, eine Volltext-Suche bzw. eine Fuzzy-Suche abzusetzen. Mit der Fuzzy-Suche kann man Informationen zu Weinen zu finden, bei denen bspw. der Weinname oder das Weingut falsch geschrieben wurden.

Analysen

Es können verschiedene Analysen durchgeführt werden. Das Beispiel rechts zeigt die Möglichkeit, ein Weingut zu suchen, um zu sehen, bei welchen weiteren Shops dieses zu finden ist. Es werden auch die Weine angezeigt, die ein Shop von einem Weingut führt. Dies kann bspw. interessant sein, wenn ein frischer Katalog geplant wird und man
nicht dieselben Weingüter wie die Konkurrenz führen möchte.

Das Bild rechts veranschaulicht, wie eine grafische Auswertung aussehen könnte. Hierbei wird der prozentuale Anteil von Weinen, die ein
Shop pro Land führt, angezeigt. Diese Grafiken könnten auch für weitere Informationen, wie Visualisierung von Preisspannen etc. dienen. In unserm Fall lässt der Screenshot erkennen, dass  dass bspw. ein Shop (grüner Balken) die meisten deutschen Weine führt. Ein anderer hingegen auf Weine aus Frankreich und Italien führt.

Preisvergleich

Wie oben erwähnt können wir die Preise der unterschiedlichen Shops nicht mit einem eindeutigen Kenner, wie den Barcode (EAN - Code) identifizieren. Hier kommt Elasticsearch ins Spiel. Über ein Groovy-Script werden alle Weine des Ausgangs-Shops mit denen des Wettbewerbs verglichen. Die Ergebnisse dienen zum Aufbau des Preisvergleichs-Index. Des Weiteren haben wir noch das Scoring getuned, z.B. Preise, die um mehr als 50% divergieren, werden ans Ende der Liste gestellt. Schaut man sich das Ergebnis an, so erhält man ein valides Matching von ca. 80% an Weinen, die beim Mitbewerb günstiger bzw. teurer sind. 100% sind nicht zu erreichen, da wir in unserem Fall keinen eindeutigen Kenner haben.

Fazit

Für die Begutachtung werden die Inhalte der Konkurrenz-Web-Seiten in eine Datenbank geladen und im selben Schritt gleichzeitig bereinigt. Für die Analyse wird eine Suchmaschine benutzt, die das Problem eines über alle Web-Shops nicht vorhanden EAN (Barcodes) löst.
Für die Analyse stehen vielfältige Möglichkeiten zur Verfügung:
  • Facettierte Filterung (analog zu Amazon) und Volltextsuche
  • Analysen der Weingüter, Preisspannen, Preisvergleich, Sortimentsverteilung, etc. eines Shops im Vergleich zum Wettbewerb
  • Graphische Darstellungen, bspw. Verteilung der Länder des Sortiments auf die einzelnen Web-Shops, etc.
Neben Elasticsearch wurde für das Analysefrontend Twitter-Bootstrap und AngularJS verwendet.

Links:

[1] http://www.elasticsearch.org http://www.elasticsearch.com
[2] http://de.wikipedia.org/wiki/Competitive_Intelligence
[3] http://www.kapowsoftware.com/de/