Sentiment Analysis using Python

One of the applications of text mining is sentiment analysis. Most of the data is getting generated in textual format and in the past few years, people are talking more about NLP. Improvement is a continuous process and many product based companies leverage these text mining techniques to examine the sentiments of the customers to find about what they can improve in the product. This information also helps them to understand the trend and demand of the end user which results in Customer satisfaction.

As text mining is a vast concept, the article is divided into two subchapters. The main focus of this article will be calculating two scores: sentiment polarity and subjectivity using python. The range of polarity is from -1 to 1(negative to positive) and will tell us if the text contains positive or negative feedback. Most companies prefer to stop their analysis here but in our second article, we will try to extend our analysis by creating some labels out of these scores. Finally, a multi-label multi-class classifier can be trained to predict future reviews.

Without any delay let’s deep dive into the code and mine some knowledge from textual data.

There are a few NLP libraries existing in Python such as Spacy, NLTK, gensim, TextBlob, etc. For this particular article, we will be using NLTK for pre-processing and TextBlob to calculate sentiment polarity and subjectivity.

The dataset is available here for download and we will be using pandas read_csv function to import the dataset. I would like to share an additional information here which I came to know about recently. Those who have already used python and pandas before they probably know that read_csv is by far one of the most used function. However, it can take a while to upload a big file. Some folks from  RISELab at UC Berkeley created Modin or Pandas on Ray which is a library that speeds up this process by changing a single line of code.

After importing the dataset it is recommended to understand it first and study the structure of the dataset. At this point we are interested to know how many columns are there and what are these columns so I am going to check the shape of the data frame and go through each column name to see if we need them or not.

 

There are so many columns which are not useful for our sentiment analysis and it’s better to remove these columns. There are many ways to do that: either just select the columns which you want to keep or select the columns you want to remove and then use the drop function to remove it from the data frame. I prefer the second option as it allows me to look at each column one more time so I don’t miss any important variable for the analysis.

Now let’s dive deep into the data and try to mine some knowledge from the remaining columns. The first step we would want to follow here is just to look at the distribution of the variables and try to make some notes. First, let’s look at the distribution of the ratings.

Graphs are powerful and at this point, just by looking at the above bar graph we can conclude that most people are somehow satisfied with the products offered at Amazon. The reason I am saying ‘at’ Amazon is because it is just a platform where anyone can sell their products and the user are giving ratings to the product and not to Amazon. However, if the user is satisfied with the products it also means that Amazon has a lower return rate and lower fraud case (from seller side). The job of a Data Scientist relies not only on how good a model is but also on how useful it is for the business and that’s why these business insights are really important.

Data pre-processing for textual variables

Lowercasing

Before we move forward to calculate the sentiment scores for each review it is important to pre-process the textual data. Lowercasing helps in the process of normalization which is an important step to keep the words in a uniform manner (Welbers, et al., 2017, pp. 245-265).

Special characters

Special characters are non-alphabetic and non-numeric values such as {!,@#$%^ *()~;:/<>\|+_-[]?}. Dealing with numbers is straightforward but special characters can be sometimes tricky. During tokenization, special characters create their own tokens and again not helpful for any algorithm, likewise, numbers.

Stopwords

Stop-words being most commonly used in the English language; however, these words have no predictive power in reality. Words such as I, me, myself, he, she, they, our, mine, you, yours etc.

Stemming

Stemming algorithm is very useful in the field of text mining and helps to gain relevant information as it reduces all words with the same roots to a common form by removing suffixes such as -action, ing, -es and -ses. However, there can be problematic where there are spelling errors.

This step is extremely useful for pre-processing textual data but it also depends on your goal. Here our goal is to calculate sentiment scores and if you look closely to the above code words like ‘inexpensive’ and ‘thrilled’ became ‘inexpens’ and ‘thrill’ after applying this technique. This will help us in text classification to deal with the curse of dimensionality but to calculate the sentiment score this process is not useful.

Sentiment Score

It is now time to calculate sentiment scores of each review and check how these scores look like.

As it can be observed there are two scores: the first score is sentiment polarity which tells if the sentiment is positive or negative and the second score is subjectivity score to tell how subjective is the text. The whole code is available here.

In my next article, we will extend this analysis by creating labels based on these scores and finally we will train a classification model.

Dem Wettbewerb voraus mit Künstlicher Intelligenz

Was KI schon heute kann und was bis 2020 auf deutsche Unternehmen zukommt

Künstliche Intelligenz ist für die Menschheit wichtiger als die Erfindung von Elektrizität oder die Beherrschung des Feuers – davon sind der Google-CEO Sundar Pichai und viele weitere Experten überzeugt. Doch was steckt wirklich dahinter? Welche Anwendungsfälle funktionieren schon heute? Und was kommt bis 2020 auf deutsche Unternehmen zu?

Big Data war das Buzzword der vergangenen Jahre und war – trotz mittlerweile etablierter Tools wie SAP Hana, Hadoop und weitere – betriebswirtschaftlich zum Scheitern verurteilt. Denn Big Data ist ein passiver Begriff und löst keinesfalls alltägliche Probleme in den Unternehmen.

Dabei wird völlig verkannt, dass Big Data die Vorstufe für den eigentlichen Problemlöser ist, der gemeinhin als Künstliche Intelligenz (KI) bezeichnet wird. KI ist ein Buzzword, dessen langfristiger Erfolg und Aktivismus selbst von skeptischen Experten nicht infrage gestellt wird. Daten-Ingenieure sprechen im Kontext von KI hier aktuell bevorzugt von Deep Learning; wissenschaftlich betrachtet ein Teilgebiet der KI.

Was KI schon heute kann

Deep Learning Algorithmen laufen bereits heute in Nischen-Anwendungen produktiv, beispielsweise im Bereich der Chatbots oder bei der Suche nach Informationen. Sie übernehmen ferner das Rating für die Kreditwürdigkeit und sperren Finanzkonten, wenn sie erlernte Betrugsmuster erkennen. Im Handel findet Deep Learning bereits die optimalen Einkaufsparameter sowie den besten Verkaufspreis.

Getrieben wird Deep Learning insbesondere durch prestigeträchtige Vorhaben wie das autonome Fahren, dabei werden die vielfältigen Anwendungen im Geschäftsbereich oft vergessen.

Die Grenzen von Deep Learning

Und Big Data ist das Futter für Deep Learning. Daraus resultiert auch die Grenze des Möglichen, denn für strategische Entscheidungen eignet sich KI bestenfalls für das Vorbereitung einer Datengrundlage, aus denen menschliche Entscheider eine Strategie entwickeln. KI wird zumindest in dieser Dekade nur auf operativer Ebene Entscheidungen treffen können, insbesondere in der Disposition, Instandhaltung, Logistik und im Handel auch im Vertrieb – anfänglich jeweils vor allem als Assistenzsystem für die Menschen.

Genau wie das autonome Fahren mit Assistenzsystemen beginnt, wird auch im Unternehmen immer mehr die KI das Steuer übernehmen.

Was sich hinsichtlich KI bis 2020 tun wird

Derzeit stehen wir erst am Anfang der Möglichkeiten, die Künstliche Intelligenz uns bietet. Das Markt-Wachstum für KI-Systeme und auch die Anwendungen erfolgt exponentiell. Entsprechend wird sich auch die Arbeitsweise für KI-Entwickler ändern müssen. Mit etablierten Deep Learning Frameworks, die mehrheitlich aus dem Silicon Valley stammen, zeichnet sich der Trend ab, der für die Zukunft noch weiter professionalisiert werden wird: KI-Frameworks werden Enterprise-fähig und Distributionen dieser Plattformen werden es ermöglichen, dass KI-Anwendungen als universelle Kernintelligenz für das operative Geschäft für fast alle Unternehmen binnen weniger Monate implementierbar sein werden.

Wir können bis 2020 also mit einer Alexa oder Cortana für das Unternehmen rechnen, die Unternehmensprozesse optimiert, Risiken berichtet und alle alltäglichen Fragen des Geschäftsführers beantwortet – in menschlich-verbal formulierten Sätzen.

Der Einsatz von Künstlicher Intelligenz zur Auswertung von Geschäfts- oder Maschinendaten ist auch das Leit-Thema der zweitägigen Data Leader Days 2018 in Berlin. Am 14. November 2018 sprechen renommierte Data Leader über Anwendungsfälle, Erfolge und Chancen mit Geschäfts- und Finanzdaten. Der 15. November 2018 konzentriert sich auf Automotive- und Maschinendaten mit hochrangigen Anwendern aus der produzierenden Industrie und der Automobilzuliefererindustrie. Seien Sie dabei und nutzen Sie die Chance, sich mit führenden KI-Anwendern auszutauschen.

Einstieg in Natural Language Processing – Teil 2: Preprocessing von Rohtext mit Python

Dies ist der zweite Artikel der Artikelserie Einstieg in Natural Language Processing.

In diesem Artikel wird das so genannte Preprocessing von Texten behandelt, also Schritte die im Bereich des NLP in der Regel vor eigentlichen Textanalyse durchgeführt werden.

Tokenizing

Um eingelesenen Rohtext in ein Format zu überführen, welches in der späteren Analyse einfacher ausgewertet werden kann, sind eine ganze Reihe von Schritten notwendig. Ganz allgemein besteht der erste Schritt darin, den auszuwertenden Text in einzelne kurze Abschnitte – so genannte Tokens – zu zerlegen (außer man bastelt sich völlig eigene Analyseansätze, wie zum Beispiel eine Spracherkennung anhand von Buchstabenhäufigkeiten ect.).

Was genau ein Token ist, hängt vom verwendeten Tokenizer ab. So bringt NLTK bereits standardmäßig unter anderem BlankLine-, Line-, Sentence-, Word-, Wordpunkt- und SpaceTokenizer mit, welche Text entsprechend in Paragraphen, Zeilen, Sätze, Worte usw. aufsplitten. Weiterhin ist mit dem RegexTokenizer ein Tool vorhanden, mit welchem durch Wahl eines entsprechenden Regulären Ausdrucks beliebig komplexe eigene Tokenizer erstellt werden können.

Üblicherweise wird ein Text (evtl. nach vorherigem Aufsplitten in Paragraphen oder Sätze) schließlich in einzelne Worte und Interpunktionen (Satzzeichen) aufgeteilt. Hierfür kann, wie im folgenden Beispiel z. B. der WordTokenizer oder die diesem entsprechende Funktion word_tokenize() verwendet werden.

Stemming & Lemmatizing

Andere häufig durchgeführte Schritte sind Stemming sowie Lemmatizing. Hierbei werden die Suffixe der einzelnen Tokens des Textes mit Hilfe eines Stemmers in eine Form überführt, welche nur den Wortstamm zurücklässt. Dies hat den Zweck verschiedene grammatikalische Formen des selben Wortes (welche sich oft in ihrer Endung unterscheiden (ich gehe, du gehst, er geht, wir gehen, …) ununterscheidbar zu machen. Diese würden sonst als mehrere unabhängige Worte in die darauf folgende Analyse eingehen.

Neben bereits fertigen Stemmern bietet NLTK auch für diesen Schritt die Möglichkeit sich eigene Stemmer zu programmieren. Da verschiedene Stemmer Suffixe nach unterschiedlichen Regeln entfernen, sind nur die Wortstämme miteinander vergleichbar, welche mit dem selben Stemmer generiert wurden!

Im forlgenden Beispiel werden verschiedene vordefinierte Stemmer aus dem Paket NLTK auf den bereits oben verwendeten Beispielsatz angewendet und die Ergebnisse der gestemmten Tokens in einer Art einfachen Tabelle ausgegeben:

Sehr ähnlich den Stemmern arbeiten Lemmatizer: Auch ihre Aufgabe ist es aus verschiedenen Formen eines Wortes die jeweilige Grundform zu bilden. Im Unterschied zu den Stemmern ist das Lemma eines Wortes jedoch klar als dessen Grundform definiert.

Vokabular

Auch das Vokabular, also die Menge aller verschiedenen Worte eines Textes, ist eine informative Kennzahl. Bezieht man die Größe des Vokabulars eines Textes auf seine gesamte Anzahl verwendeter Worte, so lassen sich hiermit Aussagen zu der Diversität des Textes machen.

Außerdem kann das auftreten bestimmter Worte später bei der automatischen Einordnung in Kategorien wichtig werden: Will man beispielsweise Nachrichtenmeldungen nach Themen kategorisieren und in einem Text tritt das Wort „DAX“ auf, so ist es deutlich wahrscheinlicher, dass es sich bei diesem Text um eine Meldung aus dem Finanzbereich handelt, als z. B. um das „Kochrezept des Tages“.

Dies mag auf den ersten Blick trivial erscheinen, allerdings können auch mit einfachen Modellen, wie dem so genannten „Bag-of-Words-Modell“, welches nur die Anzahl des Auftretens von Worten prüft, bereits eine Vielzahl von Informationen aus Texten gewonnen werden.

Das reine Vokabular eines Textes, welcher in der Variable “rawtext” gespeichert ist, kann wie folgt in der Variable “vocab” gespeichert werden. Auf die Ausgabe wurde in diesem Fall verzichtet, da diese im Falle des oben als Beispiel gewählten Satzes den einzelnen Tokens entspricht, da kein Wort öfter als ein Mal vorkommt.

Stopwords

Unter Stopwords werden Worte verstanden, welche zwar sehr häufig vorkommen, jedoch nur wenig Information zu einem Text beitragen. Beispiele in der beutschen Sprache sind: der, und, aber, mit, …

Sowohl NLTK als auch cpaCy bringen vorgefertigte Stopwordsets mit. 

Vorsicht: NLTK besitzt eine Stopwordliste, welche erst in ein Set umgewandelt werden sollte um die lookup-Zeiten kurz zu halten – schließlich muss jedes einzelne Token des Textes auf das vorhanden sein in der Stopworditerable getestet werden!

POS-Tagging

POS-Tagging steht für „Part of Speech Tagging“ und entspricht ungefähr den Aufgaben, die man noch aus dem Deutschunterricht kennt: „Unterstreiche alle Subjekte rot, alle Objekte blau…“. Wichtig ist diese Art von Tagging insbesondere, wenn man später tatsächlich strukturiert Informationen aus dem Text extrahieren möchte, da man hierfür wissen muss wer oder was als Subjekt mit wem oder was als Objekt interagiert.

Obwohl genau die selben Worte vorkommen, bedeutet der Satz „Die Katze frisst die Maus.“ etwas anderes als „Die Maus frisst die Katze.“, da hier Subjekt und Objekt aufgrund ihrer Reihenfolge vertauscht sind (Stichwort: Subjekt – Prädikat – Objekt ).

Weniger wichtig ist dieser Schritt bei der Kategorisierung von Dokumenten. Insbesondere bei dem bereits oben erwähnten Bag-of-Words-Modell, fließen POS-Tags überhaupt nicht mit ein.

Und weil es so schön einfach ist: Die obigen Schritte mit spaCy

Die obigen Methoden und Arbeitsschritte, welche Texte die in natürlicher Sprache geschrieben sind, allgemein computerzugänglicher und einfacher auswertbar machen, können beliebig genau den eigenen Wünschen angepasst, einzeln mit dem Paket NLTK durchgeführt werden. Dies zumindest einmal gemacht zu haben, erweitert das Verständnis für die funktionsweise einzelnen Schritte und insbesondere deren manchmal etwas versteckten Komplexität. (Wie muss beispielsweise ein Tokenizer funktionieren der den Satz “Schwierig ist z. B. dieser Satz.” korrekt in nur einen Satz aufspaltet, anstatt ihn an jedem Punkt welcher an einem Wortende auftritt in insgesamt vier Sätze aufzuspalten, von denen einer nur aus einem Leerzeichen besteht?) Hier soll nun aber, weil es so schön einfach ist, auch das analoge Vorgehen mit dem Paket spaCy beschrieben werden:

Dieser kurze Codeabschnitt liest den an spaCy übergebenen Rohtext in ein spaCy Doc-Object ein und führt dabei automatisch bereits alle oben beschriebenen sowie noch eine Reihe weitere Operationen aus. So stehen neben dem immer noch vollständig gespeicherten Originaltext, die einzelnen Sätze, Worte, Lemmas, Noun-Chunks, Named Entities, Part-of-Speech-Tags, ect. direkt zur Verfügung und können.über die Methoden des Doc-Objektes erreicht werden. Des weiteren liegen auch verschiedene weitere Objekte wie beispielsweise Vektoren zur Bestimmung von Dokumentenähnlichkeiten bereits fertig vor.

Die Folgende Übersicht soll eine kurze (aber noch lange nicht vollständige) Übersicht über die automatisch von spaCy generierten Objekte und Methoden zur Textanalyse geben:

Diese „Vollautomatisierung“ der Vorabschritte zur Textanalyse hat jedoch auch seinen Preis: spaCy geht nicht gerade sparsam mit Ressourcen wie Rechenleistung und Arbeitsspeicher um. Will man einen oder einige Texte untersuchen so ist spaCy oft die einfachste und schnellste Lösung für das Preprocessing. Anders sieht es aber beispielsweise aus, wenn eine bestimmte Analyse wie zum Beispiel die Einteilung in verschiedene Textkategorien auf eine sehr große Anzahl von Texten angewendet werden soll. In diesem Fall, sollte man in Erwägung ziehen auf ressourcenschonendere Alternativen wie zum Beispiel gensim auszuweichen.

Wer beim lesen genau aufgepasst hat, wird festgestellt haben, dass ich im Abschnitt POS-Tagging im Gegensatz zu den anderen Abschnitten auf ein kurzes Codebeispiel verzichtet habe. Dies möchte ich an dieser Stelle nachholen und dabei gleich eine Erweiterung des Pakets spaCy vorstellen: displaCy.

Displacy bietet die Möglichkeit, sich Zusammenhänge und Eigenschaften von Texten wie Named Entities oder eben POS-Tagging graphisch im Browser anzeigen zu lassen.

Nach ausführen des obigen Codes erhält man eine Ausgabe die wie folgt aussieht:

Nun öffnet man einen Browser und ruft die URL ‘http://127.0.0.1:5000’ auf (Achtung: localhost anstatt der IP funktioniert – warum auch immer – mit displacy nicht). Im Browser sollte nun eine Seite mit einem SVG-Bild geladen werden, welches wie folgt aussieht

Die Abbildung macht deutlich was POS-Tagging genau ist und warum es von Nutzen sein kann wenn man Informationen aus einem Text extrahieren will. Jedem Word (Token) ist eine Wortart zugeordnet und die Beziehung der einzelnen Worte durch Pfeile dargestellt. Dies ermöglicht es dem Computer zum Beispiel in dem Satzteil “der grüne Apfel”, das Adjektiv “grün” auf das Nomen “Apfel” zu beziehen und diesem somit als Eigenschaft zuzuordnen.

Nachdem dieser Artikel wichtige Schritte des Preprocessing von Texten beschrieben hat, geht es im nächsten Artikel darum was man an Texten eigentlich analysieren kann und welche Analysemöglichkeiten die verschiedenen für Python vorhandenen Module bieten.

II. Einführung in TensorFlow: Grundverständnis für TensorFlow

o. Installation von TensorFlow

Bevor wir richtig durchstarten können, müssen wir natürlich TensorFlow erstmal installieren. Auf dieser Seite findet ihr eine ausführliche Anleitung, wie man TensorFlow auf allen möglichen Systemen installiert. Die nächsten Schritte beschränken sich auf die Installation auf Windows.

o.1.  Installation mit pip

Um TensorFlow zu nutzen, müssen wir diesen Framework auch erstmal installieren. Am einfachsten ist die Installation, wenn ihr Python in reiner Form auf euren Rechner habt. Dann ist es vollkommen ausreichend, wenn ihr folgenden Befehl in eure Eingabeaufforderung(Windows: cmd) eingebt:

Stellt bei dieser Installation sicher, dass ihr keine ältere Version von Python habt als 3.5.x. Außerdem ist es erforderlich, dass ihr pip installiert habt und Python bei euch in der PATH-Umgebung eingetragen ist.Besitzt ihr eine NVIDIA® Grafikkarte so könnt ihr TensorFlow mit GPU Support nutzen. Dazu gebt ihr statt des oben gezeigten Befehls folgendes ein:

o.2. Installation mit Anaconda

Ein wenig aufwendiger wird es, wenn ihr die beliebte Anaconda Distribution nutzt, weil wir da eine Anaconda Umgebung einrichten müssen. Auch hier müssen wir wieder in den Terminal bzw. in die Eingabeaufforderung und folgenden Befehl eingeben:

Tauscht das mit eurer genutzten Version aus.(= 5, 6) Danach aktiviert ihr die erstellte Umgebung:

Nun installieren wir TensorFlow in unsere erstellte Umgebung. Ohne GPU Support

mit GPU Support

Es sei erwähnt, dass das Conda package nur von der Community unterstützt wird, jedoch nicht offiziell seitens Google.

o.3.  Validierung der Installation

Der einfachste Weg um zu überprüfen ob unsere Installation gefruchtet hat und funktioniert können wir anhand eines einfachen Beispiels testen. Dazu gehen wir wieder in den/die Terminal/Eingabeaufforderung und rufen python auf, indem wir python eingeben.


 

1. Grundverständnis für TensorFlow

1.1. Datenstrom-orientierte Programmierung

In diesem Artikel wollen wir näher auf die Funktionsweise von TensorFlow eingehen. Wie wir aus dem ersten Artikel dieser Serie wissen, nutzt TensorFlow das datenstrom-orientierte Paradigma. In diesem wird ein Datenfluss-Berechnungsgraph erstellt, welcher aus Knoten und Kanten besteht. Ein  Datenfluss-Berechnungsgraph, Datenflussgraph oder auch Berechnungsgraph kann mehrere Knoten haben, die wiederum durch die Kanten verbunden sind. In TensorFlow steht jeder Knoten für eine Operation, die Auswirkungen auf eingehende Daten haben.

Abb.1: Knoten und Kanten: Das Eingangssignal wird durch Kanten in den Knoten eingespeist, verändert und ausgegeben

Abb. 1.5: Achterbahn mit fehlender Verbindung [Quelle]

Analogie-Beispiel: Stellt euch vor ihr seid in einem Freizeitpark und habt Lust eine Achterbahn zu fahren. Am Anfang seid ihr vielleicht ein wenig nervös, aber euch geht es noch sehr gut. Wie jeder von euch weiß, hat eine Achterbahn verschiedene Fahrelemente eingebaut, die unsere Emotionen triggern und bei manchen vielleicht sogar auf den Magen schlagen. Diese Elemente sind äquivalent unsere Knoten. Natürlich müssen diese Elemente auch verbunden sein, sonst wäre eine Fahrt mit dieser Achterbahn in meinen Augen nicht empfehlenswert. Diese Verbindungsstücke sind unsere Kanten und somit sind wir die Daten/Signale, die von Knoten zu Knoten durch die Kanten weitergeleitet werden. Schauen wir uns Abb. 2 an, in der eine schematische Darstellung einer fiktiven Achterbahn zu sehen ist, welche mit 4 Fahrelementen dienen kann.

Abb. 2: Oben: Schematische Darstellung eines Datenflussgraphen anhand unserer fiktiven Achterbahn Unten: Unsere fiktive Achterbahn

  1. Airtime-Hügel: Ein Airtime-Hügel erzeugt bei der Überfahrt Schwerelosigkeit und in manchen Fällen ein Abheben aus dem Sitz. Ein guter Einstieg für die Mitfahrer, wie ich finde.
  2. Klassischer Looping: Wir kennen ihn alle, den Looping. Mit hoher Geschwindigkeit geht es in einen vertikalen Kreis hinein und man sich am höchsten Punkt kopfüber befindet.  Für Leute mit nicht so starken Nerven fragen sich spätestens jetzt, warum sie überhaupt mitgefahren sind.
  3. Korkenzieher/Schraube: Der Korkenzieher kann als auseinander gezogener Looping beschrieben werden.
  4. Schraubel-Looping : Und zu guter Letzt kombinieren wir  einen Looping mit einer Schraube! Ein Teil unserer Mitfahrer sucht den nächsten Busch auf, ein anderer Teil will am liebsten nochmal fahren und der Rest wird jetzt einen Pause brauchen.

Fakt ist, dass die Fahrelemente/Knoten unsere anfänglichen Emotionen/Eingangsdatensignale geändert haben.

1.2. Genereller Ablauf in TensorFlow

Anhand unser fiktiven Achterbahn haben wir das Prinzip der datenstrom-orientierten Programmierung eingefangen. Damit wir aber erst einmal Achterbahn fahren können, müssen wir diese konstruieren. Das gilt auch in TensorFlow und können die Arbeit in zwei wesentliche Phasen unterteilen:

  1. Erstellen eines Berechnungsgraphen: Wie auch bei einer Achterbahn müssen wir unser Modell erst einmal modellieren. Je nachdem welche Ressourcen uns zur Verfügung gestellt werden, welche Bedingungen wir folgen müssen, können wir unser Modell darauf aufbauen und gestalten.
  2. Ausführung des Berechnungsgraphen: Nachdem wir das Modell/den Graph fertig konstruiert haben, führen wir diese nun aus, d.h. für unsere Achterbahn, dass wir den Strom anschalten und losfahren können.

2. Erstellung eines Graphen

2.1. TensorFlow-Operatoren

Wie bereits erwähnt können Knoten verschiedene Operationen in sich tragen. Das können z.B. Addition, Substraktion oder aber auch mathematische Hyperbelfunktionen  à la Tangens Hyperbolicus Operatoren sein. Damit TensorFlow mit den Operatoren arbeiten kann, müssen wir diese mit den zur Verfügung gestellten Operatoren von TensorFlow auskommen. Eine vollständige Dokumentation findet ihr hier.

2.2. Platzhalter

Wenn in TensorFlow Daten aus externen Quellen in den Berechnungsgraph integriert werden sollen, dann wird eine eigens dafür entwickelte Struktur genutzt um die Daten einzulesen; dem Platzhalter. Ihr könnt euch den Platzhalter als Wagon unserer Achterbahn vorstellen, der die Mitfahrer (Daten bzw. Tensoren) durch die Achterbahn (Berechnungsgraph) jagt.

Es ist bei der Modellierung eines Berechnungsgraphen nicht notwendig, die Daten am Anfang einzuspeisen. Wie der Name schon sagt, setzt TensorFlow eine ‘leere Größe’ ein, die in der zweiten Phase gefüllt wird.

Eine Frage, die ich mir damals gestellt habe war, warum man einen Platzhalter braucht? Dazu können wir uns wieder unsere Achterbahn nehmen. Bei 2-3 Fahrgästen besteht kein Problem; wir hätten genug Platz/Ressourcen um diese unterzubringen. Aber was machen wir, wenn wir 10.000 Gäste haben, wie es auch in der Realität ist ? Das ist auch bei neuronalen Netzen der Fall, wenn wir zu viele Daten haben, dann stoßen wir irgendwann an unser Leistungslimit. Wir teilen unsere Daten/Gäste so auf, dass wir damit arbeiten können.

2.3. Variable

Stellen wir uns folgendes Szenario vor: Wir haben eine Achterbahn fertig konstruiert – wahrscheinlich die beste und verrückteste Achterbahn, die es jemals gegeben hat. Je nachdem welchen Effekt wir mit unserer Achterbahn erzielen wollen; z.B. ein einfacher Adrenalinschub, ein flaues Gefühl im Magen oder den vollständigen Verlust jeglicher Emotionen aus purer Angst um das eigene Leben, reicht es nicht nur ein schönes Modell zu bauen. Wir müssen zusätzlich verschiedene Größen anpassen um das Erlebnis zu maximieren. Eine wichtige Größe für unsere Achterbahn wäre die Geschwindigkeit (in neuronalen Netzen sind es die Gewichte), die über den Fahrspaß entscheidet. Um die optimale Geschwindigkeit zu ermitteln, müssen viele Versuche gemacht werden (sei es in der Realität oder in der Simulation) und nach jedem Test wird die Geschwindigkeit nach jedem Test angepasst. Zu diesem Zweck sind die Variablen da. Sie passen sich nach jedem Versuch an.

2.4. Optimierung

Damit die Variablen angepasst werden können, müssen wir TensorFlow Anweisungen geben, wie er die Variablen optimiert werden soll. Dafür müssen wir eine Formel an TensoFlow übermitteln, die dann optimiert wird. Auch hat man die Auswahl von verschiedenen Optimierer, die die Aufgabe anders optimieren. Die Wahl der richtigen Formel und des passenden Optimierer ist jedoch eine Sache, die ohne weiteres nicht zu beantworten ist. Wir wollen ein anderes Mal Bezug auf diese Frage nehmen.

3. Ausführung eines Graphen

Wie die Ausführung des Graphen von statten läuft, schauen wir uns im nächsten Abschnitt genauer an. Es sei so viel gesagt, dass um eine Ausführung einzuleiten wir den Befehl tf.Session() benötigen. Die Session wird mit tf.Session().run()gestartet und am Ende mit tf.Session().close() geschlossen. In der Methode .run()müssen die ausgeführten Größen stehen und außerdem der Befehl feed_dict= zum Befüllen der Platzhalter.

4. Beispiel: Achterbahn des Grauens – Nichts für schwache Nerven

4.1 Erklärung des Beispiels

Wir haben jetzt von so vielen Analogien gesprochen, dass es alles ein wenig verwirrend sein kann. Daher nochmal eine Übersicht zu den wesentlichen Punkten:

TensorFlow Neuronales Netz Achterbahn
Knoten Neuron Fahrelement
Variable Gewichte, Bias Geschwindigkeit
Kanten Signale Zustand der Fahrer
Platzhalter Wagon
Tab.1: Analogie unser fiktiven Achterbahn

 

Nun haben wir so viel Theorie gehört, jetzt müssen auch Taten folgen! Weshalb wir unsere Achterbahn modellieren wollen. Zu unserem Beispiel: Wir wollen eine Achterbahn bauen, welche ängstlichen Mitfahrer noch ängstlicher machen soll und diese sollen am Ende der Fahrt sich wünschen nie mitgefahren zu sein. (Es wird natürlich eine stark vereinfachte Variante werden, die aber auf all unsere Punkte eingehen soll, die wir im oberen Teil angesprochen haben.)

Wie im bereits beschrieben, unterteilt sich die Arbeit in TensorFlow in zwei Phasen:

  1. Erstellung des Graphen: In unserem Falle wäre das die Konstruktion unserer Achterbahn.
  2. Ausführung des Graphen: In dieser Phase lassen wir unsere Insassen einfach los und schauen mal was passiert.

Um die Zahlen zu verstehen, möchte ich euch zudem erklären, was überhaupt das Ziel unseres Modells ist. Wir haben 8 Probanden mit verschiedenen Angstzuständen. Der Angstzustand ist in unserem Beispiel ein quantitativer Wert, Menge der ganzen Zahlen  und je größer dieser Wert ist, desto ängstlicher sind unsere Probanden. Unser Ziel ist es alle Probanden in Angst und Schrecken zu versetzen, die einen Angstzustand >5 haben und sich nach der Fahrt wünschen unserer Achterbahn nie mitgefahren zu sein! Die Größe die wir dabei optimieren wollen, ist die Geschwindigkeit. Wenn die Geschwindigkeit zu schnell ist, dann fürchten sich zu viele, wenn wir zu langsam fahren, dann fürchtet sich womöglich niemand. Außerdem benötigen wir noch eine Starthöhe, die wir dem Modell zugeben müssen.

Wir haben somit eine Klassifikationsaufgabe mit dem Ziel die Geschwindigkeit und die Starthöhe zu optimieren, damit sich Fahrgäste mit einem Angstzustand > 5 so eine schlechte Erfahrung machen, dass sie am liebsten nie mitgefahren wären.

Wir benötigen außerdem für unser Beispiel folgende Module:

4.2. Eingangssignale: Zustände der Gäste

Wir sehen hier zwei Vektoren bzw. Tensoren die Informationen über unsere Gäste haben.

  • x_input ist der Angstzustand unserer Gäste
  • y_input ist unser gewünschtes Ausgangsssignal: 0  normal, 1  Wunsch nicht mitgefahren zu sein

4.3. Erstellung unseres Graphen: Konstruktion der Achterbahn

Nun konstruieren wir unsere Achterbahn des Grauens:

Eine Gleichrichter-Aktivierungsfunktion (engl. rectifier) mit einer Matrizenmultiplikation aus einem Vektor und einem Skalar mit anschließender Fehleroptimierung! MuhahahahaHAHAHAHA!

Auf den ersten Blick vielleicht ein wenig verwirrend, weshalb wir alles Schritt für Schritt durchgehen:

  • wag = tf.placeholder(tf.float32, shape = [8, 1]) ist unser Wagon, welcher die Achterbahn auf und ab fährt. Gefüllt mit unseren Probanden. Die Daten der Probanden (x_input)sind externe Daten und damit geeignet für einen Platzhalter.
    • Wichtig bei Platzhalter ist, dass ihr den Datentyp angeben müsst!
    • Optional könnt ihr auch die Form angeben. Bei einem so überschaubaren Beispiel machen wir das auch. (Form unseres Vektors: 8×1)
  • y_true = tf.placeholder(tf.float32, shape = [8, 1]) ist der gewünschte Endzustand unserer Gäste, den wir uns für die Probanden erhoffen, d.h. es ist unser y_input. Auch hier kommen die Daten von außerhalb und daher wird der Platzhalter genutzt.
  • v, h sind Geschwindigkeit und Starthöhe, die optimiert werden müssen; perfekt für eine Variable!
    • Variablen brauchen am Anfang immer einen Initialisierungswert. Für v soll es 1 sein und für h soll es -2 sein. Außerdem liegen diese Größen als Skalare (1×1) vor.

Abb.2: Schematische Darstellung unseres Berechnungsgraphen

Nun zum zweiten Teil der Modellierung in dem wir ein klein wenig Mathematik benötigen. Schauen wir uns folgende Gleichung an:

  • z = tf.matmul(wag, v) + h: ist unsere Matrizenmultiplikation -> Da unsere Größen in Vektoren/Tensoren vorliegen, können wir diese nicht einfach multiplizieren, wie z.B. 2*2 = 4. Bei der Multiplikation von Matrizen oder Vektoren müssen bestimmte Bedingungen herrschen, damit diese überhaupt multipliziert werden können. Eine ausführlichere Erklärungen soll demnächst folgen.
  • y_pred = tf.nn.relu(z): Für all diejenigen, die sich bereits mit neuronalen Netzen beschäftigt haben; relu ist in unserem Fall die Aktivierungsfunktion. Für alle anderen, die mit der Aktivierungsfunktion noch nichts anfangen können: Die Kombination (Matrizenmultiplikation) aus dem Angstzustand und der Geschwindigkeit ist der Wert Z. Je nachdem welche Aktivierungsfunktion genutzt wird, triggert der Wert unsere Emotionen, so dass wir den Wunsch verspüren, die Bahn nie gefahren zu sein.
  • err = tf.square(y_true - y_pred):Quadriert die Differenz der tatsächlichen und der ermittelten Werte. -> die zu optimierende Funktion
  • opt = tf.train.AdamOptimizer(learning_rate=0.01).minimize(err)Unser gewählter Optimierer mit der Lernrate 0.01.
  • init = tf.global_variables_initializer() Initialisierung der Variablen

Abb. 3: Aktivierungsfunktion ReLu

4.4. Ausführung des Graphen: Test der Achterbahn

Wenn wir den unten stehenden Code mal grob betrachten, dann fällt vor allem die Zeile mit dem with-(Python)Operator und dem tf.Session()-(TensorFlow)Operator auf. Der tf.Session()-Operator leitet unsere Ausführung ein. Warum wir with nutzen hat den Grund, dass dieser Operator uns das Leben einfacher macht, da dieser die nachfolgenden Befehle wieder schließt und damit wieder Leistungsressourcen frei werden. Werden zum Beispiel Daten aus externen Quellen benötigt – sei es eine Excel- oder eine SQL-Tabelle – dann schließt uns der with Operator die geöffneten Dateien, nachdem er alle unsere Befehle durchgeführt hat.

Durch die Methode .run() werden dann die in der Klammer befindenden Größen bearbeitet. Mit dem Parameter feed_dict= füllen wir den Graphen mit unseren gewünschten Dateien.

Wir lassen das Ganze 100 mal Testfahren um die optimalen Variablen zu finden. In Abb. 4 sehen wir die Verläufe der Fehlerfunktion, der Geschwindigkeit und der Höhe.

 

In Tab.2 sind nun zwei Fahrgäste zu sehen, die sich wünschen, die Bahn nie gefahren zu sein! Deren Angstlevel () ist über 0 und damit wird der Wunsch getriggert wurde; so wie wir es auch beabsichtigt haben!

Angstlvl berechnet: Fehler: Geschwindigkeit: Starthöhe:
 [0.       ] [0.        ] [0.4536] [-2.5187]
 [0.       ]  [0.        ]
 [0.       ]  [0.        ]
 [0.       ]  [0.        ]
 [0.       ]  [0.        ]
 [0.       ]  [0.        ]
 [0.2060 ] -> Wunsch getriggert  [0.6304]
 [1.5685] -> Wunsch getriggert  [0.3231]
Tab.2: Endergebnisse der letzten Runde

Abb.4: Verläufe der Fehler-, Geschwindigkeits- und Höhenfunktion durch Optimierung

5. Zusammenfassung und Ausblick

Zugegeben ist dieser ganze Aufwand für ein mehr oder weniger linearen Zusammenhang etwas übertrieben und bestimmt ist dem einen oder anderen aufgefallen, dass unser Beispiel mit der Achterbahn an manchen Stellen hinkt. Dennoch hoffe ich, dass ich mit der Analogie das Verständnis von TensorFlow rüberbringen konnte. Lasst uns daher nochmal die wichtigsten Punkte zusammenfassen:

Die Arbeit mit TensorFlow unterteilt sich in folgende Phasen:

  1. Erstellung des Graphen: In dieser Phase konzentrieren wir uns darauf einen Berechnungsgraphen zu erstellen, welcher  so konzipiert wird, dass er uns am Ende das Ergebnis ausgibt, welches wir uns wünschen.
    • Platzhalter: Eine der wichtigsten Sturkturen in TensorFlow ist der Platzhalter. Er ist dafür zuständig, wenn es darum geht externe Daten in unseren Graph einfließen zu lassen. Bei der Erstellung eines Platzhalters müssen wir zumindest den Datentypen angeben.
    • Variable: Wenn es darum geht Größen für ein Modell zu optimieren, stellt TensorFlow Variablen zur Verfügung. Diese benötigen eine Angabe, wie die Form des Tensors aussehen soll.
  2. Ausführung des Graphen: Nachdem wir unseren Graphen entwickelt haben, ist der nächste Schritt diesen auszuführen.
    • Dies machen wir mit dem Befehl tf.Session() und führen diesen dann mit der Methode .run() aus
    • Ebenfalls hat die Optimierung einen wichtigen Bestand in dieser Phase
    • Um unseren Graphen mit den Daten zu füllen, nutzen wir den wird den Parameter feed_dict=

Um diesen Artikel nicht in die Länge zu ziehen, wurden die Themen der Matrizenmultiplikation, Aktivierungsfunktion und Optimierung erstmal nur angerissen. Wir wollen in einem separaten Artikel näher darauf eingehen. Für den Anfang genügen wir uns damit, dass wir von diesen Elementen wissen und dass sie einen wichtigen Bestandteil haben, wenn wir neuronale Netze aufbauen wollen.

In nächsten Artikel werden wir dann ein Perzeptron erstellen und gehen auch näher auf die Themen ein, die wir in diesem Teil nur angerissen haben. Bleibt gespannt!

6. Bonus-Material

Mit Tensorboard ist es möglich unseren entwickelten Graphen auch plotten und auszugeben zu lassen. So sieht unser Graph aus:

Abb.5.: Tensorboard Berechnungsgraphausgabe

Den Programmiercode könnt ihr in diesem Link auch als Ganzes betrachten.

Deep Learning and Human Intelligence – Part 2 of 2

Data dependency is one of the biggest problem of Deep Learning Architectures. This difficulty lies not so much in the algorithm of Deep Learning as in the invisible structure of the data itself.

This is part 2 of 2 of the Article Series: Deep Learning and Human Intelligence.

We saw that the process of discovering numbers was accompanied with many aspects of what are today basic ideas of Machine Learning. But let us go back, a little before that time, when humankind did not fully discovered the concept of numbers. How would a person, at such a time, perceive quantity and the count of things? Some structures are easily recognizable as patterns of objects, that is numbers, like one sun, 2 trees, 3 children, 4 clouds and so on. Sets of objects are much simpler to count if all the objects of the set are present. In such a case it is sufficient to keep a one-to-one relationship between two different set, without the need for numbers, to make a judgement of crucial importance. One could consider the case of two enemies that go to war and wish to know which has a larger army. It is enough to associate a small stone to every enemy soldier and do the same with his one soldier to be able to decide, depending if stones are left or not, if his army is larger or not, without ever needing to know the exact number soldier of any of the armies.

But also does things can be counted which are not directly visible, and do not allow a direct association with direct observable objects that can be seen, like stones. Would a person, at that time, be able to observe easily the 4-th day since today, 5 weeks from now, when even the concept of week is already composite? Counting in this case is only possible if numbers are already developed through direct observation, and we use something similar with stones in our mind, i.e. a cognitive association, a number. Only then, one can think of the concept of measuring at equidistant moments in time at all. This is the reason why such measurements where still cutting edge in the time of Galileo Galilei as we seen before. It is easily to assume that even in the time when humans started to count, such indirect concepts of numbers were not considered to be in relation with numbers. This implies that many concepts with which we are today accustomed to regard as a number, were considered as belonging to different groups, cluster which are not related. Such an hypothesis is not even that much farfetched. Evidence for such a time are still present in some languages, like Japanese.

When we think of numbers, we associate them with the Indo-Arabic numbers, but in Japanese numbers have no decimal structure and counting depends not only on the length of the set (which is usually considered as the number), but also on the objects that make up the set. In Japanese one can speak of meeting roku people, visiting muttsu cities and seeing ropa birds, but referring each time to the same number: six. Additional, many regular or irregular suffixes make the whole system quite complicated. The division of counting into so many clusters seems unnecessarily complicated today, but can easily be understood from a point of view where language and numbers still form and, the numbers, were not yet a uniform concept. What one can learn from this is that the lack of a unifying concept implies an overly complex dependence on data, which is the present case for Deep Learning and AI in general.

Although Deep Learning was a breakthrough in the development of Artificial Intelligence, the task such algorithms can perform were and remained very narrow. It may identify birds or cancer cells, but it will miss the song of the birds or the cry of the patient with cancer. When Watson, a Deep Learning Architecture played the famous Jeopardy game against two former Champions and won, it still made several simple mistakes, like going for the same wrong answer like the player before. If it could listen to the answer of the candidate, it could delete the top answer it had, and gibe the second which was the right one. With other words, Deep Learning Architecture are not multi-tasking and it is for this reason that some experts in AI are calling them intelligent idiots.

Imagine spending time learning to play a game for years and years, and then, when mastering it and wish to play a different game, to be unable to use any of the past experience (of gaming) for the new one and needing to learn everything from scratch. That could be quite depressing and would make life needlessly difficult. This is the reason why people involved in developing Deep Learning worked from early on in the development of multi-tasking Deep Learning Architectures. On the way a different method of using Deep Learning was discovered: transfer learning. Because the time it takes for a Deep Learning Architecture to learn is very long, transfer learning uses already learned Deep Learning Architectures but for slightly different task. It is similar to the use of past experiences in solving new problems, but, the advantage of transfer learning is, it allow the using of past experiences (what it already learned) which reduces dramatically the amount of new data needed in performing a new task. Still, transfer learning is far away from permitting Deep Learning Architectures to perform any kind of task learning only from one master data set.

The management of a unique master data set which includes all the needed data to enable human accuracy for any human activity, is not enough. One needs another ingredient, the so called cost function which translates, in this case, to the human brain. There are all our experiences and knowledge. How long does it takes to collect sufficient of both to handle a normal human life? How much to achieve our highest potential? If not a lifetime, at least decades. And this also applies to our job: as a IT-developer, a Data Scientist or a professor at the university. We will always have to learn new things, how to use them, and how to expand the limits of our perceptions. The vast amount of information that science has gathered over the last four centuries makes it impossible for any human being to become an expert in all of it. Thus, one has to specialized. After the university, anyone has to choose o subject which is appealing enough to study it for decades. Here is the first sign of what can be understood as data segmentation and dependency. Such improvements can come in various forms: an algorithm in the IT, a theorem in mathematics, a new way to look at particles in physics or a new method to scan for diseases in biology, and so on. But there is a price to pay for specialization: the inability to be an expert in another field or subfield. (Subfields induces limitation!)

Lets take the Deep Learning algorithm itself as an example. For IT and much of everyday life, this is a real breakthrough, but it lacks any scientific, that is mathematical, foundation. There are no theorems which proofs that it will find (converge, to use a mathematical term) the global optimum. This does not appear to be of any great consequences if it can be so efficient, except that, when adding new data and let the algorithm learn the same architecture again, there is no guaranty what so ever that it will be as good as the old model, or even better. On the contrary, it is as real as the efficiency of the first model, that chances are that the new model with the new data will perform worse than the old model, and one has to invest again time in finding a better model, or even a different architecture. On the other hand, with a mathematical proof of convergence, it would be always possible to know in what condition such a convergence can be achieved. In other words, without deep knowledge in mathematics, any proof of a consistent Deep Learning Algorithm is impossible.

Such a situation is true for any other corssover between fields. A mathematical genius will make a lousy biologist, a great chemist will make a average economist, and a top economist will be a poor physicist. Knowledge is difficult to transfer and this is true also for everyday experiences. We learn from very small to play a game like football, but are unable to use the reflexes to play basketball, or tennis better than a normal beginner. We learn a new language after years and years of practice, but are unable to use the way we learned to learn faster other languages. We are trapped within the knowledge we developed from the data we used. It is for this reason why we cannot transfer the knowledge a mathematician has developed over decades to use it in biology or psychology, even if the knowledge is very advanced. Instead of thinking in knowledge, we thing in data. This is similar to the people which were unaware of numbers, and used sets (data) to work with them. Numbers could be very difficult to transmit from one person to another in former times.

Only think on all the great achievements that our society managed, like relativity, quantum mechanics, DNA, machines, etc. Such discoveries are the essences of human knowledge and took millennia to form and centuries to crystalize. Still, all this knowledge is captive in the data, in the special frame in which it was discovered and never had the chance to escape. Imagine the possibility to use thoughts/causalities like the one in relativity or quantum mechanics in biology, or history, or of the concept of DNA in mathematics or art. Imagine a music composition where the law of the notes allows a “tunnel effect” like in quantum mechanics, lower notes to warp the music scales like in relativity and/or to twist two music scale in a helix-like play. How many way to experience life awaits us. Or think of the knowledge hidden in mathematics which could help develop new medicine, but can not be transmitted.

Another example of the connection we experience between knowledge and the data through which we obtain it, are children. They are classical example when it come determine if one is up to explain to them something. Take as an explain something simple they can observe often, like lightning and thunder. Normal concepts like particles, charge, waves, propagation, medium of propagation, etc. become so complicated to expose by other means then the one through which they were discovered, that it becomes nearly impossible to explain to children how it works and that they do not need to fear it. Still, one can use analogy (i.e., transfer) to enable an explanation. Instead of particles, one can use balls, for charge one can use hardness, waves can be shown with strings by keeping one end fix and waving the other, propagation is the movement of the waves from one end of the string to the other end, medium of propagation is the difference between walking in air and water, etc. Although difficult, analogies can be found which enables us to explain even to children how complex phenomena works.

The same is true also for Deep Learning. The model, the knowledge it can extract from the data can be expressed only by such data alone. There is no transformation of the knowledge from one type of data to another. If such a transformation would exists, then Deep Learning would be able to learn any human task by only a set of data, a master data set. Without such a master data set and a corresponding cost function it will be nearly impossible to develop AI that mimics human behavior. With other words, without the realization how our mind works, and how to crystalize by this the data needed, AI will still need to look at all the activities separately. It also implies that AI are restricted to the human understanding of reality and themselves. Only with such a characteristic of a living being, thus also AI, can development of its on occur.

Kiano – visuelle Exploration mit Deep Learning

Kiano – eine iOS-App zur visuellen Exploration und Suche der eigenen Fotos.

Menschen haben kein Problem, komplexe Bilder zu verstehen, es fällt ihnen aber schwer, gezielt Bilder in großen Bildersammlungen (wieder) zu finden. Da die Anzahl von Bildern, insbesondere auch auf Smartphones zusehends zunimmt – mehrere tausend Bilder pro Gerät sind keine Seltenheit, wird die Suche nach bestimmten Bildern immer schwieriger. Ist bei einem gesuchten Foto dessen Aufnahmedatum unbekannt, so kann es sehr lange dauern, bis es gefunden ist. Werden dem Nutzer zu viele Bilder auf einmal präsentiert, so geht der Überblick schnell verloren. Aus diesem Grund besteht eine typische Bildsuche heutzutage meist im endlosen Scrollen über viele Bildschirmseiten mit langen Bilderlisten.

Dieser Artikel stellt das Prinzip und die Funktionsweise der neuen iOS-App “Kiano” vor, die es Nutzern ermöglicht, alle ihre Bilder explorativ mittels visuellem Browsen zu erkunden. Der Name “Kiano” steht hierbei für “Keep Images Arranged & Neatly Organized”. Mit der App ist es außerdem möglich, zu einem Beispielbild gezielt nach ähnlichen Fotos auf dem Gerät zu suchen.

Um Bilder visuell durchsuch- und sortierbar zu machen, werden sogenannte Merkmalsvektoren bzw. Featurevektoren verwendet, die Aussehen und Inhalt von Bildern kompakt repräsentieren können. Zu einem Bild lassen sich ähnliche Bilder finden, indem die Bilder bestimmt werden, deren Featurevektoren eine geringe Distanz zum Featurevektor des Suchbildes haben.

Werden Bilder zweidimensional so angeordnet, dass die Featurevektoren benachbarter Bilder sehr ähnlich sind, so erhält man eine visuell sortierte Bilderlandkarte. Bei einer visuell sortierten Anordnung der Bilder fällt es Menschen deutlich leichter, mehr Bilder gleichzeitig zu erfassen, als dies im unsortierten Fall möglich wäre. Durch die graduelle Veränderung der Bildinhalte wird es möglich, über diese Karte visuell zu navigieren.

Generierung von Featurevektoren zur Bildbeschreibung

Convolutional Neural Networks (CNNs) sind nicht nur in der Lage, Bilder mit hoher Genauigkeit zu klassifizieren, d.h. zu erkennen, welches Objekt – entsprechend einer Menge von gelernten Objektkategorien auf einem Bild zu sehen ist, die Aktivierungen der Netzwerkschichten lassen sich auch als universelle Featurevektoren zur Bildbeschreibung nutzen. Während die vorderen Netzwerkschichten von CNNs einfache visuelle Bildmerkmale wie Farben und einfache Muster detektieren, repräsentieren die Ausgangsschichten des Netzwerks die semantischen Informationen bezüglich der gelernten Objektkategorien. Die Zwischenschichten des Netzwerks sind weniger von den Objektkategorien abhängig und können somit als generelle abstrakte Repräsentationen des Inhalts der Bilder angesehen werden. Hierbei ist es möglich, bereits fertig trainierte Klassifikationsnetzwerke für die Featureextraktion wiederzuverwenden. In der Visual Computing Gruppe der HTW Berlin wurden umfangreiche Evaluierungen durchgeführt, um zu bestimmen, welche Netzwerkschichten von welchen CNNs mit welchen zusätzlichen Transformationen zu verwenden sind, um aus Netzwerkaktivierungen Feature-Vektoren zu erzeugen, die sehr gut für die Suche nach beliebigen Bildern geeignet sind.

Beste Ergebnisse hinsichtlich der Suchgenauigkeit (der Mean Average Precision) wurden mit einem Deep Residual Learning Network (ResNet-200) erzielt. Die 2048 Aktivierungen vor dem vollvernetzten letzten Layer werden als initiale Featurevektoren verwendet, wobei sich die Suchgenauigkeit durch eine L1-Normierung, gefolgt von einer PCA-Transformation (Principal Component Analysis) sogar noch verbessern lässt. Hierdurch ist es möglich, die Featurevektoren auf eine Größe von nur 64 Bytes zu reduzieren. Leider ist die rechnerische Komplexität der Bestimmung dieser hochwertigen Featurevektoren zu groß, um sie auf mobilen Geräten verwenden zu können. Eine gute Alternative stellen die Mobilenets dar, die sich durch eine erheblich reduzierte Komplexität auszeichnen. Als Kompromiss zwischen Klassifikationsgenauigkeit und Komplexität wurde für die Kiano-App das Mobilenet_v2_0.5_128 verwendet. Die mit diesem Netzwerk bestimmten Featurevektoren wurden ebenfalls auf eine Größe von 64 Bytes reduziert.

Die aus CNNs erzeugten Featurevektoren sind gut für die Suche nach Bildern mit ähnlichem Inhalt geeignet. Für die Suche nach Bilder, mit ähnlichen visuellen Eigenschaften (z.B. die auftretenden Farben oder deren örtlichen Verteilung) sind diese Featurevektoren nur bedingt geeignet. Hierfür eignen sich klassische sogenannte “Low-Level”-Featurevektoren besser. Da für eine ansprechende und leicht erfassbare Bildsortierung auch eine Übereinstimmung dieser visuellen Bildattribute wichtig ist, kommt bei Kiano ein weiterer Featurevektor zum Einsatz, mit dem sich diese “primitiven” visuellen Bildattribute beschreiben lassen. Dieser Featurevektor hat eine Größe von 50 Bytes. Bei Kiano kann der Nutzer in den Einstellungen wählen, ob bei der visuellen Sortierung und Bildsuche größerer Wert auf den Bildinhalt oder die visuelle Erscheinung eines Bildes gelegt werden soll.

Visuelle Bildsortierung

Werden Bilder entsprechend ihrer Ähnlichkeiten sortiert angeordnet, so können mehrere hundert Bilder gleichzeitig wahrgenommen bzw. erfasst werden. Dies hilft, Regionen interessanter Bildern leichter zu erkennen und gesuchte Bilder schneller zu entdecken. Die Möglichkeit, viele Bilder gleichzeitig präsentieren zu können, ist neben Bildverwaltungssystemen besonders auch für E-Commerce-Anwendungen interessant.

Herkömmliche Dimensionsreduktionsverfahren, die hochdimensionale Featurevektoren auf zwei Dimensionen projizieren, sind für die Bildsortierung ungeeignet, da sie die Bilder so anordnen, dass Lücken und Bildüberlappungen entstehen. Sollen Bilder sortiert auf einem dichten regelmäßigen 2D-Raster angeordnet werden, kommen als Verfahren nur selbstorganisierende Karten oder selbstsortierende Karten in Frage.

Eine selbstorganisierende Karte (Self Organizing Map / SOM) ist ein künstliches neuronales Netzwerk, das durch unbeaufsichtigtes Lernen trainiert wird, um eine niedrigdimensionale, diskrete Darstellung der Daten des Eingangsraums als sogenannte Karte (Map) zu erzeugen. Im Gegensatz zu anderen künstlichen neuronalen Netzen, werden SOMs nicht durch Fehlerkorrektur, sondern durch ein Wettbewerbsverfahren trainiert, wobei eine Nachbarschaftsfunktion verwendet wird, um die lokalen Ähnlichkeiten der Eingangsdaten zu bewahren.

Eine selbstorganisierende Karte besteht aus Knoten, denen einerseits ein Gewichtsvektor der gleichen Dimensionalität wie die Eingangsdaten und anderseits eine Position auf der 2D-Karte zugeordnet sind. Die SOM-Knoten sind als zweidimensionales Rechteckgitter angeordnet. Das vom der SOM erzeugte Mapping ist diskret, da jeder Eingangsvektor einem bestimmten Knoten zugeordnet wird. Zu Beginn werden die Gewichtsvektoren aller Knoten mit Zufallswerten initialisiert. Wird ein hochdimensionaler Eingangsvektor in das Netz eingespeist, so wird dessen euklidischer Abstand zu allen Gewichtsvektoren berechnet. Der Knoten, dessen Gewichtsvektor dem Eingangsvektor am ähnlichsten ist, wird als Best Matching Unit (BMU) bezeichnet. Die Gewichte des BMU und seiner auf der Karte örtlich benachbarten Knoten werden an den Eingangsvektor angepasst. Dieser Vorgang wird iterativ wiederholt. Das Ausmaß dieser Anpassung nimmt im Laufe der Iterationen und der örtlichen Entfernung zum BMU-Knoten ab.

Um SOMs an die Bildsortierung anzupassen, sind zwei Modifikationen notwendig. Jeder Knoten darf nicht von mehr als einem Featurevektor (der ein Bild repräsentiert) ausgewählt werden. Eine Mehrfachauswahl würde zu einer Überlappung der Bilder führen. Aus diesem Grund muss die Anzahl der SOM-Knoten mindestens so groß wie die Anzahl der Bilder sein. Eine sinnvolle Erweiterung einer SOM verwendet ein Gitter, bei dem gegenüberliegende Kanten verbunden sind. Werden diese Torus-förmigen Karten für große SOMs verwendet, kann der Eindruck einer endlosen Karte erzeugt werden, wie es in Kiano umgesetzt ist. Ein Problem der SOMs ist ihre hohe rechnerische Komplexität, die quadratisch mit der Anzahl der zu sortierenden Bilder wächst, wodurch die maximale Anzahl an zu sortierenden Bildern beschränkt wird. Eine Lösung stellt eine selbstsortierende Karte (Self Sorting Map / SSM) dar, deren Komplexität nur n log(n) beträgt.

Selbstsortierende Karten beginnen mit einer zufälligen Positionierung der Bilder auf der Karte. Diese Karte wird dann in 4×4-Blöcke aufgeteilt und für jeden Block wird der Mittelwert der zugehörigen Featurevektoren bestimmt. Als nächstes werden aus 2×2 benachbarten Blöcken jeweils vier korrespondierende Bild-Featurevektoren untersucht und ihre zugehörigen Bilder gegebenenfalls getauscht. Aus den 4! = 24 Anordnungsmöglichkeiten wird diejenige gewählt, die die Summe der quadrierten Differenzen zwischen den jeweiligen Featurevektoren und den Featuremittelwerten der Blöcke minimiert. Nach mehreren Iterationen wird jeder Block in vier kleinere Blöcke halber Breite und Höhe aufgeteilt und wiederum in der beschriebenen Weise überprüft, wie die Bildpositionen dieser kleineren Blöcke getauscht werden sollten. Dieser Vorgang wird solange wiederholt, bis die Blockgröße auf 1×1 Bild reduziert ist.

In der Visual-Computing Gruppe der HTW Berlin wurde untersucht, wie die Sortierqualität des SSM-Algorithmus verbessert werden kann. Anstatt die Mittelwerte der Featurevektoren als konstanten Durchschnittsvektor für den gesamten Block zu berechnen, verwenden wir gleitende Tiefpassfilter, die sich effizient mittels Integralbildern berechnen lassen. Hierdurch entstehen weichere Übergänge auf der sortierten Bilderkarte. Weiterhin wird die Blockgröße nicht für mehrere Iterationen konstant gehalten, sondern kontinuierlich zusammen mit dem Radius des Filterkernels reduziert. Durch die Verwendung von optimierten Algorithmen von “Linear Assignment” Algorithmen wird es weiterhin möglich, den optimalen Positionstausch nicht nur für jeweils vier Featurevektoren bzw. Bildern sondern für eine deutlich größere Anzahl zu überprüfen. All diese Maßnahmen führen zu einer deutlich verbesserten Sortierungsqualität bei gleicher Komplexität.

Effiziente Umsetzung für iOS

Wie so oft, liegen die softwaretechnischen Herausforderungen an ganz anderen Stellen, als man zunächst vermutet. Für eine effiziente Implementierung der zuvor beschriebenen Algorithmen, insbesondere der SSM, stellte es sich heraus, dass die Programmiersprache Swift, in der iOS Apps normaler Weise entwickelt werden, erheblich mehr Rechenzeit benötigt, als eine Umsetzung in der Sprache C. Im Zuge der stetigen Weiterentwicklung von Swift und dessen Compiler mag sich die Lücke zu C zwar immer weiter schließen, zum Zeitpunkt der Umsetzung war die Implementierung in C aber um einen Faktor vier schneller als in Swift. Hierbei liegt die Vermutung nahe, dass der Zugriff auf und das Umsortieren von Featurevektoren als native C-Arrays deutlich effektiver passiert, als bei der Verwendung von Swift-Arrays. Da Swift-Arrays Value-Type sind, kommt es in Swift vermutlich zu unnötigen Kopieroperationen der Fließkommazahlen in den einzelnen Featurevektoren.

Die Berechnung des Mobilenet-Anteils der Featurevektoren konnte sehr komfortabel mit Apples CoreML Machine Learning Framework umgesetzt werden. Hierbei ist zu beachten, dass es sich wie oben beschrieben, nicht um eine Klassifikation handelt, sondern um das Abgreifen der Aktivierungen einer tieferen Schicht. Für Klassifikationen findet man praktisch sofort nutzbare Beispiele, für den Zugriff auf die Aktivierungen waren jedoch Anpassungen notwendig, die bei der Portierung eines vortrainierten Mobilenet nach CoreML vorgenommen wurden. Das stellte sich als erheblich einfacher heraus, als der Versuch, auf die tieferen Schichten eines Klassifizierungsnetzes in CoreML zuzugreifen.

Für die Verwaltung der Bilder, ihrer Featurevektoren und ihrer Position in der sortieren Karte wird in Kiano eine eigene Datenstruktur verwendet, die es zu persistieren gilt. Es ist dem Nutzer ja nicht zuzumuten, bei jedem Start der App auf die Berechnung aller Featurevektoren zu warten. Die Strategie ist es hierbei, bereits bekannte Bilder zu identifizieren und deren Features nur dann neu zu berechnen, falls sich das Bild verändert hat. Die über Appels Photos Framework zur Verfügung gestellten local Identifier identifizieren dabei die Bilder. Veränderungen werden über das Modifikationsdatum eines Bildes detektiert. Die größte Herausforderung ist hierbei das Zeichnen der Karte. Die Benutzerinteraktion soll schnell und flüssig erscheinen, auf Animationen wie das Nachlaufen der Karte beim Verschieben möchte man nicht verzichten. Die Umsetzung geschieht hierbei nicht in OpenGL ES, welches ab iOS 12 ohnehin als deprecated bezeichnet wird. Auf der anderen Seite wird aber auch nicht der „Standardweg“ des Überschreibens der draw-Methode einer Ableitung von UIView gewählt. Letztes führt bekanntlich zu Performanceeinbußen. Insbesondere deshalb, weil das System sehr oft Backing-Images der Ansichten erstellt. Um die Kontrolle über das Neuzeichnen zu behalten, wird in Kiano ein eigenes Backing-Image implementiert, das auf Ebene des Core Animation Frameworks dem View als Layer zugweisen wird. Diesem Layer kann dann sehr komfortabel eine 3D-Transformation zugewiesen werden und man profitiert von der GPU-Beschleunigung, ohne OpenGL ES direkt verwenden zu müssen.

 

Trotz der Verwendung eines Core Animation Layers ist das Zeichnen der Karte immer noch sehr zeitaufwendig. Das liegt an der Tatsache, dass je nach Zoomstufe tausende von Bildern darzustellen sind, die alle über das Photos Framework angefordert werden müssen. Das Nadelöhr ist dann weniger das Zeichnen, als die Zeit, die vergeht, bis einem das Bild zur Verfügung gestellt wird. Diese Vorgänge sind praktisch alle nebenläufig. Zur Erinnerung: Ein Foto kann in der iCloud liegen und zum Zeitpunkt der Anfrage noch gar nicht (oder noch nicht in geeigneter Auflösung) heruntergeladen sein. Netzwerkbedingt gibt es keine Vorhersage, wann oder ob überhaupt das Bild zur Verfügung gestellt wird. In Kiano werden zum einen Bilder in sehr kleiner Auflösung gecached, zum anderen wird beim Navigieren auf der Karte im Hintergrund ein neues Kartenteil als Backing-Image vorbereitet, das dem Nutzer nach Fertigstellung angezeigt wird. Die vorberechneten Kartenteile sind dabei drei Mal so breit und drei Mal so hoch wie das Display, so dass man diese „Hintergrundaktivität“ beim Verschieben der Karte in der Regel nicht bemerkt. Nur wenn die Bewegung zu schnell wird oder die Bilder zu langsam „geliefert“ werden, erkennt man schwarze Flächen, die sich dann verzögert mit Bildern füllen.

Vergleichbares passiert beim Hineinzoomen in die Karte. Der Nutzer sieht zunächst eine vergrößerte und damit unscharfe Version des aktuellen Kartenteils, während im Hintergrund ein Kartenteil in höherer Auflösung und mit weniger Bildern vorbereitet wird. In der Summe geht Kiano hier einen Kompromiss ein. Die Pixeldichte der Geräte würde eine schärfere Darstellung der Bilder auf der Karte erlauben. Allerdings müssten dann die Bilder in so höher Auflösung angefordert werden, dass eine flüssige Kartennavigation nicht mehr möglich wäre. So sieht der Nutzer in der Regel eine Karte mit Bildern in halber Auflösung gemessen an den physikalischen Pixeln seines Displays.

Ein anfangs unterschätzter Arbeitsaufwand bei der Umsetzung von Kiano liegt darin begründet, dass sich die Photo Library des Nutzers jederzeit während der Benutzung der App verändern kann. Bilder können durch Synchronisationen mit der iCloud oder mit iTunes verschwinden, sich in andere Alben bewegen, oder neue können auftauchen. Der Nutzer kann Bildschirmfotos machen. Das Photos Framework stellt komfortable Benachrichtigungen für solche Events zur Verfügung. Der Implementierung obliegt es dabei aber herauszubekommen, ob die Karte neu zu sortieren ist oder nicht, ob das gerade anzeigte Bild überhaupt noch existiert und was zu tun ist, wenn es verschwunden ist.

Zusammenfassend kann man feststellen, dass natürlich die Umsetzung der Algorithmen und die Darstellung dessen auf einer Karte zu den spannendsten Teilen der Arbeiten an Kiano zählen, dass aber der Umgang mit einer sich dynamisch ändernden Datenbasis nicht unterschätzt werden sollte.

Autoren

Prof. Dr. Klaus JungProf. Dr. Klaus Jung studierte Physik an der TU Berlin, wo er im Bereich der Mathematischen Physik promovierte. Bis 2008 arbeitete er als Leiter F&E bei der Firma LuraTech im Bereich der Dokumentenverarbeitung und Langzeitarchivierung. In der JPEG-Gruppe leitete er die deutsche Delegation bei der Standardisierung von JPEG2000. Seit 2008 ist er Professor für Medieninformatik an der HTW Berlin mit dem Schwerpunkt „Visual Computing“.

Prof. Dr. Kai Uwe Barthel

Prof. Dr. Kai Uwe Barthel studierte Elektrotechnik an der TU Berlin, bevor er Assistent am Institut für Nachrichtentechnik wurde und im Bereich Bildkompression promovierte. Seit 2001 ist er Professor der HTW Berlin. Hauptforschungsbereiche sind visuelle Bildsuche und automatisches Bildverstehen. 2009 gründete er die pixolution GmbH www.pixolution.de, ein Unternehmen, das Technologien für die visuelle Bildsuche anbietet.

Einstieg in Natural Language Processing – Teil 1: Natürliche vs. Formale Sprachen

Dies ist Artikel 1 von 4 der Artikelserie Einstieg in Natural Language Processing – Artikelserie.

Versuche und erste Ansätze, Maschinen beizubringen menschliche Sprache zu verstehen, gibt es bereits seit den 50er Jahren. Trotz der jahrzehntelangen Forschung und Entwicklung gelingt dies bis heute nicht umfassend. Woran liegt dies?

Um diese Frage zu beantworten, hilft es, sich die Unterschiede zwischen „natürlichen“, also sich selbstständig entwickelnden, typischerweise von Menschen gesprochenen Sprachen und den von Computern interpretieren formalen Sprachen klar zu machen. Formale Sprachen, wie zum Beispiel Python zum Ausführen der Codebeispiele in dieser Artikelserie, HTML (Hyper Text Markup Language) zur Darstellung von Webseiten und andere typische Programmier- und Skriptsprachen, sind üblicherweise sehr streng strukturiert.

Alle diese Sprachen weisen eine Reihe von Gemeinsamkeiten auf, welche es Computern einfach machen, sie korrekt zu interpretieren (also den Informationsinhalt zu “verstehen”). Das vermutlich auffälligste Merkmal formaler Sprachen ist eine relativ strikte Syntax, welche (wenn überhaupt) nur geringe Abweichungen von einem Standard erlaubt. Wie penibel die jeweilige Syntax oft einzuhalten ist, wird am ehesten deutlich, wenn diese verletzt wird:

Solche so genannten “Syntax Error”  gehören daher zu den häufigsten Fehlern beim Schreiben von Quellcode.

Ganz anders dagegen sieht es in der Kommunikation mit natürlichen Sprachen aus. Zwar fördert falsche Komma-Setzung in der Regel nicht die Leserlichkeit eines Textes, jedoch bleibt dieser in der Regel trotzdem verständlich. Auch macht es keinen Unterschied ob ich sage „Es ist heiß heute.“ oder „Heute ist es heiß.“. Genau wie in der deutschen Sprache funktioniert dieses Beispiel auch im Englischen sowie in anderen natürlichen Sprachen. Insbesondere Spanisch ist ein Beispiel für eine Sprache mit extrem variabler Satzstellung. Jedoch kann in anderen Fällen eine andere Reihenfolge der selben Worte deren Bedeutung auch verändern. So ist „Ist es heute heiß?“ ganz klar eine Frage, obwohl exakt die selben Worte wie in den Beispielsätzen oben vorkommen.

Ein weiterer wichtiger, hiermit verwandter Unterschied ist, dass es bei formalen Sprachen in der Regel einen Ausdruck gibt, welcher eine spezifische Bedeutung besitzt, während es in natürlichen Sprachen oft viele Synonyme gibt, die ein und dieselbe Sache (oder zumindest etwas sehr ähnliches) ausdrücken. Ein wahrer boolscher Wert wird in Python als

geschrieben. Es gibt keine andere Möglichkeit, diesen Wert auszudrücken (zumindest nicht ohne irgend eine Art von Operatoren wie das Doppelgleichheitszeichen zu benutzen und damit z. B. “0 == 0” zu schreiben).  Anders hingegen zum Beispiel in der Deutschen Sprache: Wahr, richtig, korrekt, stimmt, ja,

Um einen Vorstellung davon zu bekommen, wie verbreitet Synonyme in natürlichen Sprachen sind, lässt sich die Internetseite https://www.openthesaurus.de verwenden. Beispielshalber findet man dutzende Synonyme für das Wort „schnell“ hier: https://www.openthesaurus.de/synonyme/schnell

Eine weitere große Schwierigkeit, welche in den meisten natürlichen Sprachen und nahezu allen Arten von Texten zu finden ist, stellen verschiedene grammatikalische Formen eines Wortes dar. So sind die Worte bin, wäre, sind, waren, wirst, werden… alles Konjugationen desselben Verbs, nämlich sein. Eine durchaus beeindruckende Übersicht über die verwirrende Vielfalt von Konjugationen dieses kleinen Wörtchens, findet sich unter: https://www.verbformen.de/konjugation/sein.htm.

Dieses Problem wird um so schwerwiegender, da viele Verben, insbesondere die am häufigsten genutzten, sehr unregelmäßige Konjugationsformen besitzen und damit keiner generellen Regel folgen. Daher ist computerintern oft ein Mapping für jede mögliche Konjugationsform bei vielen Verben die einzige Möglichkeit, an die Grundform zu kommen (mehr dazu in Teil 3 dieser Artikelserie).

Die Liste der sprachlichen Schwierigkeiten beim computergestützten Auswerten natürlicher Sprache ließe sich an diesem Punkt noch beliebig weiter fortsetzen:

  • Rechtschreibfehler
  • falsche Grammatik
  • Smileys
  • der „Substantivverkettungswahn“ im Deutschen
  • mehrdeutige Worte und Abkürzungen
  • abwegige Redewendungen (z. B. “ins Gras beißen”)
  • Ironie
  • und, und, und …

Ob und welche Rolle jede dieser Schwierigkeiten im einzelnen spielt, hängt natürlich sehr stark von den jeweiligen Texten ab und kann nicht pauschalisiert werden – ein typischer Chatverlauf wird ganz andere Probleme bereithalten als ein Wikipedia-Artikel. Wie man einige dieser Probleme in der Praxis vereinfachen oder sogar lösen kann und welche Ansätze und Methoden zur Verfügung stehen und regelmäßig zur Anwendung kommen wird im nächsten Teil dieser Artikelserie an praktischen Codebeispielen genauer unter die Lupe genommen.

NLTK vs. Spacy – Eine kurze Übersicht

Möchte man einen (oder auch einige) Text(e) mit den Methoden des natural language processings untersuchen um die darin verwendete Sprache auswerten oder nach bestimmten Informationen suchen, so sind insbesondere die Pakete NLTK und spaCy zu empfehlen (bei sehr vielen Texten sieht das schon wieder anders aus und wird am Ende der Artikelserie mit dem Paket gensim vorgestellt); beide bieten eine unglaubliche Vielzahl von Analysemöglichkeiten, vorgefertigten Wortsets, vortrainierte Stemmer und Lemmatiser, POS Tagger und, und, und…

Ist man vor allem an den Ergebnissen der Analyse selbst interessiert, so bietet sich spaCy an, da hier bereits mit wenigen Zeilen Code viele interessante Informationen generiert werden können.

Wer dagegen gerne selber bastelt oder wissen möchte wie die einzelnen Tools und Teilschritte genau funktionieren oder sich seine eigenen Stemmer, Tagger ect. trainieren will, ist vermutlich mit NLTK besser beraten. Zwar ist hier oft mehr Quellcode für das gleiche Ergebnis notwendig, allerdings kann das Preprocessing der Texte hierbei relativ einfach exakt den eigenen Vorstellungen angepasst werden. Zudem bietet NLTK eine Vielzahl von Beispieltexten und bereits fertig getagte Daten, mit welchen eigene Tagger trainiert und getestet werden können.

Interview – Künstliche Intelligenz im Unternehmen & der Mangel an IT-Fachkräften

Interview mit Sebastian van der Meer über den Einsatz von künstlicher Intelligenz im Unternehmen und dem Mangel an IT-Fachkräften

Sebastian van der Meer

Sebastian van der Meer ist Managing Partner der lexoro Gruppe, einem Technologie- und Beratungsunternehmen in den Zukunftsmärkten: Data-Science, Machine-Learning, Big-Data, Robotics und DevOps. Das Leistungsspektrum ist vielschichtig. Sie vermitteln Top-Experten an Unternehmen (Perm & IT-Contracting), arbeiten mit eigenen Teams für innovative Unternehmen an spannenden IT-Projekten und entwickeln zugleich eigene Produkte und Start-Ups in Zukunftsmärkten. Dabei immer im Mittelpunkt: Menschen und deren Verbindung mit exzellenter Technologiekompetenz.

Data Science Blog: Herr van der Meer, wenn man Google News mit den richtigen Stichwörtern abruft, scheinen die Themen Künstliche Intelligenz, Data Science und Machine Learning bei vielen Unternehmen bereits angekommen zu sein – Ist das so?

Das ist eine sehr gute Frage! Weltweit, vor allem in der USA und China, sind diese bereits „angekommen“, wenn man es so formulieren kann. Allerdings sind wir in Europa leider weit hinterher. Dazu gibt es ja bereits viele Studien und Umfragen, die dies beweisen. Vereinzelt gibt es große mittelständische- und Konzernunternehmen in Deutschland, die bereits eigene Einheiten und Teams in diesen Bereich und auch neue Geschäftsbereiche dadurch ermöglicht haben. Hier gibt es bereits tolle Beispiele, was mit K.I. erreichbar ist. Vor allem die Branchen Versicherungs- und Finanzdienstleistungen, Pharma/Life Science und Automotive sind den anderen in Deutschland etwas voraus.

Data Science Blog: Wird das Thema Data Science oder Machine Learning früher oder später für jedes Unternehmen relevant sein? Muss jedes Unternehmen sich mit K.I. befassen?

Data Science, Machine Learning, künstliche Intelligenz – das sind mehr als bloße Hype-Begriffe und entfernte Zukunftsmusik! Wir stecken mitten in massiven strukturellen Veränderungen. Die Digitalisierungswelle der vergangenen Jahre war nur der Anfang. Jede Branche ist betroffen. Schnell kann ein Gefühl von Bedrohung und Angst vor dem Unbekannten aufkommen. Tatsächlich liegen aber nie zuvor dagewesene Chancen und Potentiale vor unseren Füßen. Die Herausforderung ist es diese zu erkennen und dann die notwendigen Veränderungen umzusetzen. Daher sind wir der Meinung, dass jedes Unternehmen sich damit befassen muss und soll, wenn es in der Zukunft noch existieren will.

Wir unterstützen Unternehmen dabei ihre individuellen Herausforderungen, Hürden und Möglichkeiten zu identifizieren, die der große Hype „künstliche Intelligenz“ mit sich bringt. Hier geht es darum genau zu definieren, welche KI-Optionen überhaupt für das Unternehmen existieren. Mit Use-Cases zeigen wir, welchen Mehrwert sie dem Unternehmen bieten. Wenn die K.I. Strategie festgelegt ist, unterstützen wir bei der technischen Implementierung und definieren und rekrutieren bei Bedarf die relevanten Mitarbeiter.

Data Science Blog: Die Politik strebt stets nach Vollbeschäftigung. Die K.I. scheint diesem Leitziel entgegen gerichtet zu sein. Glauben Sie hier werden vor allem Ängste geschürt oder sind die Auswirkungen auf den Arbeitsmarkt durch das Vordringen von K.I. wirklich so gravierend?

Zu diesem Thema gibt es bereits viele Meinungen und Studien, die veröffentlicht worden sind. Eine interessante Studie hat vorhergesagt, dass in den nächsten 5 Jahren, weltweit 1.3 Millionen Stellen/Berufe durch K.I. wegfallen werden. Dafür aber in den gleichen Zeitnahmen 1.7 Millionen neue Stellen und Berufe entstehen werden. Hier gehen die Meinungen aber ganz klar auseinander. Die Einen sehen die Chancen, die Möglichkeiten und die Anderen sehen die Angst oder das Ungewisse. Eins steht fest, der Arbeitsmarkt wird sich in den nächsten 5 bis 10 Jahren komplett verändern und anpassen. Viele Berufe werden wegfallen, dafür werden aber viele neue Berufe hinzukommen. Vor einigen Jahren gab es noch keinen „Data Scientist“ Beruf und jetzt ist es einer der best bezahltesten IT Stellen in Unternehmen. Allein das zeigt doch auch, welche Chancen es in der Zukunft geben wird.

Data Science Blog: Wie sieht der Arbeitsmarkt in den Bereichen Data Science, Machine Learning und Künstliche Intelligenz aus?

Der Markt ist sehr intransparent. Jeder definiert einen Data Scientist anders. Zudem wird sich der Beruf und seine Anforderungen aufgrund des technischen Fortschritts stetig verändern. Der heutige Data Scientist wird sicher nicht der gleiche Data Scientist in 5 oder 10 Jahren sein. Die Anforderungen sind enorm hoch und die Konkurrenz, der sogenannte „War of Talents“ ist auch in Deutschland angekommen. Der Anspruch an Veränderungsbereitschaft und technisch stets up to date und versiert zu sein, ist extrem hoch. Das gleiche gilt auch für die anderen K.I. Berufe von heute, wie z.B. den Computer Vision Engineer, der Robotics Spezialist oder den DevOps Engineer.

Data Science Blog: Worauf sollten Unternehmen vor, während und nach der Einstellung von Data Scientists achten?

Das Allerwichtigste ist der Anfang. Es sollte ganz klar definiert sein, warum die Person gesucht wird, was die Aufgaben sind und welche Ergebnisse sich das Unternehmen mit der Einstellung erwartet bzw. erhofft. Oftmals hören wir von Unternehmen, dass sie Spezialisten in dem Bereich Data Science / Machine Learning suchen und große Anforderungen haben, aber diese gar nicht umgesetzt werden können, weil z.B. die Datengrundlage im Unternehmen fehlt. Nur 5% der Data Scientists in unserem Netzwerk sind der Ansicht, dass vorhandene Daten in ihrem Unternehmen bereits optimal verwertet werden. Der Data Scientist sollte schnell ins Unternehmen integriert werde um schnellstmöglich Ergebnisse erzielen zu können. Um die wirklich guten Leute für sich zu gewinnen, muss ein Unternehmen aber auch bereit sein finanziell tiefer in die Tasche zu greifen. Außerdem müssen die Unternehmen den top Experten ein technisch attraktives Umfeld bieten, daher sollte auch die Unternehmen stets up-to-date sein mit der heutigen Technologie.

Data Science Blog: Was macht einen guten Data Scientist eigentlich aus?

Ein guter Data Scientist sollte in folgenden Bereichen sehr gut aufgestellt sein: Präsentations- und Kommunikationsfähigkeiten, Machine Learning Kenntnisse, Programmiersprachen und ein allgemeines Business-Verständnis. Er sollte sich stets weiterentwickeln und von den Trends up to date sein. Auf relevanten Blogs, wie dieser Data Science Blog, aktiv sein und sich auf Messen/Meetups etc bekannt machen.

Außerdem sollte er sich mit uns in Verbindung setzen. Denn ein weiterer, wie wir finden, sehr wichtiger Punkt, ist es sich gut verkaufen zu können. Hierzu haben wir uns in dem letzten Jahr sehr viel Gedanken gemacht und auch Studien durchgeführt. Wir wollen es jedem K.I. -Experten ermöglichen einen eigenen Fingerabdruck zu haben. Bei uns ist dies als der SkillPrint bekannt. Hierfür haben wir eine holistische Darstellung entwickelt, die jeden Kandidaten einen individuellen Fingerabdruck seiner Kompetenzen abbildet. Hierfür durchlaufen die Kandidaten einen Online-Test, der von uns mit top K.I. Experten entwickelt wurde. Dieser bildet folgendes ab: Methoden Expertise, Applied Data Science Erfahrung, Branchen know-how, Technology & Tools und Business knowledge. Und die immer im Detail in 3 Ebenen.

Der darauf entstehende SkillPrint/Fingerprint ist ein Qualitätssigel für den Experten und damit auch für das Unternehmen, das den Experten einstellt.

Interesse an einem Austausch zu verschiedenen Karriereperspektiven im Bereich Data Science/ Machine Learning? Dann registrieren Sie sich direkt auf dem lexoro Talent Check-In und ein lexoro-Berater wird sich bei Ihnen melden.

Einstieg in Natural Language Processing – Artikelserie

Unter Natural Language Processing (NLP) versteht man ein Teilgebiet der Informatik bzw. der Datenwissenschaft, welches sich mit der Analyse und Auswertung , aber auch der Synthese natürlicher Sprache befasst. Mit natürlichen Sprachen werden Sprachen wie zum Beispiel Deutsch, Englisch oder Spanisch bezeichnet, welche nicht geplant entworfen wurden, sondern sich über lange Zeit allein durch ihre Benutzung entwickelt haben. Anders ausgedrückt geht es um die Schnittstelle zwischen unserer im Alltag verwendeten und für uns Menschen verständlichen Sprache auf der einen, und um deren computergestützte Auswertung auf der anderen Seite.

Diese Artikelserie soll eine Einführung in die Thematik des Natural Language Processing sein, dessen Methoden, Möglichkeiten, aber auch der Grenzen . Im einzelnen werden folgende Themen näher behandelt:

1. Artikel – Natürliche vs. Formale Sprachen
2. Artikel – Preprocessing von Rohtext mit Python
3. Artikel – Möglichkeiten/Methoden der Textanalyse an Beispielen (erscheint demnächst…)
4. Artikel – NLP, was kann es? Und was nicht? (erscheint demnächst…)

Zur Verdeutlichung der beschriebenen Zusammenhänge und Methoden und um Interessierten einige Ideen für mögliche Startpunkte aufzuzeigen, werden im Verlauf der Artikelserie an verschiedenen Stellen Codebeispiele in der Programmiersprache Python vorgestellt.
Von den vielen im Internet zur Verfügung stehenden Python-Paketen zum Thema NLP, werden in diesem Artikel insbesondere die drei Pakete NLTK, Gensim und Spacy verwendet.

I. Einführung in TensorFlow: Einleitung und Inhalt

 

 

 

1. Einleitung und Inhalt

Früher oder später wird jede Person, welche sich mit den Themen Daten, KI, Machine Learning und Deep Learning auseinander setzt, mit TensorFlow in Kontakt geraten. Für diejenigen wird der Zeitpunkt kommen, an dem sie sich damit befassen möchten/müssen/wollen.

Und genau für euch ist diese Artikelserie ausgelegt. Gemeinsam wollen wir die ersten Schritte in die Welt von Deep Learning und neuronalen Netzen mit TensorFlow wagen und unsere eigenen Beispiele realisieren. Dabei möchten wir uns auf das Wesentlichste konzentrieren und die Thematik Schritt für Schritt in 4 Artikeln angehen, welche wie folgt aufgebaut sind:

  1. In diesem und damit ersten Artikel wollen wir uns erst einmal darauf konzentrieren, was TensorFlow ist und wofür es genutzt wird.
  2. Im zweiten Artikel befassen wir uns mit der grundlegenden Handhabung von TensorFlow und gehen den theoretischen Ablauf durch.
  3. Im dritten Artikel wollen wir dann näher auf die Praxis eingehen und ein Perzeptron – ein einfaches künstliches Neuron – entwickeln. Dabei werden wir die Grundlagen anwenden, die wir im zweiten Artikel erschlossen haben.

Wenn ihr die Praxisbeispiele in den Artikeln 3 & 4 aktiv mit bestreiten wollt, dann ist es vorteilhaft, wenn ihr bereits mit Python gearbeitet habt und die Grundlagen dieser Programmiersprache beherrscht. Jedoch werden alle Handlungen und alle Zeilen sehr genau kommentiert, so dass es leicht verständlich bleibt.

Neben den Programmierfähigkeiten ist es hilfreich, wenn ihr euch mit der Funktionsweise von neuronalen Netzen auskennt, da wir im späteren Verlauf diese modellieren wollen. Jedoch gehen wir vor der Programmierung  kurz auf die Theorie ein und werden das Wichtigste nochmal erwähnen.

Zu guter Letzt benötigen wir für unseren Theorie-Teil ein Mindestmaß an Mathematik um die Grundlagen der neuronalen Netze zu verstehen. Aber auch hier sind die Anforderungen nicht hoch und wir sind vollkommen gut  damit bedient, wenn wir unser Wissen aus dem Abitur noch nicht ganz vergessen haben.

2. Ziele dieser Artikelserie

Diese Artikelserie ist speziell an Personen gerichtet, welche einen ersten Schritt in die große und interessante Welt von Deep Learning wagen möchten, die am Anfang nicht mit zu vielen Details überschüttet werden wollen und lieber an kleine und verdaulichen Häppchen testen wollen, ob dies das Richtige für sie ist. Unser Ziel wird sein, dass wir ein Grundverständnis für TensorFlow entwickeln und die Grundlagen zur Nutzung beherrschen, um mit diesen erste Modelle zu erstellen.

3. Was ist TensorFlow?

Viele von euch haben bestimmt von TensorFlow in Verbindung mit Deep Learning bzw. neuronalen Netzen gehört. Allgemein betrachtet ist TensorFlow ein Software-Framework zur numerischen Berechnung von Datenflussgraphen mit dem Fokus maschinelle Lernalgorithmen zu beschreiben. Kurz gesagt: Es ist ein Tool um Deep Learning Modelle zu realisieren.

Zusatz: Python ist eine Programmiersprache in der wir viele Paradigmen (objektorientiert, funktional, etc.) verwenden können. Viele Tutorials im Bereich Data Science nutzen das imperative Paradigma; wir befehlen Python also Was gemacht und Wie es ausgeführt werden soll. TensorFlow ist dahingehend anders, da es eine datenstrom-orientierte Programmierung nutzt. In dieser Form der Programmierung wird ein Datenfluss-Berechnungsgraph (kurz: Datenflussgraph) erzeugt, welcher durch die Zusammensetzung von Kanten und Knoten charakterisiert wird. Die Kanten enthalten Daten und können diese an Knoten weiterleiten. In den Knoten werden Operationen wie z. B. Addition, Multiplikation oder auch verschiedenste Variationen von Funktionen ausgeführt. Bekannte Programme mit datenstrom-orientierten Paradigmen sind Simulink, LabView oder Knime.

Für das Verständnis von TensorFlow verrät uns der Name bereits erste Informationen über die Funktionsweise. In neuronalen Netzen bzw. in Deep-Learning-Netzen können Eingangssignale, Gewichte oder Bias verschiedene Erscheinungsformen haben; von Skalaren, zweidimensionalen Tabellen bis hin zu mehrdimensionalen Matrizen kann alles dabei sein. Diese Erscheinungsformen werden in Deep-Learning-Anwendungen allgemein als Tensoren bezeichnet, welche durch ein Datenflussgraph ‘fließen’. [1]

Abb.1 Namensbedeutung von TensorFlow: Links ein Tensor in Form einer zweidimensionalen Matrix; Rechts ein Beispiel für einen Datenflussgraph

 

4. Warum TensorFlow?

Wer in die Welt der KI einsteigen und Deep Learning lernen will, hat heutzutage die Qual der Wahl. Neben TensorFlow gibt es eine Vielzahl von Alternativen wie Keras, Theano, Pytorch, Torch, Caffe, Caffe2, Mxnet und vielen anderen. Warum also TensorFlow?

Das wohl wichtigste Argument besteht darin, dass TensorFlow eine der besten Dokumentationen hat. Google – Herausgeber von TensorFlow – hat TensorFlow stets mit neuen Updates beliefert. Sicherlich aus genau diesen Gründen ist es das meistgenutzte Framework. Zumindest erscheint es so, wenn wir die Stars&Forks auf Github betrachten. [3] Das hat zur Folge, dass neben der offiziellen Dokumentation auch viele Tutorials und Bücher existieren, was die Doku nur noch besser macht.

Natürlich haben alle Frameworks ihre Vor- und Nachteile. Gerade Pytorch von Facebook erfreut sich derzeit großer Beliebtheit, da die Berechnungsgraphen dynamischer Natur sind und damit einige Vorteile gegenüber TensorFlow aufweisen.[2] Auch Keras wäre für den Einstieg eine gute Alternative, da diese Bibliothek großen Wert auf eine einsteiger- und nutzerfreundliche Handhabung legt. Keras kann man sich als eine Art Bedienoberfläche über unsere Frameworks vorstellen, welche vorgefertigte neuronale Netze bereitstellt und uns einen Großteil der Arbeit abnimmt.

Möchte man jedoch ein detailreiches und individuelles Modell bauen und die Theorie dahinter nachvollziehen können, dann ist TensorFlow der beste Einstieg in Deep Learning! Es wird einige Schwierigkeiten bei der Gestaltung unserer Modelle geben, aber durch die gute Dokumentation, der großen Community und der Vielzahl an Beispielen, werden wir gewiss eine Lösung für aufkommende Problemstellungen finden.

 

Abb.2 Beliebtheit von DL-Frameworks basierend auf Github Stars & Forks (10.06.2018)

 

5. Zusammenfassung und Ausblick

Fassen wir das Ganze nochmal zusammen: TensorFlow ist ein Framework, welches auf der datenstrom-orientierten Programmierung basiert und speziell für die Implementierung von Machine/Deep Learning-Anwendungen ausgelegt ist. Dabei fließen unsere Daten durch eine mehr oder weniger komplexe Anordnung von Berechnungen, welche uns am Ende ein Ergebnis liefert.

Die wichtigsten Argumente zur Wahl von TensorFlow als Einstieg in die Welt des Deep Learnings bestehen darin, dass TensorFlow ausgezeichnet dokumentiert ist, eine große Community besitzt und relativ einfach zu lesen ist. Außerdem hat es eine Schnittstelle zu Python, welches durch die meisten Anwender im Bereich der Datenanalyse bereits genutzt wird.

Wenn ihr es bis hier hin geschafft habt und immer noch motiviert seid den Einstieg mit TensorFlow zu wagen, dann seid gespannt auf den nächsten Artikel. In diesem werden wir dann auf die Funktionsweise von TensorFlow eingehen und einfache Berechnungsgraphen aufbauen, um ein Grundverständnis von TensorFlow zu bekommen. Bleibt also gespannt!

Quellen

[1] Hope, Tom (2018): Einführung in TensorFlow: DEEP-LEARNING-SYSTEME PROGRAMMIEREN, TRAINIEREN, SKALIEREN UND DEPLOYEN, 1. Auflage

[2] https://www.marutitech.com/top-8-deep-learning-frameworks/

[3] https://github.com/mbadry1/Top-Deep-Learning

[4] https://www.bigdata-insider.de/was-ist-keras-a-726546/