Kontaktieren

Der Rocketloop Blog

Vorverarbeitung von Text für Machine Learning in node.js

Für die Verwendung großer Daten für Machine Learning Verfahren bedarf es erst einer sorgfältigen Vorverarbeitung, die grundlegend ist für die Genauigkeit der Ausgabe. Betrachten wir die Klassifizierung von Texten auf Wortebene, so ist es wichtig, dass jegliche Texte vorverarbeitet werden, sprich jeder Text wird in Sätze unterteilt und dieser danach in einzelne Wörter. Der OpenNLP Wrapper für Node.js ist optimal dafür geeignet diese Vorverarbeitung zu leisten, denn dieser ist nicht nur detailliert konfigurierbar, sondern unterliegt auch der MIT License, sodass der private und kommerzielle Gebrauch kostenlos ist.

Installation

npm install opennlp

OpenNLP bietet folgende Verfahren einen Text zu verarbeiten/analysieren:

  • Chunker
  • Name Finder
  • Part of Speach Tagging
  • Sentence Detector
  • Tokenizer

Dafür stellt Apache unter http://opennlp.sourceforge.net/models-1.5/ eine Vielzahl trainierter Modelle zur Verfügung, die in verschiedenen Sprachen (zum Beispiel Englisch und Deutsch) heruntergeladen und eingebunden werden können. Zusätzlich benötigt man die opennlp-tools-1.6.0.jar, die hier heruntergeladen werden kann.

Konfiguration

In der folgenden Konfiguration wird der OpenNLP Wrapper mit den deutschen Modellen für den Sentence Detector und den Tokenizer initialisiert.

var openNLPOptions = {
    "models" : {
        "tokenizer": nlpPath + '/de-token.bin',
        "sentenceDetector": nlpPath + '/de-sent.bin',
    },
    "jarPath": nlpPath + "/opennlp-tools-1.6.0.jar"
};

Der große Vorteil hierbei ist, dass für die Verarbeitung einer anderen Sprache lediglich die Modelle ausgetauscht und sonst keinerlei Änderungen vorgenommen werden müssen.

Sentence Detector

Der Sentence Detector splittet die Texteingabe bei jedem Punkt und erkennt, ob es sich dabei um ein Satzende handelt oder um einen Punkt in einer Datumsangabe oder Abkürzung.

var openNLP = require("opennlp");
var sentence = 'Am 13. Juni 2014 wurde die deutsche Fußball Nationalmannschaft ' + 
               'Weltmeister. Das war der 4. Weltmeister Titel!';
var sentenceDetector = new openNLP().sentenceDetector;
sentenceDetector.sentDetect(sentence, function(err, results) {
    console.log(results)
    /*
    Ausgabe: 
    [ 
        'Am 13. Juni 2014 wurde die deutsche Fußball  Nationalmannschaft Weltmeister.', 
        'Das war der 4. Weltmeister Titel!'
    ]
    */
});

Tokenizer

Der Tokenizer splittet den Satz in einzelne Wörter und Satzzeichen auf. Leerzeichen zwischen Satzzeichen werden nicht verworfen, sondern als Token erkannt.

var openNLP = require("opennlp");
var sentences = "Am 12. Juni 2014 wurde die deutsche Fußball Nationalmannschaft Weltmeister.";
var tokenizer = new openNLP().tokenizer;
tokenizer.tokenize(sentence, function(err, results) {
    console.log(results);
    /*
    Ausgabe: [ 
                'Am',
                '12',
                '.',
                'Juni',
                '2014',
                'wurde',
                'die',
                'deutsche',
                'Fußball',
                'Nationalmannschaft',
                'Weltmeister',
                '.' 
            ]
    */
})

Optimierung

Verwendet man eine große Datenmenge an Text, so ist der OpenNLP Wrapper sehr gut, um die Texte zu verarbeiten, jedoch arbeitet dieser nicht effizient, da die Tokenisierung sequentiell abläuft und nicht parallel. Da die Dauer der Tokenisierung somit linear mit der Satzanzahl ansteigt, mussten wir hierfür eine effiziente Lösung finden. Dazu haben wir uns einen eigenen minimalistischen OpenNLP Wrapper geschrieben, der den Sentence Detector und den Tokenizer beinhaltet. Dieser ist auf https://github.com/flore2003/opennlp-wrapper zu finden und unterliegt der MIT License. Der Wrapper ist somit nicht vollkompatibel zum zuvor beschriebenen Wrapper.

Installation

npm install opennlp-wrapper

Die Konfiguration, Sentence Splitting und Tokenisierung unterscheidet sich hierbei leicht vom originalen Projekt, sodass ein einfacher Tausch der Bibliothek nicht genügt.

Konfiguration

Die folgende Konfiguration beschreibt den OpenNLP Wrapper, der von uns entwickelt wurde, mit den deutschen Modellen für den Sentence Detector und den Tokenizer initialisiert. Man beachte, dass auch hier die Konfiguration leicht angepasst wurde, im Vergleich zur original Bibliothek.

var openNLPOptions = {
    models : {
        "tokenizer": nlpPath +  'de-token.bin',
        "sentenceDetector": nlpPath + 'de-sent.bin'
    },
    "jarPath": nlpPath +  "opennlp-tools-1.6.0.jar"
};
var openNLP = new OpenNLP(openNLPOptions);

Sentence Detector

In der originalen Bibliothek wurde auf der OpenNLP Instanz sentenceDetector.sentDetect() aufgerufen. Hier genügt lediglich der Methodenaufruf detectSentences() auf der OpenNLP Instanz.

var input = 'Am 12. Juni 2014 wurde die Fußball Nationalmannschaft ' + 
            'Fußballweltmeister. Das war der 4. Weltmeister Titel!';

openNLP.detectSentences(input, function(err, sentences) {
    console.log(sentences);
});

Tokenizer

In der originalen Bibliothek wurde auf der OpenNLP Instanz tokenizer.tokenize aufgerufen. Hier genügt lediglich der Methodenaufruf tokenize() auf der OpenNLP Instanz.

var input = 'Am 12. Juni 2014 wurde die Fußball Nationalmannschaft Fußballweltmeister.';

openNLP.tokenize(input, function(err, tokens) {
    console.log(tokens);
});

Anmerkungen und Tipps

Damit die Daten für ein Machine Learning Verfahren, wie zum Beispiel Naive Bayes, geeignet sind, bedarf es noch weiteren Vorverarbeitungsschritten, wie die Verwendung eines Stemmers oder Lemmatisierers. Für die Verarbeitung von deutschem Text haben wir einen Stemmer verwendet, der folgendes Problem löst: Man betrachte die Wörter "Kauf, Käufe, kaufen, kaufe", die sich alle auf den Erwerb eines Artikels beziehen, jedoch unterschiedlich verwendet werden, aber dennoch das Gleiche aussagen. Der Stemmer extrahiert aus jedem Wort den Wortstamm, was in diesem Fall "kauf" entspricht. Führt man dieses Verfahren auf allen Wörtern durch, die man mittels des Tokenisierens ermittelt hat, so schrumpft die Anzahl unterschiedlicher Wörter um ein Vielfaches.

Der Snowball Stemmer ist hierfür sehr zu empfehlen, da er nicht nur sehr einfach zu verwenden ist, sondern auch über 13 verschiedene Sprachen unterstützt.

Nachdem man alle Wörter gestemmt hat sollte man noch die Stopworte entfernen. Hierzu zählen im Deutschen unter anderem bestimmte Artikel, unbestimmte Artikel und Konjunktionen. Im Englischen sind die Wörter 'a', 'of', 'the', 'I', 'it', 'you' und 'and' Teil der Stopwörter. Eine sehr gute Variante Stopworte zu bestimmten, ist nach dem Stemming alle Wörter nach absteigender Häufigkeit zu sortieren und die ersten 100 bis 200 Wörter dieser Liste zu betrachten und zu analysieren, welche Wörter wirklich nicht aussagekräftig sind und verworfen werden können.

Im nächsten Beitrag bauen wir auf diesem Wissen auf und entwickeln einen Naive Bayes Klassifizierer, der beispielsweise in der Spamerkennung eingesetzt wird.

Kommentare

Wir sind bereit! Was ist mit Ihnen?

Schreiben Sie uns einfach an hello@rocketloop.de

Kontakt

Rocketloop

Helmig Klein Reifschneider GbR

Trakehner Str. 7-9, Eingang B
60487 Frankfurt am Main
Deutschland
Gesellschafter

Patrick Helmig, Alex Klein und Florian Reifschneider

Umsatzsteuer-Identifikationsnummer gem. § 27a UStG

DE 310970201