title | description | prev | next | type | id |
---|---|---|---|---|---|
Kapitel 4: Trainieren eines neuronalen Netzwerks |
In diesem Kapitel lernst du, wie du spaCys statistische Modelle aktualisieren und für deine spezielle Anwendung anpassen kannst – zum Beispiel, um eine neue Art von Entität in Online-Kommentaren vorherzusagen. Du wirst deine eigene Trainingsschleife schreiben und die Grundlagen des Trainingsprozesses verstehen, samt Tipps und Tricks, die deine NLP-Projekte erfolgreicher machen. |
/chapter3 |
chapter |
4 |
spaCy bietet zwar eine Reihe an vortrainierten Modellen, um linguistische Eigenschaften vorherzusagen. Jedoch möchte man Modelle eigentlich fast immer mit mehr Beispielen anpassen. Dies kannst du tun, indem du sie mit mehr annotierten Daten trainierst.
Womit kann Training nicht helfen?
Wenn ein vortrainiertes Modell keine guten Ergebnisse mit deinen Daten erzielt, ist es oft eine gute Lösung, das Modell mit mehr speziellen Beispielen zu trainieren.
Mithilfe von Training kannst du einem Modell neue Labels, Entitäten und andere Klassifizierungssysteme beibringen.
spaCys Komponenten sind überwachte Modelle für Textannotationen, was bedeutet, dass sie nur lernen können, Beispiele zu reproduzieren, nicht jedoch neue Labels auf Basis von rohem Text zu erraten.
spaCys regelbasierter Matcher
eignet sich super dazu, schnell Trainingsdaten
für Entitäten zu erstellen. Eine Liste mit Sätzen ist verfügbar als die Variable
TEXTS
. Du kannst sie ausdrucken, um sie zu begutachten. Wir wollen alle
Erwähnungen verschiedener iPhone-Modelle finden, damit wir Trainingsdaten
erstellen und einem Modell beibringen können, diese als "GADGET"
zu erkennnen.
- Schreibe ein Pattern für zwei Tokens, deren kleingeschriebene Form mit
"iphone"
und"x"
übereinstimmt. - Schreibe ein Pattern für zwei Tokens: ein Token, dessen kleingeschriebene Form
mit
"iphone"
übereinstimmt, und eine Ziffer.
- Um die kleingeschriebene Form eines Tokens zu beschreiben, kannst du das
Attribut
"LOWER"
verwenden. Zum Beispiel:{"LOWER": "apple"}
. - Um einen Ziffer-Token zu finden, kannst du das Attribut
"IS_DIGIT"
verwenden. Zum Beispiel:{"IS_DIGIT": True}
.
Lass uns die Patterns, die wir in der vorherigen Übung gerade erstellt haben,
verwenden, um schnell ein paar Trainingsdaten zu erstellen. Eine Liste mit
Sätzen ist verfügbar als Variable TEXTS
.
- Erstelle ein
Doc
-Objekt für jeden Text und benutze dafürnlp.pipe
. - Wende den Matcher auf das
doc
an und erstelle eine Liste der gefundenen Spans. - Erstelle
(Start-Buchstabe, End-Buchstabe, Label)
Tuples für die gefundenen Spans. - Formatiere alle Beispiele als Tuple bestehend aus Text und einem Dictionary
mit dem Schlüssel
"entities"
und den Entitäts-Tuples als Wert. - Füge die Beispiele zu
TRAINING_DATA
hinzu und begutachte die gedruckten Daten.
- Um Resultate der Patterns zu finden, rufe den
matcher
mit einemdoc
als Argument auf. - Die Resultate des Matchers sind
(match_id, start, end)
Tuples. - Um ein Beispiel zur Liste der Trainingsdaten hinzuzufügen, kannst du die
Methode
TRAINING_DATA.append()
verwenden.
In dieser Übung wirst du eine spaCy-Pipeline vorbereiten, um dem Entity
Recognizer beizubringen, "GADGET"
-Entitäten im Text zu erkennen – zum
Beispiel, "iPhone X".
- Erstelle ein leeres
"de"
-Modell, zum Beispiel mit der Methodespacy.blank
. - Erstelle einen neuen Entity Recognizer mithilfe der Methode
nlp.create_pipe
und füge ihn zur Pipeline hinzu. - Füge das neue Label
"GADGET"
zum Entity Recognizer hinzu und verwende hierfür die Methodeadd_label
des Pipeline-Komponenten.
- Um einen leeren Entity Recognizer zu erstellen, kannst du die Methode
nlp.create_pipe
mit dem String"ner"
als Argument aufrufen. - Um eine Komponente zur Pipeline hinzuzufügen, benutze die Methode
nlp.add_pipe
. - Die Methode
add_label
ist eine Methode der Entity Recognizer Pipeline-Komponente, welche du in der Variablener
gespeichert hast. Um ein Label hinzuzufügen, kannst duner.add_label
mit dem String-Namen des Labels aufrufen, zum Beispielner.add_label("EIN_LABEL")
.
Lass uns eine einfache Trainingsschleife erstellen!
Die Pipeline, die du in der vorherigen Übung erstellt hast, ist bereits als das
nlp
-Objekt verfügbar. Es enthält den Entity Recognizer mit dem neuen Label
"GADGET"
.
Die kleine Anzahl an Trainingsdaten, die du bereits erstellt hast, ist als
TRAINING_DATA
verfügbar. Um dir ein paar Beispiele anzusehen, kannst du sie in
deinem Skript drucken.
- Rufe
nlp.begin_training
auf, erstelle eine Trainingsschleife mit 10 Iterationen und mische die Trainingsdaten. - Erstelle Batches von Trainingsdaten mithilfe von
spacy.util.minibatch
und iteriere über die Batches. - Wandle die
(text, annotations)
Tuples im Batch in Listen vontexts
undannotations
um. - Verwende
nlp.update
, um das Modell mit den Texten und Annotationen aus dem Batch zu aktualisieren.
- Um das Training zu beginnen und die Gewichte zurückzusetzen, kannst du die
Methode
nlp.begin_training
aufrufen. - Um die Trainingsdaten in Batches aufzuteilen, rufe die Funktion
spacy.util.minibatch
mit der Liste der Trainingsdaten als Argument auf.
Mal gucken, wie das Modell abschneidet, wenn es neue Daten zu sehen bekommt. Um
das Ganze ein bisschen zu beschleunigen, haben wir schon einmal ein Modell mit
dem Label "GADGET"
trainiert und es über eine Auswahl an Texten laufen lassen.
Hier sind ein paar der Ergebnisse:
Text | Entitäten |
---|---|
iPhone X: Warum das iPhone 8 die bessere Wahl ist | (iPhone X, iPhone 8) |
Endlich verstehe ich, wofür der "Notch" beim iPhone X da ist | (iPhone X,) |
Alles was du über das Samsung Galaxy S9 wissen musst | (Samsung Galaxy,) |
Tablet-Modelle aus 2018s im Vergleich: so schneidet das iPad ab | (iPad,) |
iPhone 8 und iPhone 8 Plus sind Smartphones, die von Apple entwickelt und vermarktet werden. | (iPhone 8, iPhone 8) |
welches ist das günstigste ipad, vor allem ipad pro??? | (ipad, ipad) |
Samsung Galaxy ist eine Reihe mobiler Computergeräte, hergestellt und vermarktet von Samsung Electronics. | (Samsung Galaxy,) |
Im Vergleich zu allen korrekten Entitäten im Text, wie oft lag das Modell richtig? Denke daran, dass unvollständige Entitäten-Spans auch als Fehler zählen! Tip: Zähle die Entitäten, die das Modell hätte vorhersagen sollen. Zähle dann die Entitäten, die es tatsächlich korrekt vorhergesagt hat, und teile das Ergebnis durch die Anzahl der gesamten korrekten Entitäten.
Zähle die korrekt vorhergesagten Entitäten und teile das Ergebnis durch die Anzahl der Entitäten, die das Modell hätte vorhersagen sollen.
Zähle die korrekt vorhergesagten Entitäten und teile das Ergebnis durch die Anzahl der Entitäten, die das Modell hätte vorhersagen sollen.
In unserem Test erzielte das Modell eine Genauigkeit von 70%.
Zähle die korrekt vorhergesagten Entitäten und teile das Ergebnis durch die Anzahl der Entitäten, die das Modell hätte vorhersagen sollen.
Hier ist ein Auszug aus einem Trainingsdatenset, das die Entität
"TOURISTENZIEL"
in Reiseberichten annotiert.
TRAINING_DATA = [
(
"ich war letztes jahr in amsterdem und die kanäle warn superschön",
{"entities": [(24, 33, "TOURISTENZIEL")]},
),
(
"Du solltest einmal im Leben Paris besuchen, aber der Eiffelturm ist relativ langweilig",
{"entities": [(28, 33, "TOURISTENZIEL")]},
),
("Es gibt auch ein Paris in Arkansas lol", {"entities": []}),
(
"Berlin ist perfekt für einen Sommerurlaub: viele Parks, tolles Nachleben, günstiges Bier!",
{"entities": [(0, 6, "TOURISTENZIEL")]},
),
]
Warum sind diese Daten und das Labelsystem problematisch?
Ein besserer Ansatz wäre, lediglich "LOC"
für "Location" zu annotieren und
dann z.B. ein regelbasiertes System zu verwenden, um zu erkennen, ob die Entität
in diesem Kontext als Touristenziel erwählt wird. So könnte man die Entitäten
beispielsweise in einer Wissensdatenback oder einem Reise-Wiki nachschlagen.
Es ist zwar durchaus möglich, dass Paris, AR ebenfalls ein beliebtes Reiseziel für Touristen ist. Dies macht deutlich, wie subjektiv das Labelsystem ist und wie schwierig es sein wird, zu entscheiden, ob das Label zutrifft oder nicht. Aufgrund dessen wird es ebenfalls schwierig für den Entitiy Recognizer sein, diese Unterscheidung zu lernen.
Selbst sehr ungebräuchliche Wörter oder Falschschreibungen können als Entitäten annotiert werden.
Vorhersagen über Texte und Entitäten mit Schreibfehlern auf Basis des Kontexts zu treffen ist sogar einer der großen Vorteile von statistischen Modellen für Named Entity Recognition.
- Schreibe die Liste
TRAINING_DATA
um, sodass sie nur das Label"LOC"
(Location, Label verwendet für alle Orte im deutschen Modell) statt"TOURISTENZIEL"
verwendet. - Vergiss nicht, Tuples für die
"LOC"
-Entitäten hinzuzufügen, die vorher nicht annotiert waren.
- Bei den Spans, die bereits annotiert sind, musst du lediglich den Namen des
Labels von
"TOURISTENZIEL"
auf"LOC"
ändern. - Ein Text enthält eine Stadt und einen Bundesstaat, die noch nicht annotiert
sind. Um die Spans für die Entitäten hinzuzufügen, zähle die Zeichen und finde
den Anfang und das Ende der Span. Füge dann
(start, end, label)
Tuples zu den Entitäten hinzu.
Hier siehst du eine kleine Auswahl aus einem Trainingsdatenset für eine neue
Entität "WEBSITE"
. Das komplette Datenset enthält ein paar Tausend Sätze. In
dieser Übung wirst du die Annotation von Hand durchführen. Im echten Leben
würdest du das wahrscheinlich automatisieren und ein Annotations-Tool verwenden
– zum Beispiel, Brat, eine beliebte
Open-Source-Lösung, oder Prodigy, unser eigenes
Annotations-Tool, das zusammen mit spaCy verwendet werden kann.
- Vervollständige die Zeichen-Offsets für die
"WEBSITE"
-Entitäten in den Daten. Du kannst auch gernelen()
verwenden, wenn du keine Lust hast, die Zeichen zu zählen.
- Die Start- und End-Zeichen-Offsets einer Entitäts-Span beschreiben die
Position der Zeichen, an denen die Span anfängt und endet. Zum Beispiel, wenn
eine Entität an Position 5 beginnt, beträgt der Start-Zeichen-Offset
5
. Denke daran, dass die End-Offsets ausschließend sind – das heißt,10
bedeutet bis hin zu Zeichen 10.
Die Daten, die du gerade annotiert hast, wurden nun zusammen mit ein paar
Tausend ähnlichen Beispielen dazu verwendet, ein Modell zu trainieren. Nach dem
Training erzielt das Modell super Ergebnisse für das Label "WEBSITE"
, aber es
erkennt keine Entitäten mit dem Label "PER"
mehr. Warum könnte das passiert
sein?
Es ist für ein Modell definitiv kein Problem zu lernen, mehrere verschiedene Kategorien vorherzusagen. spaCys vortrainierte englische Modelle beispielsweise können sowohl Personen als auch Organisationen oder Prozentzahlen erkennen.
Wenn "PER"
-Entities in den Trainingsdaten vorkommen, aber nicht annotiert
sind, lernt das Modell, dass diese nicht vorhersagt werden sollen. Ebenso kann
das Modell eine Kategorie "vergessen" und sie nicht mehr vorhersagen, wenn diese
nicht in den Trainingsdaten vorhanden ist.
Auch wenn die Hyperparameter einen Einfluss auf die Ergebnisse eines Modells haben können, sind sie hier wahrscheinlich nicht das Problem.
- Aktualisiere die Trainingsdaten, sodass sie außerdem Annotationen für die
"PER"
-Entitäten "PewDiePie" und "Alexis Ohanian" enthalten.
- Um zusätzliche Entitäten zu annotieren, füge ein weiteres Tuple mit
(start, end, label)
zur Liste der Entitäten hinzu.