Del 3: Word2vec – et eksempel

Forventet tid ca. 90 min.

Formålet med denne del er dels at gennemføre beregningerne i Word2vec for et meget lille korpus af data, men også at forstå, hvad det vil sige at optimere vektorerne, så tabsfunktionen minimeres.

Et meget lille tekstkorpus

Vi vi anvende følgende meget simple tekstkorpus med 12 sætninger, som kun anvender 5 forskellige ord:

  • Hunden sover.
  • Katten sover.
  • Katten spinder.
  • Hunden gør.
  • Hunden sover.
  • Hunden gør.
  • Katten sover.
  • Hunden gør.
  • Katten sover.
  • Katten spinder.
  • Katten sover.
  • Katten spinder.

For at forsimple tingene vil vi for hver sætning her nøjes med at se på to vinduer:

Hunden sover

og

Hunden sover

I det første vindue er "Hunden" fokusord, mens "sover" er kontekstord. I det andet vindue er "Hunden" kontekstord, mens "sover" er fokusord. Vi ser altså bort fra punktummer, og vi forestiller os heller ikke, at teksten fortsætter på næste linje. Bemærk, at det er forsimplet i forhold det, hvordan det gøres i Word2vec.

Helt overordnet er idéen så, at vi skal bestemme værdier til fokus- og kontekstvektorer for alle fem ord, så værdien af tabfunktionen minimeres.



Aktivitet 1 - Fokus- og kontekstvektorer

NoteOpgave 1:
  • Hvor mange fokusvektorer er der brug for?
  • Hvor mange kontekstvektorer er der brug for?

Nu vælger vi indledningsvist tilfældige værdier til alle disse vektorer – vi venter med optimering. For at gøre det simplere, vil vi dog begrænse os til enhedsvektorer, hvor længden i Word2vec ellers generelt er variabel.

Vi vælger for fokusvektorerne: \[ \color{#F288B9} \begin{aligned} \vec{v}_{{hunden}} &= \begin{pmatrix} -0.8 \\ 0.6 \end{pmatrix}, \quad \vec{v}_{\text{katten}} = \begin{pmatrix} 0 \\ 1 \end{pmatrix},\\ \vec{v}_{\text{spinder}} &= \begin{pmatrix} 0.6 \\ 0.8 \end{pmatrix}, \quad \vec{v}_{\text{sover}} = \begin{pmatrix} 0.8 \\ 0.6 \end{pmatrix}, \\ \vec{v}_{\text{gør}} &= \begin{pmatrix} 1 \\ 0 \end{pmatrix} \\ \end{aligned} \] Og for kontekstvektorerne: \[ \color{#8086F2} \begin{aligned} \vec{k}_{\text{hunden}} &= \begin{pmatrix} 0.8 \\ -0.6 \end{pmatrix}, \quad \vec{k}_{\text{katten}} = \begin{pmatrix} 0.6 \\ -0.8 \end{pmatrix}, \\ \vec{k}_{\text{spinder}} &= \begin{pmatrix} -1 \\ 0 \end{pmatrix}, \quad \vec{k}_{\text{sover}} = \begin{pmatrix} -0.8 \\ -0.6 \end{pmatrix}, \\ \vec{k}_{\text{gør}} &= \begin{pmatrix} -0.6 \\ -0.8 \end{pmatrix} \\ \end{aligned} \] Til disse værdier af vektorerne skal vi nu have beregnet værdien af tabsfunktionen \(L\). Men lad os først visualisere vektorerne i en app, der både viser vektorerne og beregner værdien af tabsfunktionen:

Figur 1: App til opgave 2.
NoteOpgave 2: Leg med app’en
  • Kontroller, at vektorerne i figur 1 passer til de værdier, vi valgte ovenfor.
  • Skriv ned, hvad værdien af tabsfunktionen er i udgangspunktet.
  • Ændr vektorerne, og bemærk af værdien af tabsfunktionen \(L\) ændrer sig.
  • Overvej, hvordan du kan ændre vektorerne, så tabsfunktionen bliver mindst mulig. Vi vender tilbage til dette senere.

Som det næste skal sandsynlighederne for, at et eller andet ord er kontekstord til et andet, udregnes. For eksempel udregnes sandsynligheden for at "sover" er kontekst til "hunden" på denne måde:

\[ \begin{multline} P(\text{kontekst = sover} \mid \text{fokus = hunden}) = \\ \frac{\mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{sover}} }} {\mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{sover}} } +\mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{gør}} } + \mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{spinder}} }+\mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{katten}} }+\mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{hunden}} }} \\ \end{multline} \tag{1}\]



Aktivitet 2 - Sandsynligheder

NoteOpgave 3: Udregn sandsynligheder
  • Kig grundigt på de 12 linjer i vores tekstkorpus, og overvej, hvilke sandsynligheder, der er relevante at udregne, fordi de optræder i teksten. Det er betydeligt færre end alle 25 kombinationer af de 5 ord, fordi mange af kombinationer slet ikke optræder – for eksempel indeholder tekstkorpus ikke kombinationen "Hunden spinder".
  • Udregn de sandsynligheder, som er relevante.



Aktivitet 3 - Tabsfunktion

Endeligt skal værdien af tabsfunktionen beregnes. Her skal vi bruge den naturlige logaritme på de beregnede sandsynligheder. Da "Hunden sover" optræder to gange, kan værdien for \(\ln(P(\text{kontekst = sover} \mid \text{fokus = hunden}))\) og for \(\ln(P(\text{kontekst = hunden} \mid \text{fokus = sover}))\) ganges med 2, "Hunden gør" optræder 3 gange, så her gælder noget tilsvarende. Vi får:

\[ \begin{aligned} L=& -2 \cdot \ln(P(\text{kontekst = sover} \mid \text{fokus = hunden})) \\ &-2 \cdot \ln(P(\text{kontekst = hunden} \mid \text{fokus = sover})) \\ &-3 \cdot \ln(P(\text{kontekst = gør} \mid \text{fokus = hunden})) \\ &- \cdots \end{aligned} \tag{2}\]

NoteOpgave 4: Udregn værdien af tabsfunktionen
  • Beregn værdien af tabsfunktionen \(L\).
  • Kontroller, at det stemmer med værdien fra app’en i figur 1, inden du ændrede vektorerne.

Lad os vende tilbage til optimering ved minimering af værdien af tabsfunktionen.

Målet er, at hvis for eksempel "sover" er kontekst til fokusordet "hunden", så skal

\[ P(\text{kontekst = sover} \mid \text{fokus = hunden}) \] være stor. Ser vi på (1), så sker det, hvis tælleren

\[ \mathrm{e}^{\vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{sover}} } \]

er stor. Det opnår vi, hvis skalarproduktet

\[ \vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{sover}} \] er et stort positivt tal. I vores simple tilfælde, hvor vi kun arbejder med enhedsvektorer, har vi:

\[ \begin{aligned} \vec{v}_{\text{hunden}} \cdot \vec{k}_{\text{sover}} &= |\vec{v}_{\text{hunden}}| \cdot |\vec{k}_{\text{sover}}| \cdot \cos(v) \\ &= 1 \cdot 1 \cdot \cos(v) = \cos(v), \end{aligned} \]

hvor \(v\) er vinklen mellem de to vektorer. Nu er

\[ \cos(v)=1 \quad \text{hvis} \quad v=0^\circ \\ \] og

\[ \cos(v)=-1 \quad \text{hvis} \quad v=180^\circ \\ \]

Altså bliver skalarproduktet stort, hvis vinklen mellem de to vektorer er tæt på \(0^\circ.\) Det vil sige, at hvis "sover" er kontekst til fokusordet "hunden", så skal kontekstvektoren for "sover" pege i nogenlunde samme retning som fokusvektoren for "hunden". Det er selvfølgelig nemt nok isoleret set, men det skal gælde for alle kombinationer af kontekst- og fokusvektorer, som optræder i tekstkorpus!

Derimod vil det være sådan, at hvis vi ser på "Hunden" som fokusord, så skal "hunden", "katten" og "spinder" som kontekstord slet ikke anvendes, så deres kontekstvektorer skal være mest muligt modsatrettet fokusvektoren for "Hunden". Derimod skal både "sover" og "gør" som kontekstvektorer være tæt på fokusvektoren for "Hunden".

Foretag lignende overvejelser for hvert fokusord, og forsøg så at placere både fokus- og kontekstvektorerne i app’en i figur 1 ud fra disse overvejelser. For eksempel skal "sover" som kontekstvektor nok tættere på "Katten" end på "Hunden" som fokusvektorer, da "Katten sover" optræder oftere1 end "Hunden sover" i teksten.

1 Antallet af gange, en kombination optræder i tekstkorpus, har betydning for værdien af tabsfunktionen – se (2).

Med lidt held og yderligere justeringer i app’en, bør du kunne få værdien af tabsfunktionen så lav som mulig.

NoteOpgave 5: Optimering
  • Minimer værdien af tabsfunktionen ved at ændre vektorerne i app’en i figur 1.
  • Beregn selv værdien af tabsfunktionen for de ændrede vektorer.
  • Kontroller, at det stemmer med værdien i app’en.
  • Hvis I er flere, kan I jo se, hvem der kan få værdien mindst mulig!