Language Detecting with sklearn by determining Letter Frequencies

Of course, there are better and more efficient methods to detect the language of a given text than counting its lettes. On the other hand this is a interesting little example to show the impressing ability of todays machine learning algorithms to detect hidden patterns in a given set of data.

For example take the sentence:

“Ceci est une phrase française.”

It’s not to hard to figure out that this sentence is french. But the (lowercase) letters of the same sentence in a random order look like this:


Still sure it’s french? Regarding the fact that this string contains the letter “ç” some people could have remembered long passed french lessons back in school and though might have guessed right. But beside the fact that the french letter “ç” is also present for example in portuguese, turkish, catalan and a few other languages, this is still a easy example just to explain the problem. Just try to guess which language might have generated this:


While this looks simply confusing to the human eye and it seems practically impossible to determine the language it was generated from, this string still contains as set of hidden but well defined patterns from which the language could be predictet with almost complete (ca. 98-99%) certainty.

First of all, we need a set of texts in the languages our model should be able to recognise. Luckily with the package NLTK there comes a big set of example texts which actually are protocolls of the european parliament and therefor are publicly availible in 11 differen languages:

  •  Danish
  •  Dutch
  •  English
  •  Finnish
  •  French
  •  German
  •  Greek
  •  Italian
  •  Portuguese
  •  Spanish
  •  Swedish

Because the greek version is not written with the latin alphabet, the detection of the language greek would just be too simple, so we stay with the other 10 languages availible. To give you a idea of the used texts, here is a little sample:

“Resumption of the session I declare resumed the session of the European Parliament adjourned on Friday 17 December 1999, and I would like once again to wish you a happy new year in the hope that you enjoyed a pleasant festive period.
Although, as you will have seen, the dreaded ‘millennium bug’ failed to materialise, still the people in a number of countries suffered a series of natural disasters that truly were dreadful.”

Train and Test

The following code imports the nessesary modules and reads the sample texts from a set of text files into a pandas.Dataframe object and prints some statistics about the read texts:

Above you see a sample set of random rows of the created Dataframe. After removing very short text snipplets (less than 200 chars) we are left with 56481 snipplets. The function clean_eutextdf() then creates a lower case representation of the texts in the coloum ‘ltext’ to facilitate counting the chars in the next step.
The following code snipplet now extracs the features – in this case the relative frequency of each letter in every text snipplet – that are used for prediction:

Now that we have calculated the features for every text snipplet in our dataset, we can split our data set in a train and test set:

After doing that, we can train a k-nearest-neigbours classifier and test it to get the percentage of correctly predicted languages in the test data set. Because we do not know what value for k may be the best choice, we just run the training and testing with different values for k in a for loop:

As you can see in the output the reliability of the language classifier is generally very high: It starts at about 97.5% for k = 1, increases for with increasing values of k until it reaches a maximum level of about 98.5% at k ≈ 10.

Using the Classifier to predict languages of texts

Now that we have trained and tested the classifier we want to use it to predict the language of example texts. To do that we need two more functions, shown in the following piece of code. The first one extracts the nessesary features from the sample text and predict_lang() predicts the language of a the texts:

With this classifier it is now also possible to predict the language of the randomized example snipplet from the introduction (which is acutally created from the first paragraph of this article):

The KNN classifier of sklearn also offers the possibility to predict the propability with which a given classification is made. While the probability distribution for a specific language is relativly clear for long sample texts it decreases noticeably the shorter the texts are.

Background and Insights

Why does a relative simple model like counting letters acutally work? Every language has a specific pattern of letter frequencies which can be used as a kind of fingerprint: While there are almost no y‘s in the german language this letter is quite common in english. In french the letter k is not very common because it is replaced with q in most cases.

For a better understanding look at the output of the following code snipplet where only three letters already lead to a noticable form of clustering:


Even though every single letter frequency by itself is not a very reliable indicator, the set of frequencies of all present letters in a text is a quite good evidence because it will more or less represent the letter frequency fingerprint of the given language. Since it is quite hard to imagine or visualize the above plot in more than three dimensions, I used a little trick which shows that every language has its own typical fingerprint of letter frequencies:

What more?

Beside the fact, that letter frequencies alone, allow us to predict the language of every example text (at least in the 10 languages with latin alphabet we trained for) with almost complete certancy there is even more information hidden in the set of sample texts.

As you might know, most languages in europe belong to either the romanian or the indogermanic language family (which is actually because the romans conquered only half of europe). The border between them could be located in belgium, between france and germany and in swiss. West of this border the romanian languages, which originate from latin, are still spoken, like spanish, portouguese and french. In the middle and northern part of europe the indogermanic languages are very common like german, dutch, swedish ect. If we plot the analysed languages with a different colour sheme this border gets quite clear and allows us to take a look back in history that tells us where our languages originate from:

As you can see the more common letters, especially the vocals like a, e, i, o and u have almost the same frequency in all of this languages. Far more interesting are letters like q, k, c and w: While k is quite common in all of the indogermanic languages it is quite rare in romanic languages because the same sound is written with the letters q or c.
As a result it could be said, that even “boring” sets of data (just give it a try and read all the texts of the protocolls of the EU parliament…) could contain quite interesting patterns which – in this case – allows us to predict quite precisely which language a given text sample is written in, without the need of any translation program or to speak the languages. And as an interesting side effect, where certain things in history happend (or not happend): After two thousand years have passed, modern machine learning techniques could easily uncover this history because even though all these different languages developed, they still have a set of hidden but common patterns that since than stayed the same.

Neuronale Netzwerke zur Spam-Erkennung

Die Funktionsweise der in immer mehr Anwendungen genutzten neuronalen Netzwerke stieß bei weniger technik-affinen Menschen bislang nur auf wenig Interesse. Geschuldet wird das sicher vor allem der eher trockenen Theorie, die hinter diesen Konstrukten steht und die sich für die meisten nicht auf Anhieb erschließt. Ein populäres Beispiel für die Fähigkeiten, die ein solches neuronales Netzwerk bereits heute hat, lieferte in jüngster Zeit Googles “Inception”, welches ohne den Anspruch auf einen praktischen Nutzen eigenständig eine spektakuläre Bilderwelt kreierte, die auch Menschen ohne großes Interesse an den dahinter steckenden Technologien ins Staunen versetzte. Ansonsten bieten sich die neuronalen Netze vor allem überall dort an, wo wenig systematisches Wissen zur Verfügung steht, wie etwa bei der Bilderkennung und der Text- bzw. Sprachanalyse.

Weniger effektheischend, als die Ergebnisse von “Inception”, dafür jedoch überaus hilfreich für den vernetzten Alltag, sind neuronale Netzwerke, die zum Aufspüren und zur Kategorisierung von Spam-Seiten entwickelt werden. In diesem Anwendungsbereich können diese ein wertvolles Werkzeug sein.

Wie bei allen selbstlernenden Netzwerken muss dafür zunächst ein Grundgerüst aufgebaut werden, welches später von Hand mit Informationen gefüttert wird, bis es schließlich in der Lage ist, sich selbstständig weiter zu entwickeln, hinzuzulernen und auf diese Weise immer genauere Ergebnisse liefert.

Die Auswahl der Kriterien

Unerwünschte Webseiten mit störenden und oft illegalen Inhalten findet man im Internet zu Hauf und meist locken sie mit dubiosen Angeboten für vermeintliche Wundermittel oder gaukeln leichtgläubigen Nutzern vor, man könne ohne großes Zutun viel Geld verdienen – meist ohne ein tatsächliches Produkt oder eine Dienstleistung dahinter. Ein entsprechend programmiertes neuronales Netzwerk spürt diese Seiten anhand von bestimmten Faktoren automatisch auf. Als Trainingsdaten werden dafür zunächst von Hand Kriterien wie die Registrierungs-IP, der Nutzername und die verwendete Sprachversion eingegeben. Da das Netzwerk nur mit den Zahlen 0 und 1 arbeiten kann, müssen diese Datensätze zuvor manuell aufbereitet werden. Indem alle gewünschten Registrierungs-IPs erst auf den jeweiligen Internetdienstanbieter abgebildet werden und der Grad ihrer jeweiligen Spammigkeit von Hand bestimmt wird, lässt sich der jeweilige Durchschnitt der “Spammigkeit” eines Internetdienstanbieters berechnen. Teilt man die Anzahl der Spammer durch die Gesamtnutzerzahl eines einzelnen Anbieters, erhält man bereits ein Ergebnis, das sich zur Eingabe in das neuronale Netzwerk eignet. Ähnlich kann z. B. bei der Kombination aus Geolocation und Sprachversion verfahren werden. Mit einer Vielzahl weiterer Faktoren kann die Effizienz des neuronalen Netzwerks verbessert werden. So lassen sich etwa große Unterschiede bei dem Herkunftsland feststellen, in dem die Spam-Seiten angesiedelt sind. Ein besonders großes Erkennungspotential bieten bestimmte Keywords und Keyword-Kombinationen, die mitunter eindeutige Rückschlüsse auf ein Spam-Angebot ziehen lassen. Befindet sich z. B. die Wortkombination “Geld verdienen” besonders häufig auf einer Seite, ist dies ein recht deutliches Kriterium für die Klassifizierung als Spam. Doch auch weniger offensichtliche Faktoren helfen dem neuronalen Netzwerk dabei, hellhörig zu werden: Ein ungewöhnliches Verhältnis zwischen Vokalen und Konsonanten oder auch Seitennamen, die vermehrt Zahlen und unübliche Zeichen beinhalten, können die Spam-Wahrscheinlichkeit steigern. Kommt die verwendete IP-Adresse aus einem anonymisierten Netzwerk oder VPN, schürt dies ebenfalls den Verdacht auf unseriöse Inhalte.

Erstellung einer Korrelationsmatrix

Da jedes der einbezogenen Kriterien zur Bestimmung der Spammigkeit einer Seite eine unterschiedlich hohe Relevanz hat, müssen die einzelnen Faktoren verschieden stark gewichtet werden. Damit das neuronale Netzwerk genau das tun kann, wird deshalb eine Korrelationsmatrix erstellt. In dieser Matrix werden alle gesammelten Kriterien in Verbindung zueinander gesetzt, um es dem Netzwerk zu ermöglichen, nicht jeden Punkt nur einzeln zu werten. So ist ein Keyword wie z. B. “100 mg” an sich vergleichsweise unverdächtig. Stammt die Seite, auf der das Wort vorkommt jedoch aus einer Gegend, in der erfahrungsgemäß viele unseriöse Arzneimittelanbieter angesiedelt sind, kann dies die Spam-Wahrscheinlichkeit erhöhen.

Libraries für die Implementierung

Ein wertvolles Tool, das sich für die Implementierung des jeweiligen neuronalen Netzwerks eignet, ist die Open Source Machine Learning Library “Tensor Flow” von Google. Diese Programmierschnittstelle der zweiten Generation verfügt über einige handfeste Vorteile gegenüber anderen Libraries und ermöglicht die Parallelisierung der Arbeit. Berechnet wird sie auf der schnellen GPU des Rechners, was in direkten Vergleichen die Rechenzeit um ein Vielfaches senken konnte. Bewährt hat sich “Tensor Flow” bereits in zahlreichen kommerziellen Diensten von Google, darunter Spracherkennungssoftware, Google Photos, und Gmail.

Für eine bessere Abstraktion des Netzwerks, können zusätzlich zu der hinteren mehrere weitere Schichten angelegt werden. Die hintere Schicht bleibt dabei oft die einzige, die von außerhalb sichtbar ist.

Die Optimierung des neuronalen Netzwerks

Es liegt in der Natur der Sache, dass ein eigenständig lernfähiges Netzwerk nicht von Anfang an durch höchste Zuverlässigkeit hinsichtlich seiner Trefferquote besticht. Zum Lernen gehört Erfahrung und die muss das Netz erst noch sammeln. Zwar gelingt es auch einem noch frisch programmierten Netzwerk bereits die Erfüllung seiner Aufgabe oft recht gut, die Fehlerquote kann jedoch im Laufe der Zeit immer weiter verbessert werden. Gerade am Anfang werden noch viele Spam-Seiten nicht erkannt und einige vermeintliche Spammer stellen sich bei der Überprüfung durch den Menschen als unbedenklich heraus. Darum ist es für die Steigerung der Effizienz praktisch unerlässlich, immer wieder von Hand einzugreifen, falsche Ergebnisse zu korrigieren und dem Netzwerk auf diese Weise zu helfen.

Machine Learning mit Python – Minimalbeispiel

Maschinelles Lernen (Machine Learning) ist eine Gebiet der Künstlichen Intelligenz (KI, bzw. AI von Artificial Intelligence) und der größte Innovations- und Technologietreiber dieser Jahre. In allen Trendthemen – wie etwa Industrie 4.0 oder das vernetzte und selbstfahrende Auto – spielt die KI eine übergeordnete Rolle. Beispielsweise werden in Unternehmen viele Prozesse automatisiert und auch Entscheidungen auf operativer Ebene von einer KI getroffen, zum Beispiel in der Disposition (automatisierte Warenbestellungen) oder beim Festsetzen von Verkaufspreisen.

Aufsehen erregte Google mit seiner KI namens AlphaGo, einem Algortihmus, der den Weltmeister im Go-Spiel in vier von fünf Spielen besiegt hatte. Das Spiel Go entstand vor mehr als 2.500 Jahren in China und ist auch heute noch in China und anderen asiatischen Ländern ein alltägliches Gesellschaftsspiel. Es wird teilweise mit dem westlichen Schach verglichen, ist jedoch einfacher und komplexer zugleich (warum? das wird im Google Blog erläutert). Machine Learning kann mit einer Vielzahl von Methoden umgesetzt werden, werden diese Methoden sinnvoll miteinander kombiniert, können durchaus äußerst komplexe KIs erreicht werden.  Der aktuell noch gängigste Anwendungsfall für Machine Learning ist im eCommerce zu finden und den meisten Menschen als die Produktvorschläge von bekannt: Empfehlungsdienste (Recommender System).

Klassifikation via K-Nearest Neighbour Algorithmus

Ein häufiger Zweck des maschinellen Lernens ist, technisch gesehen, die Klassifikation von Daten in Abhängigkeit von anderen Daten. Es gibt mehrere ML-Algorithmen, die eine Klassifikation ermöglichen, die wohl bekannteste Methode ist der k-Nearest-Neighbor-Algorithmus (Deutsch:„k-nächste-Nachbarn”), häufig mit “kNN” abgekürzt. Das von mir interviewte FinTech StartUp Number26 nutzt diese Methodik beispielsweise zur Klassifizierung von Finanztransaktionen.

Um den Algorithmus Schritt für Schritt aufbauen zu können, müssen wir uns

Natürlich gibt es in Python, R und anderen Programmiersprachen bereits fertige Bibliotheken, die kNN bereits anbieten, denen quasi nur Matrizen übergeben werden müssen. Am bekanntesten ist wohl die scikit-learn Bibliothek für Python, die mehrere Nächste-Nachbarn-Modelle umfasst. Mit diesem Minimalbeispiel wollen wir den grundlegenden Algorithmus von Grund auf erlernen. Wir wollen also nicht nur machen, sondern auch verstehen.

Vorab: Verwendete Bibliotheken

Um den nachstehenden Python-Code (Python 3.x, sollte allerdings auch mit Python 2.7 problemlos funktionieren) ausführen zu können, müssen folgende Bibliotheken  eingebunden werden:

Übrigens: Eine Auflistung der wohl wichtigsten Pyhton-Bibliotheken für Datenanalyse und Datenvisualisierung schrieb ich bereits hier.

Schritt 1 – Daten betrachten und Merkmale erkennen

Der erste Schritt ist tatsächlich der aller wichtigste, denn erst wenn der Data Scientist verstanden hat, mit welchen Daten er es zu tun hat, kann er die richtigen Entscheidungen treffen, wie ein Algorithmus richtig abgestimmt werden kann und ob er für diese Daten überhaupt der richtige ist.

In der Realität haben wir es oft mit vielen verteilten Daten zu tun, in diesem Minimalbeispiel haben wir es deutlich einfacher: Der Beispiel-Datensatz enthält Informationen über Immobilien über vier Spalten.

  • Quadratmeter: Größe der nutzbaren Fläche der Immobilie in der Einheit m²
  • Wandhoehe: Höhe zwischen Fußboden und Decke innerhalb der Immobilie in der Einheit m
  • IA_Ratio: Verhältnis zwischen Innen- und Außenflächen (z. B. Balkon, Garten)
  • Kategorie: Enthält eine Klassifizierung der Immobilie als “Haus”, “Wohnung” und “Büro”



[box]Hinweis für Python-Einsteiger: Die Numpy-Matrix ist speziell für Matrizen-Kalkulationen entwickelt. Kopfzeilen oder das Speichern von String-Werten sind für diese Datenstruktur nicht vorgesehen![/box]

Aufgerufen wird diese Funktion dann so:

Die Matrix mit den drei Spalten (Quadratmeter, Wandhohe, IA_Ratio) landen in der Variable “dataSet”.

Schritt 2 – Merkmale im Verhältnis zueinander perspektivisch betrachten

Für diesen Anwendungsfall soll eine Klassifizierung (und gewissermaßen die Vorhersage) erfolgen, zu welcher Immobilien-Kategorie ein einzelner Datensatz gehört. Im Beispieldatensatz befinden sich vier Merkmale: drei Metriken und eine Kategorie (Wohnung, Büro oder Haus). Es stellt sich zunächst die Frage, wie diese Merkmale zueinander stehen. Gute Ideen der Datenvisualisierung helfen hier fast immer weiter. Die gängigsten 2D-Visualisierungen in Python wurden von mir bereits hier zusammengefasst.

[box]Hinweis: In der Praxis sind es selten nur drei Dimensionen, mit denen Machine Learning betrieben wird. Das Feature-Engineering, also die Suche nach den richtigen Features in verteilten Datenquellen, macht einen wesentlichen Teil der Arbeit eines Data Scientists aus – wie auch beispielsweise Chief Data Scientist Klaas Bollhoefer (siehe Interview) bestätigt.[/box]

Die beiden Scatter-Plots zeigen, das Häuser (blau) in allen Dimensionen die größte Varianz haben. Büros (gelb) können größer und höher ausfallen, als Wohnungen (rot), haben dafür jedoch tendenziell ein kleineres IA_Ratio. Könnten die Kategorien (blau, gelb, rot) durch das Verhältnis innerhalb von einem der beiden Dimensionspaaren in dem zwei dimensionalen Raum exakt voneinander abgegrenzt werden, könnten wir hier stoppen und bräuchten auch keinen kNN-Algorithmus mehr. Da wir jedoch einen großen Überschneidungsbereich in beiden Dimensionspaaren haben (und auch Wandfläche zu IA_Ratio sieht nicht besser aus),

Eine 3D-Visualisierung eignet sich besonders gut, einen Überblick über die Verhältnisse zwischen den drei Metriken zu erhalten: (die Werte wurden hier bereits normalisiert, liegen also zwischen 0,00 und 1,00)

3D Scatter Plot in Python [Matplotlib]

Es zeigt sich gerade in der 3D-Ansicht recht deutlich, dass sich Büros und Wohnungen zum nicht unwesentlichen Teil überschneiden und hier jeder Algorithmus mit der Klassifikation in Probleme geraten wird, wenn uns wirklich nur diese drei Dimensionen zur Verfügung stehen.

Schritt 3 – Kalkulation der Distanzen zwischen den einzelnen Punkten

Bei der Berechnung der Distanz in einem Raum hilft uns der Satz des Pythagoras weiter. Die zu überbrückende Distanz, um von A nach B zu gelangen, lässt sich einfach berechnen, wenn man entlang der Raumdimensionen Katheten aufspannt.

c = \sqrt{a^2+ b^2}

Die Hypotenuse im Raum stellt die Distanz dar und berechnet sich aus der Wurzel aus der Summe der beiden Katheten im Quadrat. Die beiden Katheten bilden sich aus der Differenz der Punktwerte (q, p) in ihrer jeweiligen Dimension.Bei mehreren Dimensionen gilt der Satz entsprechend:

Distanz = \sqrt{(q_1-p_1)^2+(q_2-p_2)^2+…+(q_n-p_n)^2}

Um mit den unterschiedlichen Werte besser in ihrer Relation zu sehen, sollten sie einer Normalisierung unterzogen werden. Dabei werden alle Werte einer Dimension einem Bereich zwischen 0.00 und 1.00 zugeordnet, wobei 0.00 stets das Minimum und 1.00 das Maximum darstellt.

NormWert = \frac{Wert - Min}{Wertspanne} = \frac{Wert - Min}{Max - Min}

Die Funktion kann folgendermaßen aufgerufen werden:

Schritt 4 & 5 – Klassifikation durch Eingrenzung auf k-nächste Nachbarn

Die Klassifikation erfolgt durch die Kalkulation entsprechend der zuvor beschriebenen Formel für die Distanzen in einem mehrdimensionalen Raum, durch Eingrenzung über die Anzahl an k Nachbarn und Sortierung über die berechneten Distanzen.

Über folgenden Code rufen wir die Klassifikations-Funktion auf und legen die k-Eingrenzung fest, nebenbei werden Fehler gezählt und ausgewertet. Hier werden der Reihe nach die ersten 30 Zeilen verarbeitet:

Nur 30 Testdatensätze auszuwählen ist eigentlich viel zu knapp bemessen und hier nur der Übersichtlichkeit geschuldet. Besser ist für dieses Beispiel die Auswahl von 100 bis 300 Datensätzen. Die Ergebnisse sind aber bereits recht ordentlich, allerdings fällt dem Algorithmus – wie erwartet – noch die Unterscheidung zwischen Wohnungen und Büros recht schwer.

0 – klassifiziert wurde: Buero, richtige Antwort: Buero
1 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
2 – klassifiziert wurde: Buero, richtige Antwort: Buero
3 – klassifiziert wurde: Buero, richtige Antwort: Buero
4 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
5 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
6 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
7 – klassifiziert wurde: Wohnung, richtige Antwort: Buero
8 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
9 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
10 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
11 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
12 – klassifiziert wurde: Buero, richtige Antwort: Buero
13 – klassifiziert wurde: Wohnung, richtige Antwort: Buero
14 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
15 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
16 – klassifiziert wurde: Buero, richtige Antwort: Buero
17 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
18 – klassifiziert wurde: Haus, richtige Antwort: Haus
19 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
20 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
21 – klassifiziert wurde: Buero, richtige Antwort: Buero
22 – klassifiziert wurde: Buero, richtige Antwort: Buero
23 – klassifiziert wurde: Buero, richtige Antwort: Buero
24 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
25 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
26 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
27 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
28 – klassifiziert wurde: Wohnung, richtige Antwort: Wohnung
29 – klassifiziert wurde: Buero, richtige Antwort: Buero
Error Count: 2

Über weitere Tests wird deutlich, dass k nicht zu niedrig und auch nicht zu hoch gesetzt werden darf.

 Datensätze  k Fehler
 150 1   25
 150 3   23
 150 5   21
 150 20   26

Ein nächster Schritt wäre die Entwicklung eines Trainingprogramms, dass die optimale Konfiguration (k-Eingrenzung, Gewichtung usw.) ermittelt.

Fehlerraten herabsenken

Die Fehlerquote ist im Grunde niemals ganz auf Null herabsenkbar, sonst haben wir kein maschinelles Lernen mehr, sondern könnten auch feste Regeln ausmachen, die wir nur noch einprogrammieren (hard-coding) müssten. Wer lernt, macht auch Fehler! Dennoch ist eine Fehlerquote von 10% einfach zu viel für die meisten Anwendungsfälle. Was kann man hier tun?

  1. Den Algorithmus verbessern (z. B. optimale k-Konfiguration und Gewichtung finden)
  2. mehr Merkmale finden (= mehr Dimensionen)
  3. mehr Daten hinzuziehen (gut möglich, dass alleine dadurch z. B. Wohnungen und Büros besser unterscheidbar werden)
  4. einen anderen Algorithmus probieren (kNN ist längst nicht für alle Anwendungen ideal!)

Das Problem mit den Dimensionen

Theoretisch kann kNN mit undenklich vielen Dimensionen arbeiten, allerdings steigt der Rechenaufwand damit auch ins unermessliche. Der k-nächste-Nachbar-Algorithmus ist auf viele Daten und Dimensionen angewendet recht rechenintensiv.

In der Praxis hat nicht jedes Merkmal die gleiche Tragweite in ihrer Bedeutung für die Klassifikation und mit jeder weiteren Dimension steigt auch die Fehleranfälligkeit, insbesondere durch Datenfehler (Rauschen). Dies kann man sich bei wenigen Dimensionen noch leicht bildlich vorstellen, denn beispielsweise könnten zwei Punkte in zwei Dimensionen nahe beieinander liegen, in der dritten Dimension jedoch weit auseinander, was im Ergebnis dann eine lange Distanz verursacht. Wenn wir beispielsweise 101 Dimensionen berücksichtigen, könnten auch hier zwei Punkte in 100 Dimensionen eng beieinander liegen, läge jedoch in der 101. Dimension (vielleicht auch auf Grund eines Datenfehlers) eine lange Distanz vor, wäre die Gesamtdistanz groß. Mit Gewichtungen könnten jedoch als wichtiger einzustufenden Dimensionen bevorzugt werden und als unsicher geltende Dimensionen entsprechend entschärft werden.

Je mehr Dimensionen berücksichtigt werden sollen, desto mehr Raum steht zur Verfügung, so dass um wenige Datenpunkte viel Leerraum existiert, der dem Algorithmus nicht weiterhilft. Je mehr Dimensionen berücksichtigt werden, desto mehr Daten müssen zu Verfügung gestellt werden, im exponentiellen Anstieg – Wo wir wieder beim Thema Rechenleistung sind, die ebenfalls exponentiell ansteigen muss.

Weiterführende Literatur

Machine Learning in Action


Introduction to Machine Learning with Python

Einführung in Data Science: Grundprinzipien der Datenanalyse mit Python

KNN: Rückwärtspass

Im letzten Artikel der Serie haben wir gesehen wie bereits trainierte Netzwerke verwendet werden können. Als Training wird der Prozess bezeichnet der die Gewichte in einen Netzwerk so anpasst, dass bei einem Vorwärtspass durch ein Netzwerk zu einen festgelegten Eingangsdatensatz ein bestimmtes Ergebnis in der Ausgangsschicht ausgegeben wird. Im Umkehrschluss heißt das auch, dass wenn etwas anderes ausgeliefert wurde als erwartet, das Netzwerk entweder noch nicht gut genug oder aber auf ein anderes Problem hin trainiert wurde.


Das Training selbst findet in drei Schritten statt. Zunächst werden die Gewichte initialisiert. Üblicherweise geschieht das mit zufälligen Werten, die aus einer Normalverteilung gezogen werden. Je nachdem wie viele Gewichte eine Schicht hat, ist es sinnvoll die Verteilung über den Sigma Term zu skalieren. Als Daumenregeln kann dabei eins durch die Anzahl der Gewichte in einer Schicht verwendet werden.

Im zweiten Schritt wird der Vorwärtspass für die Trainingsdaten errechnet. Das Ergebnis wird beim ersten Durchlauf alles andere als zufrieden stellend sein, es dient aber dem Rückwärtspass als Basis für dessen Berechnungen und Gewichtsänderungen. Außerdem kann der Fehler zwischen der aktuellen Vorhersage und dem gewünschten Ergebnis ermittelt werden, um zu entscheiden, ob weiter trainiert werden soll.

Der eigentliche Rückwärtspass errechnet aus der Differenz der Vorwärtspassdaten und der Zieldaten die Steigung für jedes Gewicht aus, in dessen Richtung dieses geändert werden muss, damit das Netzwerk bessere Vorhersagen trifft. Das klingt zunächst recht abstrakt, die genauere Mathematik dahinter werde ich in einem eigenen Artikel erläutern. Zur besseren Vorstellung betrachten wir die folgende Abbildung.

    visuelle Darstellung aller Gewichtskombinationen und deren Vorhersagefehler

Das Diagramm zeigt in blau zu allen möglichen Gewichtskombinationen eines bestimmten, uns unbekannten, Netzwerks und Problems den entsprechenden Vorhersagefehler. Die Anzahl der Kombinationen hängt von der Anzahl der Gewichte und der Auflösung des Wertebereiches für diese ab. Theoretisch ist die Menge also unendlich, weshalb die blaue Kurve eine von mir ausgedachte Darstellung aller Kombinationen ist. Der erste Vorwärtspass liefert uns eine Vorhersage die eine normalisierte Differenz von 0.6 zu unserem eigentlichen Wunschergebnis aufweist. Visualisiert ist das Ganze mit einer schwarzen Raute. Der Rückwärtspass berechnet aus der Differenz und den Daten vom Vorwärtspass einen Änderungswunsch für jedes Gewicht aus. Da die Änderungen unabhängig von den anderen Gewichten ermittelt wurden, ist nicht bekannt was passieren würde wenn alle Gewichte sich auf einmal ändern würden. Aus diesem Grund werden die Änderungswünsche mit einer Lernrate abgeschwächt. Im Endeffekt ändert sich jedes Gewicht ein wenig in die Richtung, die es für richtig erachtet. In der Hoffnung einer Steigerung entlang zu einem lokalen Minimum zu folgen, werden die letzten beiden Schritte (Vor- und Rückwärtspass) mehrfach wiederholt. In dem obigen Diagramm würde die schwarze Raute der roten Steigung folgen und sich bei jeder Iteration langsam auf das linke lokale Minimum hinzubewegen.


Anwendungsbeispiel und Programmcode

Um den ganzen Trainingsprozess im Einsatz zu sehen, verwenden wir das Beispiel aus dem Artikel “KNN: Vorwärtspass”. Die verwendeten Daten kommen aus der Wahrheitstabelle eines X-OR Logikgatters und werden in ein 2-schichtiges Feedforward Netzwerk gespeist.

XOR Wahrheitstabelle

X1 X2 Y = X1 ⊻ X2
0 0 0
0 1 1
1 0 1
1 1 0

Der Programmcode ist in Octave geschrieben und kann zu Testzwecken auf der Webseite von Tutorialpoint ausgeführt werden. Die erste Hälfte von dem Algorithmus kennen wir bereits, der Vollständigkeit halber poste ich ihn noch einmal, zusammen mit den Rückwärtspass. Hinzugekommen sind außerdem ein paar Konsolenausgaben, eine Lernrate- und eine Iterations-Variable die angibt wie viele Trainingswiederholungen durchlaufen werden sollen.

Zu jeder Zeile bzw. Funktion die wir im Vorwärtspass geschrieben haben, gibt es im Rückwärtspass eine abgeleitete Variante. Dank den Ableitungen können wir die Änderungswünsche der Gewichte in jeder Schicht ausrechnen und am Ende einer Trainingsiteration anwenden. Wir trainieren 10.000 Iterationen lang und verwenden eine Lernrate von 0,8. In komplexeren Fragestellungen, mit mehr Daten, würden diese Werte niedriger ausfallen.

Es ist außerdem möglich den ganzen Programmcode viel modularer aufzubauen. Dazu werde ich im nächsten Artikel auf eine mehr objekt-orientiertere Sprache wechseln. Nichts desto trotz liefert der obige Algorithmus gute Ergebnisse. Hier ist mal ein Ausgabebeispiel:


KNN: Vorwärtspass

Wenn die Gewichte eines künstlichen neuronalen Netzwerkes trainiert sind, kann es verwendet werden, um Vorhersagen über eine am Eingang angelegte Beobachtung zu treffen. Hierzu werden Schicht für Schicht, in einem sogenannten Vorwärtspass (Forward-Pass), die Aktivierungen der einzelnen Neuronen ermittelt, bis ein Ergebnis an der Ausgabeschicht anliegt. Der ganze Prozess hat zwar einen eigenen Namen (Vorwärtspass), ist aber im Endeffekt nur ein iteratives durchführen von mehreren logistischen Regressionen und entspricht dem Vorgehen aus dem Artikel „KNN: künstliche Neuronen“.


Im folgenden Beispiel verwenden wir die Wahrheitstabelle von einem X-OR Logikgatter (siehe Abbildungen unten links) als Ground Truth Data. Ziel ist es, den Ausgangwert Y, für einen beliebig anliegenden Eingangsvektor [X1, X2] vorherzusagen. Die Aufgabe ist recht komplex, so dass eine einfache lineare oder logistische Regression keine zufriedenstellende Lösung finden wird. Die zum Einsatz kommende  Netzwerkstruktur ist ein 2-schichtiges Feedforward Netzwerk mit zwei Eingangsneuronen, einer verborgenen Schicht und einem Ausgangsneuron.

XOR Wahrheitstabelle

X1 X2 Y = X1 ⊻ X2
0 0 0
0 1 1
1 0 1
1 1 0


Da das Netzwerk wie anfänglich erwähnt, bereits trainiert ist, gebe ich die Gewichte (Theta) vor. Werden die Werte als Matrix dargestellt, können mit Hilfe der linearen Algebra die Aktivierungswahrscheinlichkeiten aller Neuronen einer Schicht auf einmal ausgerechnet werden.

Theta 1

θ11 =  2,7 θ12 =   3,1
θ13 =  5,6 θ14 = -6
θ15 = -5,4 θ16 =  6,2
Theta 2

θ21 =  9,6
θ22 = -6,6
θ23 = -6,5


Für die eigentlichen Berechnungen verwenden wir die Programmiersprache Octave oder MATLAB. Octave ist eine kostenlose alternative zu MATLAB. Wobei es nicht notwendig ist irgendetwas zu installieren, da es auch eine Online Variante von MATLAB/Octave gibt:

Ein paar Sätze zu den verwendeten Befehlen. Der Punkt vor manchen Operationen gibt an, dass die Operation Elementweise durchzuführen ist (wichtig bei der Sigmoid Funktion). Die Methode ones(M,N) erzeugt eine MxN große Matrix gefüllt mit den Werten 1. Wir erzeugen damit einen Spaltenvektor der unseren Bias Units entspricht und den wir anschließend an eine vorhandene Matrix horizontal anfügen.

Wird das Programm ausgeführt schreibt es unter anderem die Werte von der Ausgabeschicht O (Output Layer) auf die Konsole. Da wir alle XOR Variationen auf einmal ausgerechnet haben, erhalten wir auch vier Vorhersagen. Verglichen mit der Zielvorgaben Y sind die Werte von O sehr vielversprechend (ähnlich).

X1 X2 Y O
0 0 0 0.057099
0 1 1 0.936134
1 0 1 0.934786
1 1 0 0.050952


Komplexe Netzwerke

Hätte das Netzwerk noch weitere verborgene Schichten, müssen Teile des Programmcodes wiederholt ausgeführt werden. Grundsätzlich sind drei Befehle pro Schicht notwendig:

Im nächsten Artikel schauen wir uns das Training solcher Netzwerke an.

Text-Mining mit dem Aika Algorithmus

In diesem Beitrag möchte ich das Open Source Projekt Aika vorstellen. Ziel des Projektes ist es einen Text-Mining Algorithmus zu entwickeln, der ein künstliches Neuronales Netz (kNN) mit einem Pattern Mining Algorithmus kombiniert. Dabei dient die Silbentrennung von Wörtern als initiale Aufgabe, anhand derer der Algorithmus weiterentwickelt wird. Für diese Aufgabe soll allerdings kein vordefiniertes Wörterbuch verwendet werden. Stattdessen sollen die Silben in ihrer Eigenschaft als häufig auftretende Muster in rohem Text erkannt werden. Hier reicht es allerdings nicht einen Mining Algorithmus nach häufig auftretenden Strings suchen zu lassen, da sich viele der Strings überlappen oder schlicht keinen Sinn ergeben würden. Es ist also wichtig, dass sich die erkannten Silben gegenseitig unterdrücken können und dass der Algorithmus in der Lage ist, die so entstehenden unterschiedlichen Interpretationen eines Wortes miteinander zu vergleichen und die am höchsten gewichtete auszuwählen. Beispielsweise taucht die Silbe ‘der’ zu Beginn des Wortes ‘de-re-gu-lie-ren’ auf. In diesem Fall muss der Algorithmus erkennen, dass die erste Silbe des Wortes nicht ‘der’ sondern nur ‘de’ ist.

Wenn nun nach häufig auftretenden Mustern in Text gesucht werden soll, warum verwenden wir nicht einen reinen Pattern Mining Algorithmus? Der Grund für die Kombination mit einem kNN liegt darin, dass die erkannten Muster innerhalb einer kNN Topologie aufeinander aufsetzen können. Wenn z. B. das Wort “hausboot” als Muster erkannt werden soll, dann entstünden in der Datenstruktur des Mining Algorithmus sehr viele Teilmuster, die alle evaluiert werden müssten. Viel leichter wäre es für den Algorithmus, wenn die Muster “haus” und “boot” bereits erkannt worden wären und nun als Eingaben für die Erkennung des Wortes “hausboot” dienen könnten. So ist der Algorithmus zum einen in der Lage komplexere Muster zu erkennen und muss gleichzeitig weniger Teilmuster untersuchen. Ausserdem erlaubt es ein kNN ‘weiche’ Muster zu erlernen, also Muster bei denen einzelne Eingänge optional sind, die aber trotzdem noch sicher erkannt werden. Dadurch kann eine höhere Toleranz gegenüber Fehlern erreicht werden.

Im Gegensatz zu einem klassischen kNN nutzt Aika einen eher mit Googles Pagerank vergleichbaren Ansatz um Gewichte zwischen den einzelnen Neuronen des Netzwerks zu propagieren. Der Grutext-pattern-knnndgedanke dabei ist es, dass Neuronen entsprechend höher gewichtet werden sollten, wenn sie mit anderen hoch gewichteten Neuronen in Beziehung stehen. Wenn also beispielsweise eine Silbe in vielen hoch gewichteten Worten auftaucht, wird sie selbst entsprechend höher gewichtet.

Neuronen eines kNN erlauben es aber nicht nur Konjunktionen wie etwa bei Mustern zu erlernen, sondern auch Disjunktionen. Disjunktionen sind insbesondere beim Erlernen von Grammatikregeln wichtig, wenn z. B. einzelne Worte als Nomen erkannt werden sollen. Wenn nun solche Disjunktionen erlernt werden sollen, können auch hier häufige Muster behilflich sein. Angenommen, es wurden durch den Mining Algorithmus bereits die folgenden häufigen Muster gefunden: “der Baum” (f=4), “der Hammer” (f=3) und “der Nagel” (f=6). Dann können diese Muster so umgeformt werden, dass ein neues, deutlich häufigeres Muster “der <NOMEN>” (f=13) und eine Disjunktion <NOMEN> = “Baum” oder “Hammer” oder “Nagel”, entsteht.

KNN: Natur als Vorbild – Biologische Neuronen

Bisher ist die genaue Funktionsweise des Gehirns bei der Verarbeitung sensorischer Informationen nicht bekannt. Neue Erkenntnisse im Bereich der Neurowissenschaften liefern jedoch einen Einblick über grundlegende Prinzipien wie das Gehirn von Säugetieren sensorische Informationen repräsentiert. Einer der wichtigsten Punkte ist dabei die Erkenntnis, dass der Neocortex, einem ankommenden Signal erlaubt ein komplexes Netzwerk von Neuronen zu durchlaufen, wodurch es zu einer abstrakten Repräsentation des ursprünglichen Eingabesignals kommt. Auch ist das Gehirn in der Lage die Leitfähigkeit der Verbindungen zwischen den Neuronen zu modifizieren, was sich auf eine Änderung der Abbildungsvorschrift auswirkt. Beobachtungen können dadurch noch besser getrennt und effizienter repräsentiert werden. Die Entdeckung dieses Verhaltens motivierte die Entstehung des Forschungszweiges Deep Machine Learning, welcher sich darauf fokussiert Modelle zu entwickeln, die ähnliche Charakteristiken wie der Neocortex aufweisen.

Das Eingabesignal durchläuft das Netzwerk bis zu einer Ausgabeschicht. Das Resultat dieser nicht linearen Transformation lässt sich dann beispielsweise mit einem Klassifizierungsalgorithmus auswerten. Die praktischen Anwendungen solcher Algorithmen sind sehr vielfältig. Deep Machine Learning Algorithmen liefern zurzeit die besten Ergebnisse zu vielen Problemen in Anwendungsdomänen wie Bilderkennung, Spracherkennung und der Verarbeitung natürlicher Sprache. Mit Hilfe dieser Algorithmen wurden beispielsweise neue elementare Teilchen gefunden, entdeckte Galaxien noch besser klassifiziert und Auswirkungen von Mutationen innerhalb von DNA vorhergesagt.

Das Neuron

Das Neuron ist die Basis-Recheneinheit des Gehirns. Ungefähr 86 Milliarden solcher Neuronen befinden sich im menschlichen Nervensystem, welche durch ca. 10^15 Synapsen miteinander vermascht sind. In Abbildung unten links wird eine Schemazeichnung eines biologischen Neurons dargestellt. Dieses besteht unter Anderem aus Dendriten, dem Zellkörper, der den Zellkern beinhaltet und einem Axon. Die Dendriten gehen aus dem Zellkörper hervor und sind über Synapsen mit sensorischen Zellen oder Axonen anderer Neuronen verbunden. Ihre Aufgabe ist die Aufnahme von ankommenden Signalen in Form von elektrischen Spannungsänderungen und der Transport dieser in den Zellkörper des Neurons, der Recheneinheit einer Nervenzelle. Dort angekommen entscheiden bestimmte Faktoren, ob ein Aktionspotential anhand einer Schwellwertfunktion ausgelöst wird oder nicht. Ist dies der Fall leitet das Neuron elektrische Energie über sein Axon an weitere angeschlossene Dendriten anderer Neuronen weiter.

Das biologische Neuron diente als Inspiration für das Software-Neuron. Beim mathematischen Modell eines Software-Neurons (Künstliches Neuron eines KNN) wird davon ausgegangen, dass die verschiedenen Dendriten unterschiedlich stark ausgeprägt sind und ein Signal daher auch verschieden stark gewichtet in den Zellkörper übertragen wird. Jedes Dendrit enthält demnach einen Faktor(θi), der das Signal(xi) vor dem Eintreffen in den Zellkörper skaliert (θixi). Diese Faktoren werden auch als Gewichte bezeichnet. Im Zellkörper selbst werden die Signale die von unterschiedlichen Neuronen stammen aufsummiert bis schließlich ein fester Bias-Wert(b) auf das Ergebnis der Summation aufaddiert wird. Anschließend bestimmt eine nicht-lineare Aktivierungsfunktion über den finalen Ausgangswert des Neurons.

Bildquelle: Wikipedia

Ähnliche Artikel:

KNN: Künstliche Neuronen

Es gibt sehr ausführliche Definitionen und Abbildungen für ein künstliches Neuron, die in diesem Artikel aber nicht behandelt werden. Der Grund dafür ist pragmatischer Natur. Es soll eine gewisse Konsistenz zu den anderen KNN-Beiträgen dieser Reihe bestehen und das Thema soll nicht zu einer wissenschaftlichen Abhandlung mutieren.

In dem Beitrag  KNN: Was sind künstliche neuronale Netze  geht es um den grundsätzlichen Aufbau von künstlichen neuronalen Netzwerken. Zusammengesetzt werden die Strukturen aus einer oftmals großen Anzahl von künstlichen Neuronen. Die nachfolgende Abbildung zeigt auf der Linken Seite einen extrahierten Ausschnitt aus einem Netzwerk. Es kann auch als einfaches allein stehendes Netzwerk betrachtet werden. Auf der rechten Seite ist eine allgemeingültigere Form zu sehen. Die Bias Unit (VB) wird üblicherweise als X0 bezeichnet und hat immer den Wert 1.


neuronen-netzwerk1 neuronen-netzwerk2


Um den Ausgangswert Y zu berechnen wird zunächst jeder Eingangswert X mit seinem dazugehörigen Gewicht \theta (Theta) multipliziert und die Ergebnisse aufsummiert. Das Zwischenergebnis ist die Aktivierungsstärke z:

    \[ z = X_0 \cdot \theta_0 + X_1 \cdot \theta_1 + X_2 \cdot \theta_2 \]

Im nächsten Schritt wird der eigentliche Ausgangswert Y errechnet, indem die Aktivierungsstärke z an eine Aktivierungsfunktion angelegt wird. Es gibt zwar verschiedene Funktionen, häufig wird aber die Logistische bzw. Sigmoid-Funktion verwendet. Sie ist nicht-linear und hat einen Ausgangswertebereich zwischen 0 und 1.


    \[ sigmoid(z) = \frac{1}{1+e^{-z}} \]

Wird das Bias Neuron und sein Gewicht nicht beachtet, bestimmen die eingehenden Daten die Aktivierungsstärke und damit den Ausgang der Funktion. Unter Verwendung der Bias Unit verschiebt sich die Funktion entlang der Y-Achse, was einer Verschiebung von einem Schwellwert gleich kommt.

Die endgültige Formel für die Aktivierung eines Neurons sieht sehr ähnlich zu der Logistischen Regression aus. Werden die Werte von X und Theta zu Vektoren zusammengefasst, lässt sich die Berechnung stark vereinfachen:

    \[ Y = sigmoid(X\theta) \]

Als Programmcode müsste diese Berechnung dennoch mit einer Schleife realisiert werden oder noch besser mit einer Bibliothek für lineare Algebra.

Ähnliche Artikel:
KNN: Was sind künstliche neuronale Netze
KNN: Vorteile und Nachteile

KNN: Vorteile und Nacheile

Wie jedes Verfahren haben auch künstliche Neuronale Netzwerke (KNN) ihre Vor- und Nachteile. Im Folgenden sollen einige benannt werden.


  • KNN können bessere Ergebnisse liefern als existierende statistische Ansätze, wenn das Problem ausreichend komplex ist. Das heißt, wenn das Problem nicht linear ist und es viele Eingabedaten mit vielen Variablen gibt.
  • Es gibt zwar sogenannte Hyperparameter, die je nach Einstellung das Netzwerk besser oder schlechter trainieren lassen, diese müssen aber nur manuell geändert werden, wenn neue Rekordwerte erreicht werden sollen. Ansonsten gibt es verhältnismäßig wenige Parameter.
  • Auch für stark nicht lineare Probleme, werden gute Lösungen gefunden. Dazu zählen fast alle Probleme die aus einer Datenbasis stammen, wo menschliche oder andere unvorhersehbare Einflüsse wirken.
  • Für große Datenmengen und viele Datendimensionen (Einflussfaktoren) können sinnvolle Ergebnisse ermittelt werden.


  • Künstliche Neuronale Netzwerke sind oftmals wie eine Blackbox. Dadurch ist es nicht möglich nachzuverfolgen wieso ein Netzwerk eine bestimmte Entscheidung getroffen hat.
  • Damit ein allgemeingültiges gutes Ergebnis berechnet werden kann, bedarf es vieler Beispiel-/Trainingsdaten.
  • Aufgrund der hohen Datenmenge, ist es sinnvoll die Berechnungen auf einer Grafikkarte durchzuführen.
  • Während des Trainings finden sehr viele Gewichtsänderungen in kurzer Zeit statt. Daher ist ein Aufteilen der Arbeit in ein verteiltes System wie Apache Hadoop oder Apache Spark nur schwer möglich und führt oftmals zu drastischen Performanz Einbußen.
  • Ist das Problem mathematisch beschreibbar sind KNNs oftmals schlechter oder maximal genauso gut.
  • Es ist zu keinen Zeitpunkt bekannt ob die gefundene Lösung das globale Optimum ist oder ob es noch bessere Lösungen gibt.

In der Forschung gibt es viele Ansätze um einige der Nachteile aufzuheben.


KNN: Was sind künstliche neuronale Netze?

Ein künstliches neuronales Netzwerk (KNN) besteht aus vielen miteinander verbundenen künstlichen Neuronen. Die einzelnen Neuronen haben unterschiedliche Aufgaben und sind innerhalb von Schichten (layer) angeordnet. Sogenannte Netzwerk Topologien geben vor, wie viele Neuronen sich auf einer Schicht befinden und welche Neuronen miteinander vernetzt sind. Neuronale Netze werden im Bereich der künstlichen Intelligenz eingesetzt und sind ein Ansatz im Machine Learning, haben hier jedoch besondere Vor- und Nachteile.

Es gibt drei Schicht- und vier grundlegende Neuronen-Arten. Bei den Schichten wird unterschieden zwischen Eingabe-, Ausgabe- und verborgener Schicht (Visible, Output & Hidden Layer). Alle eingehenden Daten werden an den Eingabe-Neuronen (Visible Unit) in der Eingabeschicht angelegt. Diese wiederum geben die Daten weiter an die verbundenen Ausgabe- oder verborgenen Neuronen (Output, Hidden Unit). Zusätzlich kann in jeder Schicht noch ein Bias Neuron (Bias Unit) zum Einsatz kommen. Read more