Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

word2vec

Von der Anwendung her gedacht

Ein Beispiel-Task, unsupervised mit neuronalen Netzen: Alle Dokumente DiD_i einlesen als Liste von Wörtern (getrennt an Leerzeichen, Satzzeichen entfernt), dann jedes einzelne Wort mit einem zuvor trainierten neuronalen Netz umrechnen in eine andere Repräsentation, die sich besser vergleichen lässt. Die andere Repräsentation verschaffen wir uns durch latente Vektoren aus einem Autoencoder. Das ist die Idee von word2vec (Mikolov et al., Google, 2013).

Vorverarbeitung und Ziel

  1. Wir zählen alle Wörter (bzw. Token) im Korpus,

  2. entfernen Stopwords und sortieren nach Häufigkeit,

  3. behalten die häufigsten NN Wörter (z.B. N=5000N = 5000),

  4. kodieren diese mit One-Hot-Encoding als Vektoren in RN\mathbb{R}^N,

  5. mit dem Ziel, eine Abbildung e ⁣:RN→RKe \colon \mathbb{R}^N \to \mathbb{R}^K zu finden, K≪NK \ll N (z.B. K=200K = 200),

  6. mit einer „Decoder“-Abbildung d ⁣:RK→RNd \colon \mathbb{R}^K \to \mathbb{R}^N, sodass d(e(w))=wd(e(w)) = w für alle NN Wörter unserer Liste gilt,

  7. und semantisch ähnliche Wörter w1,w2w_1, w_2 nach Kodieren in RK\mathbb{R}^K einen kleinen Abstand d⁡(e(w1),e(w2))≈0\operatorname{d}(e(w_1), e(w_2)) \approx 0 haben.

Punkt 6 allein wäre ein gewöhnlicher Autoencoder auf One-Hot-Vektoren – und der lernt nichts über Bedeutung, denn One-Hot-Vektoren sind alle gleich weit voneinander entfernt. Punkt 7 ist der Clou.

Kernidee

Die Semantik eines Wortes ergibt sich durch seine Nutzung in Sätzen (distributional hypothesis). Beispiel: „Die [MASK] frisst ihr Futter am liebsten aus dem goldenen Napf“ kommt in Texten mit [MASK] = Katze und [MASK] = Hündin vor. Der Machine-Learning-Task, unsupervised: Gegeben Text, ersetze ein Wort durch [MASK] und lasse vorhersagen, was [MASK] ist – wie ein Denoising Autoencoder, bei dem das Rauschen im Löschen eines Wortes besteht.

CBOW (Continuous Bag of Words, für kleinere Korpora). Hyperparameter ist die Fenstergröße SS (window size), z.B. S=2S = 2. Eingabe: 2S+12S + 1 Token, die hintereinander im Text vorkommen, dabei das mittlere durch [MASK] ersetzt – also 2S2S One-Hot-Vektoren. Ausgabe: eine Wahrscheinlichkeitsverteilung auf allen NN Wörtern. Loss-Funktion: negative Log-Likelihood (NLL), d.h. Vergleich der ausgegebenen Verteilung mit dem One-Hot-Vektor für das Wort, welches sich hinter [MASK] verbirgt. Architektur: 1 Hidden Layer mit KK Neuronen, der „Encoder“ W∈RK×NW \in \mathbb{R}^{K \times N}, angewendet auf alle 2S2S Kontextwörter und dann gemittelt (averaging), danach ein Layer „Decoder“ W′∈RN×KW' \in \mathbb{R}^{N \times K} gefolgt von Softmax:

P(wmitte∣Kontext)=sm⁡(W′⋅12S∑j∈KontextWwj).P(w_{\text{mitte}} \mid \text{Kontext}) = \operatorname{sm}\Bigl( W' \cdot \frac{1}{2S} \sum_{j \in \text{Kontext}} W w_j \Bigr).

Die Wortvektoren sind die Spalten von WW: e(w)=Wwe(w) = W w ist für einen One-Hot-Vektor ww einfach die entsprechende Spalte.

Skip-gram, die Alternative zu CBOW: Gegeben ein Token, sage den Kontext vorher. Eingabe: das mittlere Token als One-Hot-Vektor für eine Abfolge von 2S+12S + 1 Token. Ausgabe: eine Wahrscheinlichkeitsverteilung auf allen NN Token. Loss-Funktion: NLL, d.h. Vergleich der ausgegebenen Verteilung mit der Summe der One-Hot-Vektoren für alle 2S2S Kontexttoken. Architektur: 1 Hidden Linear Layer mit KK Neuronen (der „Encoder“), danach ein Layer „Decoder“ mit NN Neuronen gefolgt von Softmax. Skip-gram funktioniert bei großen Korpora und seltenen Wörtern besser.

CBOW und Skip-gram: dieselben zwei Matrizen W (Encoder, N \to K) und W' (Decoder, K \to N), einmal von mehreren Kontextwörtern auf ein Wort, einmal umgekehrt.

CBOW und Skip-gram: dieselben zwei Matrizen WW (Encoder, N→KN \to K) und W′W' (Decoder, K→NK \to N), einmal von mehreren Kontextwörtern auf ein Wort, einmal umgekehrt.

word2vec benutzen

Verfügbare Gewichte WW gibt es mit Gensim (z.B. wiki-english-20171001) oder von Hugging Face (z.B. word2vec-google-news-300, N=3N = 3 Millionen, K=300K = 300). Klappt nicht gut? Drop-in-Ersatz für word2vec ist Facebooks fastText, welches hauptsächlich einen geeigneteren Tokenizer benutzt (Stichwort Subword-Tokenization) und dadurch auch mit unbekannten Wörtern umgehen kann.

word2vec selbst trainieren (ein ganz knapper Überblick)

Zutatenliste: Keine GPU oder andere Beschleuniger zur Hand? Google Colab oder CPU reicht. Input: ein Textkorpus zum Training, eine Tokenization-Strategie bzw. ein Tokenizer (darüber sprechen wir noch), die Dimension KK des Latent Space, CBOW oder Skip-gram (wie groß ist das Korpus?), von Grund auf trainieren (Pretraining) oder Finetuning, und welche Implementierung?

Wozu? Durch Pretraining oder Finetuning von word2vec-Modellen mit PyTorch bekommt man Wortvektoren, die auf die eigene Domäne (Fachsprache, andere Sprache) passen, und kann sie als erste Schicht in ein größeres Modell einbauen.

Von Wörtern zu Dokumenten: NLP

Beispiel-Task: ähnliche Dokumente finden

Gegeben ist eine Menge von NN (kurzen) Dokumenten {D1,…,DN}\{D_1, \dots, D_N\} (z.B. Tweets, Webseiten, Hausarbeiten). Gesucht sind kk Paare ähnlicher Dokumente (k≪Nk \ll N), z.B. um Tweets thematisch zu gruppieren oder Plagiate zu finden: {(x1,y1),…,(xk,yk)}\{(x_1, y_1), \dots, (x_k, y_k)\}, Paare von Indizes, sodass DxiD_{x_i} und DyiD_{y_i} ähnlich sind.

Klassischer Ansatz: Wörter in DiD_i zählen, Häufigkeitsverteilungen von DiD_i und DjD_j vergleichen (bag of words). Probleme mit diesem Ansatz:

  1. „Katze isst Maus“ und „Maus isst Katze“ sind ununterscheidbar.

  2. „Schwimmen“ und „schwamm“ haben nichts miteinander zu tun.

  3. „Hund“ und „Tier“ haben nichts miteinander zu tun.

  4. Wörter wie „der“, „die“, „das“ sind sehr häufig, aber bedeutungslos.

Klassische Lösungsansätze: (1) nn-Gramme statt Wörter betrachten, (2) Lemmatisierung, (3) komplexe Ontologien (formalisiertes Wissen), (4) Stopwords entfernen.

Wörter? Token!

Alternative Lösung zu Problem 2 (statt Lemmatisierung): Buchstaben bzw. Zeichen anstelle von Wörtern als „Atome“ (= Token) nehmen, und nn-Gramme davon (z.B. Trigramme, n=3n = 3). Beispiel: „schwimm!“ und „schwimmen“ ergeben

[sch,chw,hwi,wim,imm,mm!]und[sch,chw,hwi,wim,imm,mme,men],[\text{sch}, \text{chw}, \text{hwi}, \text{wim}, \text{imm}, \text{mm!}] \quad\text{und}\quad [\text{sch}, \text{chw}, \text{hwi}, \text{wim}, \text{imm}, \text{mme}, \text{men}],

die haben sehr ähnliche Trigrammhäufigkeitsverteilungen. Konkret zu klärende Fragen: Leerzeichen wie jedes andere Zeichen behandeln? Über das Satzende „.“ hinaus? Flexibles nn, z.B. Silben statt Buchstabentrigramme? Die Antworten darauf bilden die Tokenisierungsstrategie, den Tokenizer. Der Einfachheit halber bleiben wir zunächst bei Token = Wörter, d.h. wir löschen Satzzeichen und trennen an Leerzeichen; Byte Pair Encoding, der Tokenizer moderner LLMs, kommt im Kapitel „Transformer“.

Modernerer Ansatz (supervised): mit einem neuronalen Netz; Menschen labeln Ähnlichkeit. Eingabe: Paare (Di,Dj)(D_i, D_j), Ausgabe: Ähnlichkeitsschätzung. Unsupervised mit neuronalen Netzen:

  1. Alle Dokumente DiD_i einlesen als Liste von Wörtern.

  2. Jedes einzelne Wort mit einem zuvor trainierten neuronalen Netz (word2vec) umrechnen in eine andere Repräsentation, die sich besser vergleichen lässt.

  3. Für jedes Paar (Di,Dj)(D_i, D_j) die Listen von Repräsentationen vergleichen (z.B. Kosinus-Ähnlichkeit der Mittelwerte), daraus ein Ähnlichkeitsmaß für das Paar berechnen.

  4. Die Top-kk ähnlichsten Paare ausgeben.

Problem 3 („Hund“ und „Tier“) löst word2vec, weil beide in ähnlichen Kontexten vorkommen und daher nahe beieinander liegen. Problem 1 (Wortreihenfolge) löst es nicht – dafür braucht man Modelle, die Sequenzen verarbeiten (Kapitel „Recurrent Neural Networks“ und „Transformer“).

Literatur und Softwarepakete

Übung

Der Satz „der hund bellt laut im garten“ (6 Token), Fenstergröße S=2S = 2.

  1. Wie viele (Kontext, Zielwort)-Paare erzeugt Skip-gram daraus? Schreiben Sie die Paare für das Zielwort „bellt“ auf. Tipp: Am Satzanfang und -ende ist das Fenster kleiner.

  2. Was ist bei CBOW Eingabe und was Ausgabe – und wie herum ist es bei Skip-gram?

  3. Der Embedding-Layer für ein Vokabular von 50 000 Wörtern und 300 Dimensionen: Wie viele Parameter, und was steht in Zeile ii?

Antwortprobe: Bei (1) liefern das erste und das letzte Token je zwei Paare, das dritte und das vierte je vier; bei (3) sind es 15 Millionen.