Tag Archive for: Data Mining

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 (erscheint demnächst…)
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.

Analyse der Netzwerktopologie des Internets auf Basis des IPv4-Protokolls

Wie kommen Daten die man via Internet quer durch die Welt sendet eigentlich an ihr Ziel? Welchen Weg nehmen beispielsweise die Datenpakete, wenn ich von mir zu Hause eine Datei an meinen Nachbarn ein Haus weiter sende? Wie groß ist der “Umweg”, den die Daten nehmen? Und macht es eigentlich einen Unterschied, ob ich www.google.de, www.google.com oder www.google.nl aufrufe, oder gehen alle Suchanfragen sowieso an dasselbe Ziel?

Fragen wie diese lassen sich durch eine Kombination von Tools wie traceroute oder tracepath und geoiplookup beantworten und unter Verwendung des Python-Paketes geoplotlib sogar graphisch auf einer Weltkarte darstellen. Die so gewonnenen Ergebnisse zeigen Teile der Netzwerktopologie des Internets auf und führen zu interessanten, teils unerwarteten Erkenntnissen.

Ziel dieses Artikels soll sein, ein möglichst einfaches Tutorial zum selber mitbasteln bereit zu stellen. Die einzelnen Schritte die hierfür notwendig sind, werden möglichst einfach verständlich dargestellt und erklärt, trotzdem sind zum vollständigen Verständnis grundlegende Kenntnisse in Python sowie der Kommandozeile hilfreich. Er richtet sich aber auch an alle, die sich einfach einmal etwas in ihrer virtuellen Umgebung „umschauen“ möchten oder einfach nur an den Ergebnissen interessiert sind, ohne sich mit den Details und wie diese umgesetzt werden, auseinander setzen zu wollen.  Am Ende des Artikels werden die einzelnen Skripte des Projekts als zip-Datei bereitgestellt.

Hinweis: Diese Anleitung bezieht sich auf ein Linux-System und wurde unter Ubuntu getestet. Windows-User können beispielsweise mit dem Befehl tracert (als Ersatz für traceroute) ähnliche Ergebnisse erziehlen, jedoch muss dann das Parsing der IP-Adressen abgeändert werden.

1. Grundsätzliches Erkunden der Route, die ein Datenpaket nimmt

Hierfür wird ein Programm wie traceroute, tracepath oder nmap benötigt, welches durch Versenden von „abgelaufenen Datenpaketen“ die Hosts „auf dem Weg“ zum Ziel dazu bringt, ihre IPv4-Adresse zurück zu geben. In diesem Artikel wird beispielhaft traceroute verwendet, da dieses unter den meisten Linux-Versionen bereits zur „Grundausstattung“ gehört und somit für diesen Schritt keine weitere Software installiert werden muss. Die Verwendung von traceroute folgt der Syntax:

sudo traceroute ${ZIEL}

Als Ziel muss hier die IP-Adresse bzw. der Domainname des Zielrechners angegeben werden. Ein Beispiel soll dies vereinfachen:

$ sudo traceroute www.google.de
traceroute to www.google.de (172.217.22.99), 64 hops max
  1   192.168.0.1  167,148ms  3,200ms  11,636ms 
  2   83.169.183.11  21,389ms  19,380ms  88.134.203.107  16,746ms 
  3   88.134.203.107  27,431ms  24,063ms  * 
  4   88.134.237.6  1679,865ms  *  130,818ms 
  5   88.134.235.207  58,815ms  84,150ms  * 
  6   72.14.198.218 144,998ms  107,364ms  108.170.253.68  121,851ms 
  7   108.170.253.84  58,323ms  101,127ms  216.239.57.218  44,461ms 
  8   216.239.57.218  43,722ms  91,544ms  172.253.50.100  67,971ms 
  9   172.253.50.214  106,689ms  96,100ms  216.239.56.130  110,334ms 
 10   209.85.241.145  63,720ms  61,387ms  209.85.252.76  73,724ms 
 11   209.85.252.28  71,214ms  61,828ms  108.170.251.129  81,470ms 
 12   108.170.251.129  64,262ms  52,056ms  72.14.234.115  71,661ms 
 13   72.14.234.113  262,988ms  55,005ms  172.217.22.99  66,043ms 

Im Beispiel wird die Route zum Hostrechner mit der Domain www.google.de ermittelt. In der ersten Spalte der Ausgabe ist die Nummer des jeweiligen „Hops“ zu sehen. Wichtig ist insbesondere die zweite Spalte, welche die IPv4-Adresse des jeweiligen Rechners auf dem Weg zum Ziel darstellt. Die folgenden Spalten enthalten weitere Informationen wie Antwortzeiten der jeweiligen Server und die IP-Adressen der Folge-Server.

Um die Ausgabe in eine Form umzuwandeln, welche später einfacher von Python gelesen werden kann, muss diese noch ausgelesen werden (Parsing). zuerst soll die erste Zeile der Ausgabe herausgeschnitten werden, da diese zwar informativ, jedoch kein Teil der eigentlichen Route ist. Dies kann sehr einfach durchgeführt werden, indem die Ausgabe des traceroute-Befehls an einen Befehl wie beispielsweise sed „gepiped“ (also weitergeleitet) wird. Die dabei entstehende Pipe sieht dann wie folgt aus:

sudo traceroute ${ZIEL} | sed '1d'

Um bei unserem Beispiel mit der Route zu www.google.de zu bleiben, sieht der Befehl und die Entsprechende Ausgabe wie folgt aus:

$ sudo traceroute   | sed '1d'
  1   192.168.0.1  167,148ms  3,200ms  11,636ms 
  2   83.169.183.11  21,389ms  19,380ms  88.134.203.107  16,746ms 
  3   88.134.203.107  27,431ms  24,063ms  * 
  4   88.134.237.6  1679,865ms  *  130,818ms 
  5   88.134.235.207  58,815ms  84,150ms  * 
  6   72.14.198.218 144,998ms  107,364ms  108.170.253.68  121,851ms 
  7   108.170.253.84  58,323ms  101,127ms  216.239.57.218  44,461ms 
  8   216.239.57.218  43,722ms  91,544ms  172.253.50.100  67,971ms 
  9   172.253.50.214  106,689ms  96,100ms  216.239.56.130  110,334ms 
 10   209.85.241.145  63,720ms  61,387ms  209.85.252.76  73,724ms 
 11   209.85.252.28  71,214ms  61,828ms  108.170.251.129  81,470ms 
 12   108.170.251.129  64,262ms  52,056ms  72.14.234.115  71,661ms 
 13   72.14.234.113  262,988ms  55,005ms  172.217.22.99  66,043ms 

Anschließend soll die zweite Spalte der Ausgabe herausgeschnitten werden. Dies ist am einfachsten mit dem Befehl awk zu bewerkstelligen. Das Prinzip dahinter ist das gleiche wie im obigen Schritt: die Ausgabe des vorherigen Befehls wird dem Befehl awk als Eingabe weitergeleitet, womit der gesamte Befehl nun wie folgt aussieht:

sudo traceroute ${ZIEL} | sed '1d' | awk '{ print $2 }'

Bezogen auf das google-Beispiel sehen Ein- und Ausgabe nun so aus:

$ sudo traceroute | sed '1d' | awk '{ print $2 }'
192.168.0.1
83.169.183.11
88.134.203.107
88.134.237.6
88.134.235.207
72.14.198.218
108.170.253.84
216.239.57.218
172.253.50.214
209.85.241.145
209.85.252.28
108.170.251.129
72.14.234.113

Im letzten Schritt sollen die einzelnen IP-Adressen durch Leerzeichen getrennt in eine einzelne Zeile geschrieben werden. Sinn dieses Schrittes ist, dass später viele Zielrechner nacheinander aus einer Datei eingelesen werden können und jede Route zu einem Zielrechner als eine einzelne Zeile in eine Zieldatei geschrieben wird.
Auch dieser Schritt funktioniert ähnlich wie die obigen Schritte, indem die Ausgabe des letzten Schrittes an einen weiteren Befehl weitergeleitet wird, der diese Funktion erfüllt. Dieser Schritt könnte wieder mit dem Befehl sed durchgeführt werden, da aber nur ein einzelnes Zeichen (nämlich das Zeilenumbruch-Zeichen bzw. Newline) durch ein Leerzeichen ersetzt werden soll, wird hier aufgrund der einfacheren Syntax der Befehl tr verwendet.
Der fertige Befehl sieht nun wie folgt aus:

sudo traceroute ${ZIEL} | sed '1d' | awk '{ print $2 }' | tr '\n' ' '

Oder im fertigen Beispiel mit www.google.de:

$ sudo traceroute   | sed '1d' | awk '{ print $2 }' | tr '\n' ' '
192.168.0.1 83.169.183.11 88.134.203.107 88.134.237.6 88.134.235.207 72.14.198.218 108.170.253.84 216.239.57.218 172.253.50.214 209.85.241.145 209.85.252.28 108.170.251.129 72.14.234.113

Hiermit ist das Parsen abgeschlossen und die fertige Ausgabe kann nun in eine Ergebnisdatei geschrieben werden. Um automatisch viele Zielrechner aus einer Datei einzulesen und alle gefundenen Routen in eine Zieldatei zu schreiben, wird der obige Befehl in eine Schleife „verpackt“ welche die Zielrechner Zeile für Zeile aus der Datei zieladressen.txt ausliest und die gefundenen Routen ebenso Zeile für Zeile in die Datei routen.csv schreibt. Die Datei routen.csv kann später zur Ermittlung verschiedener Informationen zu den gefunden IP-Adressen einfach mit einem Python-Skript eingelesen und geparst werden.

In diesem Artikel wird das fertige Skript ohne weitere Erklärung in der beiliegenden zip-Datei bereitgestellt. Wen die genaue Funktionsweise der Schleife interessiert, sei angehalten sich generell über die Funktionsweise von Shellskripten einzulesen, da dies den Rahmen des Artikels sprengen würde.

#/bin/sh

cat zieladressen.txt | while read ZIEL; do
    printf 'Ermittle Route nach: %s\n' "${ZIEL}"
    traceroute ${ZIEL} | sed '1d' | awk '{ print $2 }' | tr '\n' ' ' >> routes.csv
    printf '\n' >> routes.csv
done

cat routes.csv | tr -d \* | tr -s ' ' > routes_corrected.csv
mv routes_corrected.csv routes.csv

Dieses Skript benötigt die Datei zieladressen.txt welche wie folgt aussehen muss (anstatt Domainnamen können auch direkt IPv4-Adressen verwendet werden):

www.google.de
www.github.com
www.google.nl
...

2. Sammeln von (Geo-)Informationen zu bestimmten IPv4-Adressen

Die gefundenen IPv4-Adressen können anschließend mit dem Befehl geoiplookup oder über die Internetseite http://geoiplookup.net/ relativ genau (meißtens auf Städteniveau) lokalisiert werden. Dies funktioniert, da einzelne Subnets in der Regel bestimmten Regionen und Internetprovidern zugeordnet sind.

Der Befehl geoiplookup greift hierbei auf eine vorher installierte und lokal gespeicherte Datenbank zu, welche je nach installierter Version als Country- oder City-Edition vorliegt. Da geoiplookup nicht zu den Standartbordmitteln unter Linux gehört und um die weiteren Schritte auch Benutzern anderer Betriebssysteme zu ermöglichen, wird hier nur ein kurzes Beispiel der Benutzung dieses Befehls und dessen Ausgabe gegeben und im weiteren die Online-Abfrage mittels eines Python-Skriptes beschrieben.

$ geoiplookup 172.217.22.99
GeoIP Country Edition: US, United States
GeoIP City Edition, Rev 1: US, CA, California, Mountain View, 94043, 37.419201, -122.057404, 807, 650
GeoIP ASNum Edition: AS15169 Google Inc.

Die Internetseite http://geoiplookup.net bietet einen Onlineservice welcher Geo- und weitere Informationen zu gegebenen IPv4-Adressen bereitstellt. Öffnet man die Seite ohne Angabe einer IP-Adresse in einem Browser, so erhält man die entsprechenden Informationen über die eigene IP-Adresse. (Achtung: die Verwendung eines Proxies oder gar Tor führt zwangsläufig zu falschen Ergebnissen.)

Da die Seite auch über eine API (also eine automatisierte Abfrageschnittstelle) unter der Adresse “http://api.geoiplookup.net/?query=${IPADRESSE}” verfügt, kann man die entsprechenden Informationen zu den IP-Adressen mittels eines Pythonskriptes abfragen und auswerten. Als Antwort erhält man eine XML‑Datei welche beispielsweise folgendermaßen aussieht:

<ip>
  <results>
    <result>
      <ip>77.20.253.87</ip>
      <host>77.20.253.87</host>
      <isp>Vodafone Kabel Deutschland</isp>
      <city>Hamburg</city>
      <countrycode>DE</countrycode>
      <countryname>Germany</countryname>
      <latitude>53.61530</latitude>
      <longitude>10.1162</longitude>
    </result>
  </results>
</ip>

Diese kann im Browser z. B. unter der Adresse http://api.geoiplookup.net/?query=77.20.253.87 aufgerufen werden (oder unter: http://api.geoiplookup.net/ für die eigene Adresse).

Um die hierin enthaltenen Informationen mit Hilfe von Python auszulesen lässt sich ElementTree aus aus dem Modul xml.etree, das in der Python-Standartbibliothek vorhanden ist, verwenden. Dies wird im beiliegenden Skript mit der Funktion get_hostinfo() bewerkstelligt:

def get_hostinfo(ipv4):
    ''' Returns geoiplookup information of agiven host adress as a dictionary.
    The adress can be given as a string representation 0f a DNS or IPv4 adress.

    get_hostinfo(str) -> dict

    Examples: get_hostinfo("www.github.com")
              get_hostinfo("151.101.12.133")
    '''

    apiurl = 'http://api.geoiplookup.net/?query='
    hostinfo = defaultdict(str, {})
    try:
        xml = urllib.request.urlopen(apiurl + dns2ipv4(ipv4)).read().decode()
        xml = xml.replace('&', '')
        tree = ETree.fromstring(xml)
        for element in tree.getiterator():
            hostinfo[element.tag] = element.text
    except:
        return hostinfo
    finally:
        return hostinfo

Diese parst die XML-Datei automatisch zu einem Python-DefaultDict das dann die entsprechenden Informationen enthält (das DefaultDict wird verwendet da normale Python Dictionaries zu Fehlern führen, wenn nicht gesetzte Werte abgefragt werden). Die Ausgabe der Funktion sieht dann wie folgt aus:

In [3]: get_hostinfo('www.google.com')
Out[3]:
defaultdict(str,
            {'city': 'Mountain View',
             'countrycode': 'US',
             'countryname': 'United States',
             'host': '172.217.22.99',
             'ip': '172.217.22.99',
             'isp': 'Google',
             'latitude': '37.4192',
             'longitude': '-122.0574',
             'result': None,
             'results': None})

3. Plotten der gefundenen Routen mit geoplotlib auf einer Weltkarte

Wichtig für das anschließende Plotten ist hierbei die Geolocation also ‘latitude’ und ‘longitude’. Mit den Werten kann man anschließend die mit traceroute gefundenen Pfade als Basemap plotten. Dies funktioniert mit der Funktion drawroutes2map():

def drawroutes2map(routesfile='routes.csv'):
    drawroutes = list()
    for route in open(routesfile).readlines():
        ips = [ip2location(ip) for ip in route.strip().split(',')]
        print(ips)
        locs = [loc for loc in ips if not loc == None]
        longs = [loc[0] for loc in locs]
        lats = [loc[1] for loc in locs]
        m = minimalmap()
        drawroutes.append(tuple(m(lats, longs)))
        for drawroute in drawroutes:
            m.plot(drawroute[0], drawroute[1], '-', markersize=0, linewidth=1, color=rand_color())
            pickleto(drawroutes, 'tracedlocs.plk')
    plt.savefig('world.svg', format='svg')
    plt.savefig('world.png', format='png')
    plt.show()

Der Plot einer Verbindungsanfrage an www.google.de aus Berlin sieht beispielsweise folgendermaßen aus:

Hier wird deutlich, dass Datenpakete durchaus nicht immer den kürzesten Weg nehmen, sondern teilweise rund um die Welt gesendet werden (Deutschland – USA – Sydney(!) – USA), bevor sie an ihrem Ziel ankommen und dass das Ziel einer Verbindung zu einer Domain mit der Endung „de“ nicht unbedingt in Deutschland liegen muss.

Mit Default-Einstellungen werden von der Funktion drawroutes2map() alle Routen in zufälligen Farben geplottet, welche in der Datei routen.csv gefunden werden.

Lässt man viele Routen plotten wird hierbei die Netzwerkstruktur deutlich, über die die Daten im Internet verteilt werden. Auf dem obigen Plot kann man recht gut erkennen, dass die meisten Internetseiten in Europa oder den USA gehostet werden, einige noch in China und Japan, dagegen beispielsweise Afrika praktisch unbedeutend ist.

Auf dem nächsten Plot wiederum ist zu erkennen, dass es tatsächlich eine Art “Hotspots” gibt über die fast alle Daten laufen, wie z. B. Frankfurt am Main, Zürich und Madrid.

4. Schematische Darstellung der Routen als directed Graph mit graphviz

Mit graphviz lassen sich schematische Graphen darstellen. Mit dem Paket pygraphviz existiert hiefür auch eine Python-Anbindung. Die schematische Darstellung als Graph ist in vielen Fällen deutlich übersichtlicher als die Darstellung auf einer Weltkarte und die Topologie des Netzwerkes wird besser sichtbar.

Die entsprechende Python-Funktion, die alle Routen aus der Datei routes.csv als geplotteten Graph ausgibt ist drawroutes2graph():

def drawroutes2graph(routesfile='routes.csv'):
    '''Draws all routes found in the routesfile with graphviz to a Graph

        drawroutes2graph(file)

    '''
    routes = open(routesfile).readlines()
    for i in range(len(routes)):
        routes[i] = routes[i].replace('*', '').split()
        G = pgv.AGraph(strict=False, directed=True)

    for l in routes:
        for i in range(len(l)-1):
            if not (l[i], l[i+1]) in set(G.edges()):
                G.add_edge(l[i], l[i+1])

    for n in G.nodes():
        if get_hostinfo(n)['countrycode'] == 'DE':
            n.attr['color'] = 'green'
        elif get_hostinfo(n)['countrycode'] == 'US':
            n.attr['color'] = 'red'
        elif get_hostinfo(n)['countrycode'] == 'ES':
            n.attr['color'] = 'yellow'
        elif get_hostinfo(n)['countrycode'] == 'CH':
            n.attr['color'] = 'blue'
        elif get_hostinfo(n)['countrycode'] == 'CN':
            n.attr['color'] = 'magenta'

        G.write('routes.dot')
        
        G.layout('dot')
        G.draw('dot.png')

        G.layout()
        G.draw('neato.png')

Die Funktion schreibt den erstellten Graph in der Dot-Language in die Datei routes.dot und erstellt zwei verschiedene visuelle Darstellungen als png-Dateien.

Da mit der Funktion get_hostinfo() auch weitere Informationen zu den jeweiligen IP-Adressen verfügbar sind  können diese auch visuell im Graph dargestellt werden. So sind in der folgenden Darstellung Hosts in verschiedenen Ländern in unterschiedlichen Farben dargestellt. (Deutschland in grün, USA in rot, Spanien in gelb, Schweiz in blau, China in magenta und alle übrigen Länder und Hosts ohne Länderinformation in schwarz).

Diese Art der Darstellung vereint damit die Vorteile der schematischen Darstellung mit der Geoinformation zu den jeweiligen Hosts. Aus der Grafik lässt sich beispielsweise sehr gut erkennen, dass, trotz oft vieler Zwischenstationen innerhalb eines Landes, Landesgrenzen überschreitende Verbindungen relativ selten sind.

Auch interessant ist, dass das Netzwerk durchaus Maschen aufweist – mit anderen Worten: Dass ein und dieselbe Station bei verschiedenen Verbindungsanfragen über verschiedene Zwischenstationen angesprochen wird und Daten, die von Punkt A nach Punkt B gesendet werden, nicht immer denselben Weg nehmen.

5. Schlussfolgerung

Was kann man hieraus denn nun letztendlich an Erkenntnissen ziehen? Zum einen natürlich, wie Daten via Internet über viele Zwischenstationen rund um die Welt gesendet und hierbei mit jeder Station neu sortiert werden. Vor allem aber auch, dass mit dem entsprechenden Know-How und etwas Kreativität mit bemerkenswert wenig Code bereits Unmengen an Daten gesammelt, geordnet und ausgewertet werden können. Alle möglichen Daten werden in unserer heutigen Welt gespeichert und sind zu einem nicht unbeträchtlichen Teil auch für jeden, der weiß, wer diese Daten hat oder wie man sie selber ermitteln kann, verfügbar und oft lassen sich hier interessante Einblicke in die Funktionsweise unserer Welt gewinnen.

Entscheidungsbaum-Algorithmus ID3

Dieser Artikel ist Teil 2 von 4 der Artikelserie Maschinelles Lernen mit Entscheidungsbaumverfahren.

Entscheidungsbäume sind den Ingenieuren bestens bekannt, um Produkte hierarchisch zu zerlegen und um Verfahrensanweisungen zu erstellen. Die Data Scientists möchten ebenfalls Verfahrensanweisungen erstellen, jedoch automatisiert aus den Daten heraus. Auf diese Weise angewendet, sind Entscheidungsbäume eine Form des maschinellen Lernens: Die Maschine soll selbst einen Weg finden, um ein Objekt einer Klasse zuzuordnen.

Der ID3-Algorithmus

Den ID3-Algorithmus zu verstehen lohnt sich, denn er ist die Grundlage für viele weitere, auf ihn aufbauende Algorithmen. Er ist mit seiner iterativen und rekursiven Vorgehensweise auch recht leicht zu verstehen, er darf nur wiederum nicht in seiner Wirkung unterschätzt werden. Die Vorgehensweise kann in drei wesentlichen Schritten zerlegt werden, wobei der erste Schritt die eigentliche Wirkung (mit allen Vor- und Nachteilen) entfaltet:

  1. Schritt: Auswählen des Attributes mit dem höchsten Informationsgewinn
    Betrachte alle Attribute (Merkmale) des Datensatzes und bestimme, welches Attribut die Daten am besten klassifiziert.
  2. Schritt: Anlegen eines Knotenpunktes mit dem Attribut
    Sollten die Ergebnisse unter diesem Knoten eindeutig sein (1 unique value), speichere es in diesem Knotenpunkt und springe zurück.
  3. Schritt: Rekursive Fortführung dieses Prozesses
    Andernfalls zerlege die Daten jedem Attribut entsprechend in n Untermengens (subsets), und wiederhole diese Schritte für jede der Teilmengen.

Der Informationsgewinn (Information Gain) – und wie man ihn berechnet


Der Informationsgewinn eines Attributes (A) im Sinne des ID3-Algorithmus ist die Differenz aus der Entropie (E(S)) (siehe Teil 1 der Artikelserie: Entropie, ein Maß für die Unreinheit in Daten) des gesamten Datensatzes (S) und der Summe aus den gewichteten Entropien des Attributes für jeden einzelnen Wert (Value i), der im Attribut vorkommt:
IG(S, A) = E(S) - \sum_{i=1}^n \frac{\bigl|S_i\bigl|}{\bigl|S\bigl|} \cdot E(S_i)

Wie die Berechnung des Informationsgewinnes funktioniert, wird Teil 3 dieser Artikel-Reihe (erscheint in Kürze) zeigen.

Die Vorzüge des ID3-Algorithmus – und die Nachteile

Der Algorithmus ist die Grundlage für viele weitere Algorithmen. In seiner Einfachheit bringt er gewisse Vorteile – die ihn vermutlich zum verbreitesten Entscheidungsbaum-Algorithmus machen – mit sich, aber hat auch eine Reihe von Nachteilen, die bedacht werden sollten.

Vorteile Nachteile
  • leicht verständlich und somit schnell implementiert
  • stellt eine gute Basis für Random Forests dar
  • alle Attribute spielen eine Rolle, der Baum wird aber tendenziell klein, da der Informationsgewinn die Reihenfolge vorgibt
  • funktioniert (mit Anpassungen) auch für Mehrfachklassifikation
  • aus der Reihenfolge durch den Informationsgewinn entsteht nicht unbedingt der beste bzw. kleinste Baum unter allen Möglichkeiten. Es ist ein Greedy-Algorithmus und somit “kurzsichtig”
  • die Suche nach Entscheidungsregeln ist daher auch nicht vollständig/umfassend
  • da der Baum via ID3 solange weiterwachsen soll, bis die Daten so eindeutig wie möglich erklärt sind, wird Overfitting geradezu provoziert

Overfitting (Überanpassung) beachten und vermeiden

Aus Daten heraus generierte Entscheidungsbäume neigen zur Überanpassung. Das bedeutet, dass sich die Bäume den Trainingsdaten soweit anpassen können, dass sie auf diese perfekt passen, jedoch keine oder nur noch einen unzureichende generalisierende Beschreibung mehr haben. Neue Daten, die eine höhere Vielfältigkeit als die Trainingsdaten haben können, werden dann nicht mehr unter einer angemessenen Fehlerquote korrekt klassifiziert.

Vorsicht vor Key-Spalten!

Einige Attribute erzwingen eine Überanpassung regelrecht: Wenn beispielsweise ein Attribut wie „Kunden-ID“ (eindeutige Nummer pro Kunde) einbezogen wird, haben wir – bezogen auf das Klassifikationsergebnis – für jeden einzelnen Wert in dem Attribut eine Entropie von 0 zu erwarten, denn jeder ID beschreibt einen eindeutigen Fall (Kunde, Kundengruppe etc.). Daraus folgt, dass der Informationsgewinn für dieses Attribut maximal wird. Hier würde der Baum eine enorme Breite erhalten, die nicht hilfreich wäre, denn jeder Wert (IDs) bekäme einen einzelnen Ast im Baum, der zu einem eindeutigen Ergebnis führt. Auf neue Daten (neue Kundennummern) ist der Baum nicht anwendbar, denn er stellt keine generalisierende Beschreibung mehr dar, sondern ist nur noch ein Abbild der Trainingsdaten.

Prunning – Den Baum nachträglich kürzen

Besonders große Bäume sind keine guten Bäume und ein Zeichen für Überanpassung. Eine Möglichkeit zur Verkleinerung ist das erneute Durchrechnen der Informationsgewinne und das kürzen von Verzweigungen (Verallgemeinerung), sollte der Informationsgewinn zu gering sein. Oftmals wird hierfür nicht die Entropie oder der Gini-Koeffizient, sondern der Klassifikationsfehler als Maß für die Unreinheit verwendet.

Random Forests als Overfitting-Allheilmittel

Bei Random Forests (eine Form des Ensemble Learning) handelt es sich um eine Gemeinschaftsentscheidung der Klassenzugehörigkeit über mehrere Entscheidungsbäume. Diese Art des “demokratischen” Machine Learnings wird auch Ensemble Learning genannt. Werden mehrere Entscheidungsbäume unterschiedlicher Strukturierung zur gemeinsamen Klassifikation verwendet, wird die Wirkung des Overfittings einzelner Bäume in der Regel reduziert.

Überwachtes vs unüberwachtes maschinelles Lernen

Dies ist Artikel 1 von 4 aus der Artikelserie – Was ist eigentlich Machine Learning?

Der Unterschied zwischen überwachten und unüberwachtem Lernen ist für Einsteiger in das Gebiet des maschinellen Lernens recht verwirrend. Ich halte die Bezeichnung “überwacht” und “unüberwacht” auch gar nicht für besonders gut, denn eigentlich wird jeder Algorithmus (zumindest anfangs) vom Menschen überwacht. Es sollte besser in trainierte und untrainierte Verfahren unterschieden werden, die nämlich völlig unterschiedliche Zwecke bedienen sollen:

Während nämlich überwachte maschinelle Lernverfahren über eine Trainingsphase regelrecht auf ein (!) Problem abgerichtet werden und dann produktiv als Assistenzsystem (bis hin zum Automated Decision Making) funktionieren sollen, sind demgegenüber unüberwachte maschinelle Lernverfahren eine Methodik, um unübersichtlich viele Zeilen und Spalten von folglich sehr großen Datenbeständen für den Menschen leichter interpretierbar machen zu können (was nicht immer funktioniert).

Trainiere dir deinen Algorithmus mit überwachtem maschinellen Lernen

Wenn ein Modell anhand von mit dem Ergebnis (z. B. Klassifikationsgruppe) gekennzeichneter Trainingsdaten erlernt werden soll, handelt es sich um überwachtes Lernen. Die richtige Antwort muss während der Trainingsphase also vorliegen und der Algorithmus muss die Lücke zwischen dem Input (Eingabewerte) und dem Output (das vorgeschriebene Ergebnis) füllen.

Die Überwachung bezieht sich dabei nur auf die Trainingsdaten! Im produktiven Lauf wird grundsätzlich nicht überwacht (und das Lernen könnte sich auf neue Daten in eine ganz andere Richtung entwickeln, als dies mit den Trainingsdaten der Fall war). Die Trainingsdaten

Eine besondere Form des überwachten Lernens ist die des bestärkenden Lernens. Bestärkendes Lernen kommt stets dann zum Einsatz, wenn ein Endergebnis noch gar nicht bestimmbar ist, jedoch der Trend hin zum Erfolg oder Misserfolg erkennbar wird (beispielsweise im Spielverlauf – AlphaGo von Google Deepmind soll bestärkend trainiert worden sein). In der Trainingsphase werden beim bestärkenden Lernen die korrekten Ergebnisse also nicht zur Verfügung gestellt, jedoch wird jedes Ergebnis bewertet, ob dieses (wahrscheinlich) in die richtige oder falsche Richtung geht (Annäherungslernen).

Zu den überwachten Lernverfahren zählen alle Verfahren zur Regression oder Klassifikation, beispielsweise mit Algorithmen wir k-nearest-Neighbour, Random Forest, künstliche neuronale Netze, Support Vector Machines oder auch Verfahren der Dimensionsreduktion wie die lineare Diskriminanzanalyse.

Mit unüberwachtem Lernen verborgene Strukturen identifizieren

Beim unüberwachten Lernen haben wir es mit nicht mit gekennzeichneten Daten zu tun, die möglichen Antworten/Ergebnisse sind uns gänzlich unbekannt. Folglich können wir den Algorithmus nicht trainieren, indem wir ihm die Ergebnisse, auf die er kommen soll, im Rahmen einer Trainingsphase vorgeben (überwachtes Lernen), sondern wir nutzen Algorithmen, die die Struktur der Daten erkunden und für uns Menschen sinnvolle Informationen aus Ihnen bilden (oder auch nicht – denn häufig bleibt es beim Versuch, denn der Erfolg ist nicht garantiert!).Unüberwachte Verfahren des maschinellen Lernens dienen dem Data Mining, also der Erkennung von Inhalten in Daten anhand von sichtbar werdenden Strukturen. Die Verfahren müssen nicht unbedingt mit Datenvisualisierung arbeiten, oft ist das aber der Fall, denn erst die visuellen Strukturen ermöglichen unseren menschlichen Gehirnen die Daten in einen Kontext zu bringen. Mir sind zwei Kategorien des unüberwachten Lernens bekannt, zum einem das Clustering, welches im Grunde ein unüberwachtes Klassifikationsverfahren darstellt, und zum anderen die Dimensionsreduktion PCA (Hauptkomponentenanalyse). Es gibt allerdings noch andere Verfahren, die mir weniger vertraut sind, beispielsweise unüberwacht lernende künstliche neuronale Netze, die Rauschen lernen, um Daten von eben diesem Rauschen zu befreien.

Was ist eigentlich Machine Learning? Artikelserie

Machine Learning ist Technik und Mythos zugleich. Nachfolgend der Versuch einer verständlichen Erklärung, mit folgenden Artikeln:

Machine Learning ist nicht neu, aber innovativ!

Machine Learning oder maschinelles Lernen ist eine Bezeichnung, die dank industrieller Trends wie der Industrie 4.0, Smart Grid oder dem autonomen Fahrzeug zur neuen Blüte verhilft. Machine Learning ist nichts Neues und die Algorithmen sind teilweise mehrere Jahrzehnte alt. Dennoch ist Machine Learning ein Innovationsinstrument, denn während früher nur abstrakte Anwendungen, mit vornehmlich wissenschaftlichen Hintergrund, auf maschinellem Lernen setzten, finden entsprechende Algorithmen Einzug in alltägliche industrielle bzw. geschäftliche, medizinische und gesellschaftsorientierte Anwendungen. Machine Learning erhöht demnach sowohl unseren Lebensstandard als auch unsere Lebenserwartung!

Maschinelles Lernen vs künstliche Intelligenz

Künstliche Intelligenz (Artificial Intelligence) ist eine Bezeichnung, die in der Wissenschaft immer noch viel diskutiert wird. Wo beginnt künstliche Intelligenz, wann entsteht natürliche Intelligenz und was ist Intelligenz überhaupt? Wenn diese Wortkombination künstliche Intelligenz fällt, denken die meisten Zuhörer an Filme wie Terminator von James Cameron oder AI von Steven Spielberg. Diese Filme wecken Erwartungen (und Ängste), denen wir mir unseren selbstlernenden Systemen noch lange nicht gerecht werden können. Von künstlicher Intelligenz sollte als mit Bedacht gesprochen werden.

Maschinelles Lernen ist Teilgebiet der künstlichen Intelligenz und eine Sammlung von mathematischen Verfahren zur Mustererkennung, die entweder über generelle Prinzipien (das Finden von Gemeinsamkeiten oder relativen Abgrenzungen) funktioniert [unüberwachtes Lernen] oder durch das Bilden eines Algorithmus als Bindeglied zwischen Input und gewünschten Output aus Trainingsdaten heraus.

Machine Learning vs Deep Learning

Deep Learning ist eine spezielle Form des maschinellen Lernens, die vermutlich in den kommenden Jahren zum Standard werden wird. Gemeint sind damit künstliche neuronale Netze, manchmal auch verschachtelte “herkömmliche” Verfahren, die zum einen mehrere Ebenen bilden (verborgene Schichten eines neuronalen Netzes) zum anderen viel komplexere Zusammenhänge erlernen können, was den Begriff Deep Learning rechtfertigt.

Machine Learning vs Data Mining

Data Mining bezeichnet die Erkenntnisgewinnung aus bisher nicht oder nicht hinreichend erforschter Daten. Unüberwachte Verfahren des maschinellen Lernens, dazu gehören einige Verfahren aus dem Clustering und der Dimensionsreduktion, dienen explizit dem Zweck des Data Minings. Es sind Verfahren, die uns Menschen dabei helfen, vielfältige und große Datenmengen leichter interpretieren zu können. Machine Learning ermöglicht jedoch noch weit mehr als Data Mining.

Scikit-Learn Machine Learning Roadmap

Darstellung der vier Gebiete des Machine Learning: Die scikit-learn-Roadmap. Die Darstellung ist nicht vollständig, sondern umfasst nur die in scikit-learn implementierten Verfahren. Das Original-Bild ist interaktiv und zu finden auf scikit-learn.org

Unsupervised Learning in R: K-Means Clustering

Die Clusteranalyse ist ein gruppenbildendes Verfahren, mit dem Objekte Gruppen – sogenannten Clustern zuordnet werden. Die dem Cluster zugeordneten Objekte sollen möglichst homogen sein, wohingegen die Objekte, die unterschiedlichen Clustern zugeordnet werden möglichst heterogen sein sollen. Dieses Verfahren wird z.B. im Marketing bei der Zielgruppensegmentierung, um Angebote entsprechend anzupassen oder im User Experience Bereich zur Identifikation sog. Personas.

Es gibt in der Praxis eine Vielzahl von Cluster-Verfahren, eine der bekanntesten und gebräuchlichsten Verfahren ist das K-Means Clustering, ein sog. Partitionierendes Clusterverfahren. Das Ziel dabei ist es, den Datensatz in K Cluster zu unterteilen. Dabei werden zunächst K beliebige Punkte als Anfangszentren (sog. Zentroiden) ausgewählt und jedem dieser Punkte der Punkt zugeordnet, zu dessen Zentrum er die geringste Distanz hat. K-Means ist ein „harter“ Clusteralgorithmus, d.h. jede Beobachtung wird genau einem Cluster zugeordnet. Zur Berechnung existieren verschiedene Distanzmaße. Das gebräuchlichste Distanzmaß ist die quadrierte euklidische Distanz:

D^2 = \sum_{i=1}^{v}(x_i - y_i)^2

Nachdem jede Beobachtung einem Cluster zugeordnet wurde, wird das Clusterzentrum neu berechnet und die Punkte werden den neuen Clusterzentren erneut zugeordnet. Dieser Vorgang wird so lange durchgeführt bis die Clusterzentren stabil sind oder eine vorher bestimmte Anzahl an Iterationen durchlaufen sind.
Das komplette Vorgehen wird im Folgenden anhand eines künstlich erzeugten Testdatensatzes erläutert.

set.seed(123)
Alter <- c(24, 22, 28, 25, 41, 39, 35, 40, 62, 57, 60, 55)
Einkommen <- c(20000, 22000, 25000, 24000, 55000, 65000, 75000, 60000, 30000, 34000, 30000, 34000)
Daten <- as.data.frame(cbind(Alter, Einkommen))

Zunächst wird ein Testdatensatz mit den Variablen „Alter“ und „Einkommen“ erzeugt, der 12 Fälle enthält. Als Schritt des „Data preprocessing“ müssen zunächst beide Variablen standardisiert werden, da ansonsten die Variable „Alter“ die Clusterbildung zu stark beeinflusst.

DatenAlter <- scale(DatenAlter)
DatenEinkommen <- scale(DatenEinkommen)

Das Ganze geplottet:

plot(DatenAlter, DatenEinkommen, col = "blue", pch = 19,
     xlab = "Alter (scaled)",
     ylab = "Einkommen (scaled)",
     main = "Alter vs. Einkommen (scaled)")

Wie bereits eingangs erwähnt müssen Cluster innerhalb möglichst homogen und zu Objekten anderer Cluster möglichst heterogen sein. Ein Maß für die Homogenität die „Within Cluster Sums of Squares“ (WSS), ein Maß für die Heterogenität „Between Cluster Sums of Squares“ (BSS).

Diese sind beispielsweise für eine 3-Cluster-Lösung wie folgt:

KmeansObj <- kmeans(Daten, 3, nstart = 20)
KmeansObjwithinss # Within Cluster Sums of Squares (WSS) KmeansObjtotss # Between Cluster Sums of Suqares (BSS)

> KmeansObjwithinss # Within Cluster Sums of Squares (WSS) [1] 0.7056937 0.1281607 0.1792432 > KmeansObjtotss # Between Cluster Sums of Suqares (BSS)
[1] 22

Sollte man die Anzahl der Cluster nicht bereits kennen oder sind diese extern nicht vorgegeben, dann bietet es sich an, anhand des Verhältnisses von WSS und BSS die „optimale“ Clusteranzahl zu berechnen. Dafür wird zunächst ein leerer Vektor initialisiert, dessen Werte nachfolgend über die Schleife mit dem Verhältnis von WSS und WSS gefüllt werden. Dies lässt sich anschließend per „Screeplot“ visualisieren.

ratio <- vector()
for (k in 1:6) {
    KMeansObj <- kmeans(Daten, k, nstart = 20)
    ratio[k] <- KMeansObjtot.withinss / KMeansObjtotss
}
plot(ratio, type = "b",
     xlab = "Anzahl der Cluster",
     ylab = "Ratio WSS/BSS",
     main = "Screeplot für verschiedene Clusterlösungen",
col = "blue",  pch = 19)

Die „optimale“ Anzahl der Cluster zählt sich am Knick der Linie ablesen (auch Ellbow-Kriterium genannt). Alternativ kann man sich an dem Richtwert von 0.2 orientieren. Unterschreitet das Verhältnis von WSS und BSS diesen Wert, so hat man die beste Lösung gefunden. In diesem Beispiel ist sehr deutlich, dass eine 3-Cluster-Lösung am besten ist.

KmeansObj <- kmeans(Daten, centers = 3, nstart = 20)
plot(DatenAlter, DatenEinkommen, col = KmeansObjcluster, pch = 19, cex = 4,      xlab = "Alter (scaled)",      ylab = "Einkommen (scaled)",      main = "3-Cluster-Lösung") points(KmeansObjcenters, col = 1:3, pch = 3, cex = 5, lwd = 5)

Fazit: Mit K-Means Clustering lassen sich schnell und einfach Muster in Datensätzen erkennen, die, gerade wenn mehr als zwei Variablen geclustert werden, sonst verborgen blieben. K-Means ist allerdings anfällig gegenüber Ausreißern, da Ausreißer gerne als separate Cluster betrachtet werden. Ebenfalls problematisch sind Cluster, deren Struktur nicht kugelförmig ist. Dies ist vor der Durchführung der Clusteranalyse mittels explorativer Datenanalyse zu überprüfen.

Der Blick für das Wesentliche: Die Merkmalsselektion

In vielen Wissensbasen werden Datensätze durch sehr große Merkmalsräume beschrieben. Während der Generierung einer Wissensbasis wird versucht jedes mögliche Merkmal zu erfassen, um einen Datensatz möglichst genau zu beschreiben. Dabei muss aber nicht jedes Merkmal einen nachhaltigen Wert für das Predictive Modelling darstellen. Ein Klassifikator arbeitet mit reduziertem Merkmalsraum nicht nur schneller, sondern in der Regel auch weitaus effizienter. Oftmals erweist sich ein automatischer Ansatz der Merkmalsselektion besser, als ein manueller, da durchaus Zusammenhänge existieren können, die wir selbst so nicht identifizieren können.

Die Theorie: Merkmalsselektion

Automatische Merkmalsselektionsverfahren unterscheiden 3 verschiedene Arten: Filter, Wrapper und Embedded Methods. Einen guten Überblick über Filter- und Wrapper-Verfahren bieten Kumari et al. in ihrer Arbeit “Filter versus wrapper feature subset selection in large dimensionality micro array: A review” (Download als PDF).

Der Filter-Ansatz bewertet die Merkmale unabhängig des Klassifikators. Dabei werden univariate und multivariate Methoden unterschieden. Univariate Methoden bewerten die Merkmale separat, während der multivariate Ansatz mehrere Merkmale kombiniert. Für jedes Merkmal bzw. jedes Merkmalspaar wird ein statistischer Wert berechnet, der die Eignung der Merkmale für die Klassifikation angibt. Mithilfe eines Schwellwertes werden dann geeignete Merkmale herausgefiltert. Der Filter-Ansatz bietet eine schnelle und, aufgrund der geringen Komplexität, leicht skalierbare Lösung für die Merkmalsselektion. Der Nachteil von Filter-Selektoren besteht in der Missachtung der Abhängigkeiten zwischen den Merkmalen. So werden redundante Merkmale ähnlich bewertet und verzerren später die Erfolgsrate des Klassifikators. Bekannte Beispiele für Filter-Selektoren sind unter anderem die Euklidische Distanz und der Chi-2-Test.

Der Wrapper-Ansatz verbindet die Merkmalsbewertung mit einem Klassifikator. Innerhalb des Merkmalsraumes werden verschiedene Teilmengen von Merkmalen generiert und mithilfe eines trainierten Klassifikators getestet. Um alle möglichen Teilmengen des Merkmalsraumes zu identifizieren, wird der Klassifikator mit einem Suchalgorithmus kombiniert. Da der Merkmalsraum mit Zunahme der Anzahl der Merkmale exponentiell steigt, werden heuristische Suchmethoden für die Suche nach optimalen Teilmengen genutzt. Im Gegensatz zu den Filtern können hier redundante Merkmale abgefangen werden. Die Nutzung eines Klassifikators zur Bewertung der Teilmengen ist zugleich Vor- und Nachteil. Da die generierte Teilmenge auf einen speziellen Klassifikator zugeschnitten wird, ist nicht gewährleistet, dass die Menge auch für andere Klassifikatoren optimal ist. Somit ist dieser Ansatz zumeist abhängig vom gewählten Klassifikator. Zudem benötigt der Wrapper-Ansatz eine viel höhere Rechenzeit. Wrapper-Selektoren werden beispielsweise durch Genetische Algorithmen und Sequentielle Forward/Backward-Selektoren vertreten.

Embedded-Ansätze stellen eine Sonderform der Wrapper-Methode da. Allerdings werden Merkmalssuche und Klassifikatoren-Training nicht getrennt. Die Suche der optimalen Teilmenge ist hier im Modelltraining eingebettet. Dadurch liefern Embedded-Ansätze die gleichen Vorteile wie die Wrapper-Methoden, während die Rechenzeit dabei erheblich gesenkt werden kann. Der reduzierte Merkmalsraum ist aber auch hier vom jeweiligen Klassifikator abhängig. Klassifikatoren, die den Embedded-Ansatz ermöglichen sind beispielsweise der Random-Forest oder die Support-Vector-Maschine.

Entwicklungsgrundlage

Analog zum letzten Tutorial wird hier Python(x,y) und die Datenbasis „Human Activity Recognition Using Smartphones“ genutzt. Die Datenbasis beruht auf erfassten Sensordaten eines Smartphones während speziellen menschlichen Aktivitäten: Laufen, Treppen hinaufsteigen, Treppen herabsteigen, Sitzen, Stehen und Liegen. Auf den Aufzeichnungen von Gyroskop und Accelerometer wurden mehrere Merkmale erhoben. Die Datenmenge, alle zugehörigen Daten und die Beschreibung der Daten sind frei verfügbar.

(https://archive.ics.uci.edu/ml/datasets/Human+Activity+Recognition+Using+Smartphones)

Alle Daten liegen im Textformat vor. Für ein effizienteres Arbeiten mit der Datenbasis wurden diese im Vorfeld in das csv-Dateiformat überführt.

Python-Bibliotheken

Alle für das Data Mining relevanten Bibliotheken sind in Python(x,y) bereits enthalten. Für die Umsetzung werden folgende Bibliotheken genutzt:

import numpy as np
import pandas as pd

from sklearn.cross_validation import StratifiedKFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import f_classif, RFECV, SelectKBest
from sklearn.svm import SVC

Die Bibliotheken NumPy und Pandas unterstützen die Arbeit mit verschiedenen Datenstrukturen und scikit-learn umfasst alle Funktionen des maschinellen Lernens.

Daten vorbereiten

Vor der Anwendung der einzelnen Verfahren werden die Daten vorbereitet. Das Data Frame wird eingelesen, die Klassen in numerische Labels überführt und das Datenfeld in Merkmale (X) und Klassenspalte (y) separiert. Weiterhin wird die informationslose Spalte subject entfernt.

index = 0
selected_features = []

# reading database
data = pd.read_csv("data/measures.csv", sep = ';', decimal = ',')

# converting textual class labels to numeric classes like description
data = data.replace({'WALKING': 1, 'WALKING_UPSTAIRS': 2, 'WALKING_DOWNSTAIRS': 3,
              'SITTING': 4, 'STANDING': 5, 'LAYING': 6})

# drop subject column
data = data.drop('subject', 1)

# remove class column from data set
print "removing class column from training set.."
X = data.drop('activity', 1)
y = data['activity']

columns = X.columns.values.tolist()

1. Verfahren: RFECV

Der RFECV (Recursive Feature Elimination with Cross Validation) ist ein Vertreter des Wrapper-Ansatzes. In diesem Beispiel wird die Merkmalsselektion mit einem Support Vector Klassifikator kombiniert. Der RFECV berechnet ein Ranking über die einzelnen Merkmale. Dabei bestimmt der Selektor selbst die optimale Menge der Merkmale. Alle Merkmale mit Platz 1 im Ranking bilden den optimalen Merkmalsraum.

''' ########## METHOD 1: RFE with cross validation and SVC ########## '''
print "create classifier for feature selection.."
svc = SVC(kernel = 'linear')

# fit the feature selector
print "create the feature selector.."
rfecv = RFECV(estimator = svc, step = 1, cv = StratifiedKFold(y, 3), scoring = 'accuracy')
print "fit the selector for data set.."
rfecv.fit(X, y)

print "The estimated number of optimal features is: " + str(rfecv.n_features_)

# get the most importent features
feat_importence = zip(rfecv.ranking_, columns)

# prepare list of selected features for new DataFrame
for i in range(len(feat_importence)):
    if(feat_importence[i][0] == 1):#>= np.nanmean(rfecv.ranking_)):
        selected_features.append(feat_importence[i][1])
        print "added feature: " + str(feat_importence[i][1]) + ".."

2. Verfahren: Random Forest-Klassifikator

Der Random-Forest-Klassifikator gehört zu den Modellen, die einen Embedded-Ansatz ermöglichen. Während des Klassifikatoren-Trainings wird jedem Merkmal ein Wert zugeordnet. Je höher der Wert, desto bedeutsamer das Merkmal. Allerdings ist hier eine manuelle Filterung notwendig, da anders als beim RFECV kein internes Optimum ermittelt wird. Mithilfe eines geeigneten Schwellwertes können die zu wählenden Merkmale bestimmt werden. In diesem Beispiel werden alle Merkmale selektiert, die eine Wichtung größer dem Mittelwert erhalten.

''' ########## METHOD 2: Random Forrest Classifier Feat Importance ########## '''
print "create classifier for feature selection.."
rfc = RandomForestClassifier(n_estimators = 500, criterion = 'entropy', max_depth = 4)
rfc = rfc.fit(X, y)

# get the most importent features
feat_importence = zip(rfc.feature_importances_, columns)

# prepare list of selected features for new DataFrame
for i in range(len(feat_importence)):
    if(feat_importence[i][0] >= np.mean(rfc.feature_importances_)):
        selected_features.append(feat_importence[i][1])
        print "added feature: " + str(feat_importence[i][1]) + ".."

3. Verfahren: Select K Best

Das Select K Best-Verfahren gehört den Filter-Ansätzen an. Daher kommt hier anders als bei den anderen beiden Verfahren kein Klassifikator zum Einsatz. Auch in diesem Verfahren wird für jedes Merkmal ein Wert berechnet, der die Wichtigkeit des Merkmals beziffert. Für die Berechnung der Werte können verschiedene Methoden verwendet werden. In diesem Beispiel wird eine Varianzanalyse genutzt (Parameter f_classif). Auch hier wird mithilfe eines manuellen Schwellwertes der reduzierte Merkmalsraum bestimmt.

''' ########## METHOD 3: Select K Best Features ########## '''
print "create classifier for feature selection.."
skb = SelectKBest(f_classif)
skb = skb.fit(X, y)

# get the most importent features
feat_importence = zip(skb.scores_, columns)

# prepare list of selected features for new DataFrame
for i in range(len(feat_importence)):
    if(feat_importence[i][0] >= np.nanmean(skb.scores_)):
        selected_features.append(feat_importence[i][1])
        print "added feature: " + str(feat_importence[i][1]) + ".."

Ergebnisse

Für die Bewertung der einzelnen Selektionsverfahren werden die einzelnen Verfahren in den Data-Mining-Prozess (siehe vorheriges Tutorial: Einstieg in das maschinelle Lernen mit Python(x,y)) integriert. Die nachfolgende Tabelle veranschaulicht die Ergebnisse der Klassifikation der einzelnen Verfahren.

 

Selektionsverfahren

Anzahl der Merkmale

Erfolgsrate Klassifikation

Ohne

561

93,96%

RFECV

314

94,03%

Random Forest

118

90,43%

Select K Best

186

92,30%

 

Durch den RFECV konnte das Ergebnis der Klassifikation leicht verbessert werden. Die anderen Selektionsverfahren, die auch deutlich weniger Merkmale nutzen, verschlechtern das Ergebnis sogar. Dies liegt vor allem an der manuellen Regulierung des Schwellwertes.

R als Tool im Process Mining

Die Open Source Sprache R ermöglicht eine Vielzahl von Analysemöglichkeiten, die von einer einfachen beschreibenden Darstellung eines Prozesses bis zur umfassenden statistischen Analyse reicht. Dabei können Daten aus einem Manufacturing Execution System, kurz MES, als Basis der Prozessanalyse herangezogen werden. R ist ein Open Source Programm, welches sich für die Lösung von statischen Aufgaben im Bereich der Prozessoptimierung sehr gut eignet, erfordert jedoch auf Grund des Bedienungskonzepts als Scriptsprache, grundlegende Kenntnisse der Programmierung. Aber auch eine interaktive Bedienung lässt sich mit einer Einbindung der Statistikfunktionen in ein Dashboard erreichen. Damit können entsprechend den Anforderungen, automatisierte Analysen ohne Programmierkenntnisse realisiert werden.

Der Prozess als Spagetti Diagramm

Um einen Überblick zu erhalten, wird der Prozess in einem „process value flowchart“, ähnlich einem Spagetti‐ Diagramm dargestellt und je nach Anforderung mit Angaben zu den Key Performance Indicators ergänzt. Im konkreten Fall werden die absolute Anzahl und der relative Anteil der bearbeiteten Teile angegeben. Werden Teile wie nachfolgend dargestellt, aufgrund von festgestellten Mängel bei der Qualitätskontrolle automatisiert ausgeschleust, können darüber Kennzahlen für den Ausschuss ermittelt werden.

Der Prozess in Tabellen und Diagrammen

Im folgenden Chart sind grundlegende Angaben zu den ausgeführten Prozessschritten, sowie deren Varianten dargestellt. Die Statistikansicht bietet eine Übersicht zu den Fällen, den sogenannte „Cases“, sowie zur Dauer und Taktzeit der einzelnen Aktivitäten. Dabei handelt es sich um eine Fertigungsline mit hohem Automatisierungsgrad, bei der jeder Fertigungsschritt im MES dokumentiert wird. Die Tabelle enthält statistische Angaben zur Zykluszeit, sowie der Prozessdauer zu den einzelnen Aktivitäten. In diesem Fall waren keine Timestamps für das Ende der Aktivität vorhanden, somit konnte die Prozessdauer nicht berechnet werden.

Die Anwendung von Six Sigma Tools

R verfügt über eine umfangreiche Sammlung von Bibliotheken zur Datendarstellung, sowie der Prozessanalyse. Darin sind auch Tools aus Six Sigma enthalten, die für die weitere Analyse der Prozesse eingesetzt werden können. In den folgenden Darstellungen wird die Möglichkeit aufgezeigt, zwei Produktionszeiträume, welche über eine einfache Datumseingabe im Dashboard abgegrenzt werden, gegenüber zu stellen. Dabei handelt es sich um die Ausbringung der Fertigung in Stundenwerten, die für jeden Prozessschritt errechnet wird. Das xbar und r Chart findet im Bereich der Qualitätssicherung häufig Anwendung zur ersten Beurteilung des Prozessoutputs.

Zwei weitere Six Sigma typische Kennzahlen zur Beurteilung der Prozessfähigkeit sind der Cp und Cpk Wert und deren Ermittlung ein Bestandteil der R Bibliotheken ist. Bei der Berechnung wird von einer Normalverteilung der Daten ausgegangen, wobei das Ergebnis aus der Überprüfung dieser Annahme im Chart durch Zahlen, als auch grafisch dargestellt wird.

Von Interesse ist auch die Antwort auf die Frage, welchem Trend folgt der Prozess? Bereits aus der Darstellung der beiden Produktionszeiträume im Box‐Whiskers‐Plot könnte man anhand der Mediane auf einen Trend zu einer Verschlechterung der Ausbringung schließen, den der Interquartilsabstand nicht widerspiegelt. Eine weitere Absicherung einer Aussage über den Trend, kann über einen statistischen Vergleichs der Mittelwerte erfolgen.

Der Modellvergleich

Besteht die Anforderung einer direkten Gegenüberstellung des geplanten, mit dem vorgefundenen, sogenannten „Discovered Model“, ist aufgrund der Komplexität beim Modellvergleich, dieser in R mit hohem Programmieraufwand verbunden. Besser geeignet sind dafür spezielle Process Miningtools. Diese ermöglichen den direkten Vergleich und unterstützen bei der Analyse der Ursachen zu den dargestellten Abweichungen. Bei Produktionsprozessen handelt es sich meist um sogenannte „Milestone Events“, die bei jedem Fertigungsschritt durch das MES dokumentiert werden und eine einfache Modellierung des Target Process ermöglichen. Weiterführende Analysen der Prozessdaten in R sind durch einen direkten Zugriff über ein API realisierbar oder es wurde vollständig integriert. Damit eröffnen sich wiederum die umfangreichen Möglichkeiten bei der statistischen Prozessanalyse, sowie der Einsatz von Six Sigma Tools aus dem Qualitätsmanagement. Die Analyse kann durch eine, den Kundenanforderungen entsprechende Darstellung in einem Dashboard vereinfacht werden, ermöglicht somit eine zeitnahe, weitgehend automatisierte Prozessanalyse auf Basis der Produktionsdaten.

Resümee

Process Mining in R ermöglicht zeitnahe Ergebnisse, die bis zur automatisierten Analyse in Echtzeit reicht. Der Einsatz beschleunigt erheblich das Process Controlling und hilft den Ressourceneinsatz bei der Datenerhebung, sowie deren Analyse zu reduzieren. Es kann als stand‐alone Lösung zur Untersuchung des „Discovered Process“ oder als Erweiterung für nachfolgende statistische Analysen eingesetzt werden. Als stand‐alone Lösung eignet es sich für Prozesse mit geringer Komplexität, wie in der automatisierten Fertigung. Besteht eine hohe Diversifikation oder sollen standortübergreifende Prozessanalysen durchgeführt werden, übersteigt der Ressourcenaufwand rasch die Kosten für den Einsatz einer Enterprise Software, von denen mittlerweile einige angeboten werden.

 

Datenschutz, Sicherheit und Ethik beim Process Mining – Regel 4 von 4:

Dieser Artikel ist Teil 4 von 4 aus der Reihe Datenschutz, Sicherheit und Ethik beim Process Mining.

english-flagRead this article in English:
Privacy, Security and Ethics in Process Mining – Rule 4 of 4


Schaffung einer Kooperationskultur

Möglicherweise ist der wichtigste Bestandteil bei der Schaffung eines verantwortungsbewussten Process Mining-Umfeldes der Aufbau einer Kooperationskultur innerhalb Ihrer Organisation. Process Mining kann die Fehler Ihrer Prozesse viel eindeutiger aufzeigen, als das manchen Menschen lieb ist. Daher sollten Sie Change Management-Experten miteinbeziehen wie beispielsweise Lean-Coaches, die es verstehen, Menschen dazu zu bewegen, sich gegenseitig “die Wahrheit“ zu sagen (siehe auch: Erfolgskriterien beim Process Mining).

Darüber hinaus sollten Sie vorsichtig sein, wie Sie die Ziele Ihres Process Mining-Projektes vermitteln und relevante Stakeholder so einbeziehen, dass ihre Meinung gehört wird. Ziel ist es, eine Atmosphäre zu schaffen, in der die Menschen nicht für ihre Fehler verantwortlich gemacht werden (was nur dazu führt, dass sie verbergen, was sie tun und gegen Sie arbeiten), sondern ein Umfeld zu schaffen, in dem jeder mitgenommen wird und wo die Analyse und Prozessverbesserung ein gemeinsames Ziel darstellt, für das man sich engagiert.

Was man tun sollte:

  • Vergewissern Sie sich, dass Sie die Datenqualität überprüfen, bevor Sie mit der Datenanalyse beginnen, bestenfalls durch die Einbeziehung eines Fachexperten bereits in der Datenvalidierungsphase. Auf diese Weise können Sie das Vertrauen der Prozessmanager stärken, dass die Daten widerspiegeln, was tatsächlich passiert und sicherstellen, dass Sie verstanden haben, was die Daten darstellen.
  • Arbeiten Sie auf iterative Weise und präsentieren Sie Ihre Ergebnisse als Ausgangspunkt einer Diskussion bei jeder Iteration. Geben Sie allen Beteiligten die Möglichkeit zu erklären, warum bestimmte Dinge geschehen und seien Sie offen für zusätzliche Fragen (die in der nächsten Iteration aufgegriffen werden). Dies wird dazu beitragen, die Qualität und Relevanz Ihrer Analyse zu verbessern, als auch das Vertrauen der Prozessverantwortlichen in die endgültigen Projektergebnisse zu erhöhen.

Was man nicht tun sollte:

  • Voreilige Schlüsse ziehen. Sie können nie davon ausgehen, dass Sie alles über den Prozess wissen. Zum Beispiel können langsamere Teams die schwierigen Fälle behandeln, es kann gute Gründe geben, von dem Standardprozess abzuweichen und Sie sehen möglicherweise nicht alles in den Daten (beispielsweise Vorgänge, die außerhalb des Systems durchgeführt werden). Indem Sie konstant Ihre Beobachtungen als Ausgangspunkt für Diskussionen anbringen und den Menschen die Möglichkeit einräumen, Ihre Erfahrung und Interpretationen mitzugeben, beginnen Sie, Vertrauen und die Kooperationskultur aufzubauen, die Process Mining braucht.
  • Schlussfolgerungen erzwingen, die ihren Erwartungen entsprechen oder die sie haben möchten, indem Sie die Daten falsch darstellen (oder Dinge darstellen, die nicht wirklich durch die Daten unterstützt werden). Führen Sie stattdessen ganz genau Buch über die Schritte, die Sie bei der Datenaufbereitung und in Ihrer Process-Mining-Analyse ausgeführt haben. Wenn Zweifel an der Gültigkeit bestehen oder es Fragen zu Ihrer Analysebasis gibt, dann können Sie stets zurückkehren und beispielsweise zeigen, welche Filter bei den Daten angewendet wurden, um zu der bestimmten Prozesssicht zu gelangen, die Sie vorstellen.

Toolkits & Services für Semantische Textanalysen

Named Entity Recognition ist ein Teilgebiet von Information Extraction. Ziel von Information Extraction ist die Gewinnung semantischer Informationen aus Texten (im Gegensatz zum verwandten Gebiet des Information Retrieval, bei dem es um das möglichst intelligente Finden von Informationen, die u.U. vorab mit Information Extraction gewonnen wurden, geht). Named Entity Recognition (kurz NER) bezeichnet die Erkennung von Entitäten wie z.B. Personen, Organisationen oder Orten in Texten.

[box]Beispiel:
Albert Einstein war ein theoretischer Physiker, der am 14. März 1879 in Ulm geboren wurde. Er erhielt 1921 den Nobelpreis für Physik. Isaac Newton, Einstein und Stephen Hawking werden oft als die größten Physiker seit der Antike bezeichnet.”[/box]

Die Disambiguierung von Entitäten ist ein weiterer wichtiger Schritt auf dem Weg zu einem semantischen Verständnis von Texten. Wenn man so in obigem Text erkennen kann, dass “Albert Einstein“, “Er” und “Einstein” die gleiche Person bezeichnen, so kann ein Analyseverfahren z.B. daraus schließen, dass in diesem Text Einstein eine wichtigere Rolle spielt, als Newton, der nur einmal erwähnt wurde. Die Hyperlinks hinter den jeweiligen Entitäten zeigen eine Möglichkeit der semantischen Anreicherung von Texten an – in diesem Fall wurden die Entitäten mit entsprechenden Einträgen bei DBpedia automatisch verlinkt.

Named Entity Recognition dient vorrangig zwei Zwecken:

  • Anreicherung von Texten mit Metadaten
  • Abstraktion von Texten zur besseren Erkennung von Mustern

Punkt 1 dient direkt dem Information Retrieval. Anwender können so z.B. gezielt nach bestimmten Personen suchen, ohne alle möglichen Schreibweisen oder Berufsbezeichnungen auflisten zu müssen.

Punkt 2 dient der Vorverarbeitung von Texten als Input für Machine Learning Verfahren. So ist es (je nach Anwendung!) oft nicht von Bedeutung, welche Person, welcher Ort oder auch welche Uhrzeit in einem Text steht sondern nur die Tatsache, dass Personen, Orte oder Zeiten erwähnt wurden.

Sirrus Shakeri veranschaulicht die zentrale Bedeutung semantischer Analyse in seinem Beitrag From Big Data to Intelligent Applications:

intelligent-applications-cirrus-shakeri

Abbildung 1: Von Big Data zu Intelligent Applications von Cirrus Shakeri

Sein “Semantic Graph” setzt voraus, dass Entitäten mittels “Natural Language Processing” erkannt und zueinander in Beziehung gesetzt wurden.

Es ist interessant zu vermerken, dass Natural Language Processing und Data Mining / Machine Learning über viele Jahre als Alternativen zueinander und nicht als Ergänzungen voneinander gesehen wurden. In der Tat springen die meisten Vorgehensmodelle heutzutage von “Data Preparation” zu “Machine Reasoning”. Wir argumentieren, dass sich in vielen Anwendungen, die auf unstrukturierten Daten basieren, signifikante Qualitätsverbesserungen erzielen lassen, wenn man zumindest NER (inklusive Disambiguierung) in die Pipeline mit einbezieht.

Toolkits und Services für NER

Es existiert eine Vielzahl von Toolkits für Natural Language Processing, die Sie mehr oder weniger direkt in Ihre Programme einbinden können. Exemplarisch seien drei Toolkits für Java, Python und R erwähnt:

Diese Toolkits enthalten Modelle, die auf Korpora für die jeweils unterstützten Sprachen trainiert wurden. Sie haben den Vorteil, dass sie auch vollkommen neue Entitäten erkennen können (wie z.B. neue Politiker oder Fernsehstars, die zur Trainingszeit noch unbekannt waren). Je nach Einstellung haben diese Systeme aber auch eine relativ hohe Falsch-Positiv-Rate.

Wer NER nur ausprobieren möchte oder lediglich gelegentlich kleinere Texte zu annotieren hat, sei auf die folgenden Web Services verwiesen, die auch jeweils eine REST-Schnittstelle anbieten.

DBpedia

Das DBpedia Projekt nutzt die strukturierten Informationen der verschieden-sprachigen Wikipedia Sites für den Spotlight Service. Im Unterschied zu den reinen Toolkits nutzen die nun genannten Werkzeuge zusätzlich zu den trainierten Modellen eine Wissensbasis zur Verringerung der Falsch-Positiv-Rate. Die mehrsprachige Version unter http://dbpedia-spotlight.github.io/demo zeigt die Möglichkeiten des Systems auf. Wählen Sie unter “Language” “German“) und dann über “SELECT TYPES…” die zu annotierenden Entitätstypen. Ein Beispieltext wird automatisch eingefügt. Sie können ihn natürlich durch beliebige andere Texte ersetzen. Im folgenden Beispiel wurden “Organisation”, “Person”, und “Place“ ausgewählt:

DBprediaSpotlight

Abbildung 2: DBpedia Demo (de.dbpedia.org)

Die erkannten Entitäten werden direkt mit ihren DBpedia Datenbankeinträgen verlinkt. Im Beispiel wurden die Orte Berlin, Brandenburg und Preußen sowie die Organisationen Deutsches Reich, Deutsche Demokratische Republik, Deutscher Bundestag und Bundesrat erkannt. Personen wurden in dem Beispieltext nicht erkannt. Die Frage, ob man “Sitz des Bundespräsidenten” als Ort (Sitz), Organisation (das Amt des Bundespräsidenten) und / oder Person (der Bundespräsident) bezeichnen sollte, hängt durchaus vom Anwendungsszenario ab.

OpeNER

Das OpeNER Projekt ist das Ergebnis eines europäischen Forschungsprojekts und erweitert die Funktionalität von DBpedia Spotlight mit weiteren semantischen Analysen. Die Demo unter http://demo2-opener.rhcloud.com/welcome.action (Tab “Live Analysis Demo“, “Named Entity Recognition and Classification” und “Named Entity Linking” auswählen und “Analyse” drücken, dann auf der rechten Seite das Tab “NERC” anwählen) ergibt für den gleichen Beispieltext:

opeNER-projekt

Abbildung 3: OpeNER Projekt (opener-project.eu)

Organisationen sind blau hinterlegt, während Orte orange markiert werden. Auch hier werden erkannte Entitäten mit ihren DBpedia Datenbankeinträgen verknüpft. Die Bedeutung dieser Verknüpfung erkennt man wenn man auf das Tab “Map” wechselt. Berlin wurde als Ort erkannt und über die Geo-Koordinaten (geo:long = 13.4083, geo.lat = 52.5186) im DBpedia Eintrag von Berlin konnte das Wort “Berlin” aus obigem Text automatisch auf der Weltkarte referenziert werden.

Es gibt eine Vielzahl weiterer Services für NLP wie z.B. OpenCalais. Einige dieser Services bieten bestimmte Funktionalitäten (wie z.B. Sentiment Analysis) oder andere Sprachen neben Englisch nur gegen eine Gebühr an.

Listen Tagger

Der Vollständigkeit halber sei noch erwähnt, dass in den meisten Anwendungsszenarien die oben genannten Werkzeuge durch sogenannte Listen-Tagger (englisch Dictionary Tagger) ergänzt werden. Diese Tagger verwenden Listen von Personen, Organisationen oder auch Marken, Bauteilen, Produktbezeichnern oder beliebigen anderen Gruppen von Entitäten. Listen-Tagger arbeiten entweder unabhängig von den oben genannten statistischen Taggern (wie z.B. dem Standford Tagger) oder nachgeschaltet. Im ersten Fall markieren diese Tagger alle Vorkommen bestimmter Worte im Text (z.B. „Zalando“ kann so direkt als Modemarke erkannt werden). Im zweiten Fall werden die Listen genutzt, um die statistisch erkannten Entitäten zu verifizieren. So könnte z.B. der Vorschlag des statistischen Taggers automatisch akzeptiert werden wenn die vorgeschlagene Person auch in der Liste gefunden wird. Ist die Person jedoch noch nicht in der Liste enthalten, dann könnte ein Mitarbeiter gebeten werden, diesen Vorschlag zu bestätigen oder zu verwerfen. Im Falle einer Bestätigung wird die neu erkannte Person dann in die Personenliste aufgenommen während sie im Falle einer Ablehnung in eine Negativliste übernommen werden könnte damit dieser Vorschlag in Zukunft automatisch unterdrückt wird.

Regular Expression Tagger

Manche Entitätstypen folgen klaren Mustern und können mit hoher Zuverlässigkeit durch reguläre Ausdrücke erkannt werden. Hierzu zählen z.B. Kreditkarten- oder Telefon- oder Versicherungsnummern aber auch in vielen Fällen Bauteilbezeichner oder andere firmeninterne Identifikatoren.

Fazit

Natural Language Processing und insbesondere Named Entity Recognition und Disambiguierung sollte Teil der Werkzeugkiste eines jeden Anwenders bei der Analyse von unstrukturierten Daten sein. Es existieren mehrere mächtige Toolkits und Services, die allerdings je nach Anwendungsgebiet kombiniert und verfeinert werden müssen. So erkennt DBpedia Spotlight nur Entitäten, die auch einen Wikipedia Eintrag haben, kann für diese aber reichhaltige Metadaten liefern. Der Stanford Tagger hingegen kann auch vollkommen unbekannte Personennamen aus dem textuellen Kontext erkennen, hat aber bei manchen Texten eine relativ hohe Falsch-Positiv-Rate. Eine Kombination der beiden Technologien und anwendungsspezifischen Listen von Entitäten kann daher zu qualitativ sehr hochwertigen Ergebnissen führen.