Deutsche Texte mit spaCy analysieren — Schritt für Schritt
Eine der bekanntesten quelloffenen Bibliotheken für Natural Language Processing (NLP) ist spaCy. Grund genug, die Ärmel hochzukrempeln und ein paar Experimente mit spaCy durchzuführen.
In diesem praxisnahen Tutorial zeige ich, wie wir mit nur vier Zeilen Python-Code in deutsch geschriebene User Stories analysieren können. Und was ein paar mehr Zeilen bewirken.
Ich hatte in diesem Blog bereits eine Menge zu NLP geschrieben. Durch das aktuelle Interesse an ChatGPT ist das Interesse sicher noch gestiegen. Dieses Mini-Tutorial zeigt, wie wir in einer halben Stunde erste Ergebnisse mit spaCy produzieren können.
Installation
Wer das hier Gezeigte selbst ausprobieren möchte, muss zunächst Python 3 installieren. Python hat sich inzwischen als die wichtigste Programmiersprache für NLP etabliert.
Wir brauchen weiterhin einen Paketmanager für Python. Ich benutze pip, es gibt aber auch andere.
Für diese kleine Beispiel brauchen wir noch nicht einmal einen Code-Editor (IDE). Wer den Code aber weiterentwickeln möchte, dem empfehle ich als IDE (Code-Editor) Visual Studio Code zu installieren. Die funktioniert auf allen gängigen Betriebssystemen und hat eine gute Unterstützung für die Programmierung in Python.
Nach der Installation von Python und pip installieren wir spaCy:
pip install -U pip setuptools wheel
pip install -U spacy
Zuletzt brauchen wir noch ein Sprachmodell. Hier können wir uns auf der spaCy-Webseite ein Sprachmodell aussuchen. Für dieses Tutorial benutze ich ein kleines deutsches Modell und installiere es folgendermaßen:
python3 -m spacy download de_core_news_sm
Das war’s auch schon!
Ein erster Test
Nun können wir unser erstes NLP-Programm schreiben:
import spacy
nlp = spacy.load("de_core_news_sm")
doc = nlp("Als Gastgeber möchte ich meine Freunde einladen, damit wir z.B. einen schönen Abend zusammen verbringen können.")
print([(w.text, w.pos_) for w in doc])
In den ersten zwei Zeilen importieren wir spaCy und konfigurieren es mit unserem deutschen Sprachmodell. In der dritten Zeile lassen wir spaCy auf eine in deutsch verfasste User Story los. In der vierten und letzten Zeile drucken wir das Ergebnis auf der Konsole aus:
[
('Als', 'ADP'),
('Gastgeber', 'NOUN'),
('möchte', 'AUX'),
('ich', 'PRON'),
('meine', 'DET'),
('Freunde', 'NOUN'),
('einladen', 'VERB'),
(',', 'PUNCT'),
('damit', 'SCONJ'),
('wir', 'PRON'),
('z.B.', 'NOUN')
('einen', 'DET'),
('schönen', 'ADJ'),
('Abend', 'NOUN'),
('zusammen', 'ADV'),
('verbringen', 'VERB'),
('können', 'AUX'),
('.', 'PUNCT')
]
Wir sehen, dass spaCy den Satz in Token zerlegt und diese klassifiziert hat. Für die Klassifizierung werden „Part of Speech“-Tags (POS-Tags) benutzt. In der Modellbeschreibung können wir nachschlagen, welche POS-Tags es bei unserem Modell gibt („Label Scheme“). Die Bedeutung vieler Bezeichner können wir natürlich leicht erraten (bspw AUX → Hilfsverb). Über spacy.explain() können wir auch eine kurze englische Beschreibung ausdrucken lassen:
print(spacy.explain("SCONJ"))
→ subordinating conjunction
Interessant ist das Token „z.B.“, welches nicht als Satzzeichen fehlinterpretiert wurde. Das zeigt schön, dass NLP mehr leistet als eine reine Mustererkennung.
Die Token enthalten neben .pos (Part of Speech) noch weitere Informationen, konkret:
- Lemma: Die neutrale Form des Tokens, bspw. schönen → schön
- Tag: Im Prinzip wie POS, nur mit mehr Details, bspw. ich → PPER (Personalpronomen, statt PRON Pronomen)
- Shape: Groß/Kleinschreibung, wobei jeder Buchstabe mit einem „X“ ersetzt wird, bspw. ‚z.B.‘ → ‚x.X.‘
- is alpha: Besteht das Token aus Buchstaben, bspw. ‚z.B.‘ → False
- is stop: Is das Token ein „Stop-Wort“, also ein extrem häufiges Wort in der gewählten Sprache, bspw. ‚damit‘ → True
- Dep: Syntaktische Abhängigkeit zwischen den Token — dazu gleich noch mehr.
Syntaktische Abhängigkeiten
Die syntaktischenb Abhängigkeiten sind das mächtigste Ergebnis von dem bisher geschriebenen Code. Um die syntaktischen Abhängigkeiten zu verstehen, hilft es, diese zunächst zu visualisieren. Dazu brauchen wir unserem Code nur die folgenden zwei Zeilen hinzuzufügen:
from spacy import displacy
displacy.serve(doc, style="dep")
Wenn wir den Code laufen lassen, dann startet Python einen Webserver, deren Seite wir im Webbrowser aufrufen können. Für dieses Beispiel sieht das Ergebnis folgendermaßen aus:

Es handelt sich hierbei um eine Baumstruktur. Die Wurzel des Baums ist das Wort „möchte“, welches den Wert „ROOT“ zurückgibt.
Ausblick
Es ist schon spannend, was wir mit ein paar Zeilen Code machen können. Was ich hier gezeigt habe ist nur die Spitze des Eisberges. spaCy kann Begriffe erkennen (Named Entities), Ähnlichkeiten bewerten und vieles mehr.
Der bisher gezeigte Code hat noch keinen praktischen Nutzen, kann aber schnell entsprechend ausgebaut werden. Wir könnten zum Beispiel durch die Abhängigkeiten die Satzstruktur analysieren und entscheiden, ob es sich bei einem Satz um eine User Story handelt oder nicht.
Oder wir könnten Subjekt, Objekt und Prädikat finden um damit eine Ontologie aufzubauen.
Um wirklich praxistauglich zu sein, muss die Qualität ausreichen, um den den Nutzern zu helfen und sie nicht zu frustrieren. In der Praxis bedeutet dies, dass wir einen robusten Rahmen für die Entwicklung brauchen und mit entsprechenden Trainingsdaten das System systematisch verbessern. Dazu hatte ich bereits im HOOD-Blog einen Artikel zu MLOps geschrieben.