Textklassifikation mit Elasticsearch

Die Suchmaschine Elasticsearch ist weitverbreitet und auch als Analytics-Tool bekannt. Dass sie sich auch fürs Text-Mining einsetzen lässt, ist vielen hingegen weniger vertraut. Dieser Artikel stellt deswegen die Klassifikation von Texten mit Elasticsearch vor.

Know-how  –  0 Kommentare
Textklassifikation mit Elasticsearch

Elasticsearch überzeugt durch den leichten Einstieg, Geschwindigkeit und zahlreiche Möglichkeiten, komplexe Funktionen vergleichsweise einfach zu konfigurieren. Wer viel mit dem Werkzeug arbeitet, entdeckt irgendwann, dass es viel mehr als nur eine klassische Suchmaschine ist. So lassen sich damit auch Probleme aus den Bereichen Computerlinguistik und Text-Mining lösen, für die sonst spezielle Tools zum Einsatz kommen.

Die meisten Aufgaben im Bereich der Computerlinguistik beginnen mit einer Standard-Vorverarbeitungs-Pipeline mit folgenden Komponenten:

  1. Datenakquise (Web-Crawling, vom Dateisystem, von einer Datenbank etc.)
  2. Extraktion des Rohtexts
  3. Satzgrenzen bestimmen (Sentence splitting)
  4. Tokenisierung
  5. Normalisierung (Stemming, Lemmatisierung)
  6. Entfernen von Stoppwörtern
  7. Part-of-Speech Tagging

Einige Aufgaben der Computerlinguistik wie syntaktisches Parsing erfordern eine tiefenlinguistische Analyse. Für diese Art von Aufgaben ist Elasticsearch nicht die ideale Software. Für alles, was über das Token-Level hinausgeht, sind Plug-ins zu implementieren beziehungsweise zu verwenden, die den kompletten Text eines Dokuments bearbeiten.

Für Aufgaben wie Klassifikation, Clustering, Extraktion von Keywords und Messung der Ähnlichkeit reicht für gewöhnlich eine normalisierte und eventuell gewichtete "Bag of Words"-Repräsentation eines Dokuments.

Die Schritte 1 und 2 aus der Vorverarbeitungs-Pipeline lassen sich mit dem Ingest Attachment Processor Plugin (vor Version 5.0 Mapper Attachments Plugin) für Elasticsearch umsetzen. Die Rohtextextraktion der beiden Plug-ins basiert auf der Bibliothek Apache Tika, die es ermöglicht, aus gängigen Dateiformaten (HTML, PDF, Word etc.) das Markup zu entfernen und den Text zu extrahieren. Die Schritte 4, 5 und 6 übernehmen automatisch beim Indexieren Language Analyzer. Die meisten dieser Analyzer in Elasticsearch bestehen aus einem Tokenizer, einem Stemmer und einer sprachspezifischen Stoppwortliste.

Sample-Mapping:

{"properties": {
"content": {
"type": "text",
"analyzer" : "german"
}
}
}

Es wird also kein weiterer Code benötigt, um ein Dokument (PDF, HTML etc.) in eine interne "Bag of Words"-Repräsentation zu überführen. Man kann sogar den dedizierten Analyseendpunkt aufrufen und sich das vorverarbeitete Dokument ausgeben lassen:

curl -XGET "http://localhost:9200/_analyze?analyzer=english" -d'
{
"text" : "This is a test."
}'

{
"tokens": [
{
"token": "test",
"start_offset": 10,
"end_offset": 14,
"type": "<ALPHANUM>",
"position": 3
}
]
}

Für Sprachen mit geringerer Verbreitung kann das eine gute Lösung sein (z. B. für dänisch). Klassischerweise wird solch eine Pipeline wie folgt implementiert: Mittels eines Skripts wird der Text aus einer Quelle gezogen und der Rohtext extrahiert. Dann benötigt man eine Bibliothek speziell für die linguistische Vorverarbeitung wie NLTK, OpenNLP, Stanford NLP oder Spacy und im Anschluss ist noch über eine Stoppwortliste zu filtern. Das kostet jedes Mal wieder Zeit. Mit den in Elasticsearch eingebauten sprachspezifischen Analyzern geschieht das alles automatisch beim Indexieren.

Traditionell und Elasticsearch

Traditionelle Methode für die Textklassifikation

Textklassifikation wird normalerweise mit Methoden des überwachten maschinellen Lernens gelöst. Zum Trainieren der Modelle benötigt man Dokumente mit Label. Die Minimalversion eines solchen Dokuments besteht aus zwei Feldern: "text" und "label". Für maschinelles Lernen stehen zahlreiche Open-Source-Bibliotheken zur Verfügung: SciKit Learn, Weka, NLTK, Apache Mahout et cetera.

Die meisten Algorithmen im Machine Learning benötigen eine Repräsentation der Daten als Vektoren (Lineare Algebra). Die Dimensionen (oder Features) bestehen meist aus den zum Beispiel 10.000 wichtigsten Wörtern oder Bigrammen eines Datensatzes.

Wie lässt sich nun ermitteln, wie wichtig ein Wort in einem gegebenen Kontext ist? Ein bewährtes und erprobtes Maß hierfür ist tf–idf. Diese Formel wurde bereits in den 70er-Jahren erfunden. Hat ein Wort in einem Dokument einen hohen tf–idf-Wert, ist es für dieses besonders charakteristisch und unterscheidet es so von allen anderen besonders gut.

Die Keywords mit den höchsten tf–idf-Scores in einer Teilmenge von Dokumenten repräsentieren ein Thema, wenn die Daten viel Fachterminologie enthalten. Daher liegt es nahe, für die Textklassifikation mit tf–idf gewichtete Keywords als Features für die Vektoren zu verwenden. Nachdem jedes Dokument aus dem Training-Set in diese Form überführt wurde, werden alle Datensätze nach Labels gruppiert und zum Beispiel mit einer Support Vector Machine (SVM) oder einem Naive-Bayes-Algorithmus trainiert. Damit lassen sich neue Dokumente klassifizieren. Die Klasse, die dem neuen Dokument am ähnlichsten ist, bekommt den höchsten Score.

Textklassifikation mit Elasticsearch

All das lässt sich auch mit Elasticsearch (oder Lucene) lösen, und zwar deutlich einfacher. Dazu sind nur die folgenden vier Schritte auszuführen:

  1. Setze das Mapping explizit ("inhalt" : "text", "kategorie" : "keyword").
  2. Indexiere die Dokumente.
  3. Führe eine More Like This Query (MLT Query) mit dem neuen Dokument als like_text aus.
  4. Schreibe ein kleines Skript, um die Label der Top-Ergebnisse mit Score zu aggregieren.

Die MLT Query ist sehr wichtig im Text-Mining. Sie kann beliebigen Text als Input nehmen, extrahiert daraus automatisch die besten n Keywords relativ zum aktuellen Index und baut dann intern eine Bool-Query mit diesen Schlüsselwörtern zusammen. Mit ihr kann man vor allem nach ähnlichen Dokumenten suchen. Wenn alle im Index ein Label haben (Kategorie) und pro Klasse eine ähnlich große Anzahl an Dokumenten vorliegt (balancierter Trainingskorpus), ist diese Methode äquivalent zur Klassifikation mit einem Machine-Learning-Verfahren.

PUT sample
POST sample/document/_mapping
{
"properties": {
"content": {
"type": "text",
"analyzer" : "english"
},
"category": {
"type": "text",
"analyzer" : "english",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}

POST sample/document/1
{
"category" : "Apple (Fruit)",
"content" : "Granny Smith, Royal Gala, Golden Delicious and
Pink Lady are just a few of the thousands of different kinds
of apple that are grown around the world! You can make dried
apple rings at home - ask an adult to help you take out the core,
thinly slice the apple and bake the rings in the oven at a
low heat."
}

POST sample/document/2
{
"category" : "Apple (Company)",
"content" : "Apple is an American multinational technology
company headquartered in Cupertino, California, that designs,
develops, and sells consumer electronics, computer software,
and online services. Its hardware products include the iPhone
smartphone, the iPad tablet computer, the Mac personal computer,
the iPod portable media player, the Apple Watch smartwatch, and
the Apple TV digital media player. Apple's consumer software
includes the macOS and iOS operating systems, the iTunes media
player, the Safari web browser, and the iLife and iWork
creativity and productivity suites. Its online services include
the iTunes Store, the iOS App Store and Mac App Store, Apple
Music, and iCloud."
}

GET sample/document/_search
{
"query": {
"more_like_this": {
"fields": [
"content",
"category"
],
"like_text": "The apple tree (Malus pumila, commonly and
erroneously called Malus domestica) is a deciduous tree in
the rose family best known for its sweet, pomaceous fruit,
the apple. It is cultivated worldwide as a fruit tree, and
is the most widely grown species in the genus Malus. The tree
originated in Central Asia, where its wild ancestor, Malus
sieversii, is still found today. Apples have been grown for
thousands of years in Asia and Europe, and were brought to
North America by European colonists. Apples have religious and
mythological significance in many cultures, including Norse,
Greek and European Christian traditions.",
"min_term_freq": 1,
"max_query_terms": 20
}
}
}

Dieses Beispiel dient nur zur Veranschaulichung. Für die Klassifikation benötigt man mehr Daten. Hier nun ein Python-Skript zum Ermitteln der besten Kategorie:

def get_best_category(response):
categories = {}
for hit in response['hits']['hits']:
score = hit['_score']
for category in hit['_source']['category']:
if category not in categories:
categories[category] = score
else:
categories[category] += score

if len(categories) > 0:
sortedCategories = sorted(categories.items(),
key=operator.itemgetter(1), reverse=True)
category = sortedCategories[0][0]
return category

Anwendungszenarien

Es gibt zahlreiche praktische Anwendungsfälle für die Textklassifikation, zum Beispiel im E-Commerce-Bereich, denn schließlich gibt es viele Online-Shops oder Meta- beziehungsweise Preisvergleichssuchmaschinen. Die Daten kommen oft aus Affiliate-Netzwerken und meist aus mehreren Shops, wobei jeder sein eigenes Kategoriensystem hat. Also sind die Kategoriensysteme zu vereinheitlichen oder aber die Daten in ein neues zu überführen.

Ein weiterer praktischer Anwendungsfall liegt im Bereich Business Intelligence: Eine Firma möchte ihre Kunden einer Branche zuordnen. Als Trainingsmodell könnte man die Wikipedia-Einträge zu den jeweiligen Branchen heraussuchen und vielleicht noch weitere Daten. Die Firmen werden dann durch ihre Webseite repräsentiert.

Fazit

Evaluierung in der Praxis

Dieser Ansatz wurde mit einem Standarddatensatz für die Textklassifikation evaluiert. Im Zuge des "20 Newsgroups Dataset" wurde die höchste Genauigkeit von 92 Prozent mit einem sehr hohen Schwellenwert erzielt. Dadurch klassifizierte man nur 12 Prozent der Daten. Wenn alle Dokumente aus dem Testset gelabelt werden, liegt die Genauigkeit bei 72 Prozent.

Die besten Algorithmen für die Textklassifikation sind normalerweise SVM und Naive Bayes. Damit lassen sich fast alle Dokumente mit einem hohen Score klassifizieren. Warum sollte man also für die Textklassifikation Elasticsearch in Erwägung ziehen, wenn es bessere Algorithmen gibt? Es gibt einige praktische Gründe: Das Trainieren von Modellen, vor allem mit SVM, dauert lange. Wenn sich die Anforderungen ständig ändern oder man das Modell schnell für neue Kunden anpassen muss, kann das ein echtes Problem werden. Es wird dann vielleicht nicht mehr möglich sein, jedes Mal neu zu trainieren, wenn sich die Daten ändern. Man arbeitet eine Zeit lang mit veralteten Modellen und dann schneiden die Evaluationsergebnisse sicherlich nicht mehr so gut ab.

Mit Elasticsearch gibt es keine Trainingsphase. Sobald die Daten indexiert sind, können sie in Echtzeit neue Daten klassifizieren. Das Training geschieht quasi beim Indexieren. Das Modell lässt sich ständig in Echtzeit aktualisieren – ohne Ausfallzeit. Wenn die Daten sowieso in Elasticsearch liegen, benötigt man keine zusätzliche Infrastruktur. Mit über 10 Prozent sehr gut klassifizierten Daten kann man meist die erste Seite der Suchergebnisse füllen. Das reicht für einen ersten guten Eindruck. In diesem Fall hat die Klassifikation mit Elasticsearch viele Vorteile. (ane)

Saskia Vola
hat an der Universität Heidelberg Computerlinguistik studiert. Sie arbeitet seit 2009 als Entwicklerin im Bereich Text-Mining. Nach ein paar Jahren in der Berliner Start-up-Szene beschloss sie, Freelancer und digitaler Nomade zu werden. Zuletzt gründete sie die Freelancer-Plattform textminers.io für Projekte im Bereich Text-Mining, NLP und AI.