RuG/L04

Tutorial

Data waarmee het een ander wordt gedemonstreerd is nog niet aanwezig. Zodra dat wel het geval is zal de tekst op deze pagina worden bijgewerkt.

8. Het vergelijken van klankreeksen

Het Levenshtein-algoritme in de eenvoudigste vorm vergelijkt twee reeksen lettertekens waarbij het er alleen toe doet of twee lettertekens hetzelfde zijn of niet. Wanneer je afstanden wilt bepalen op basis van fonetische verschillen dan valt er wel wat te verbeteren. Je wilt dan klankreeksen met elkaar vergelijken. Er is weliswaar een relatie tussen een klankreeks en de reeks letters waarmee die klankreeks is opgetekend, waardoor je met een simpele Levenshtein-meting een goede indruk kunt krijgen van dialectverschillen (zie deel 2 van deze tutorial), maar het is niet de nauwkeurigste methode die denkbaar is.

Er spelen twee dingen:

Hieronder staan twee woorden, links opgetekend in fonetisch schrift, rechts de transcriptie in X-Sampa, een codering die bruikbaar is om fonetisch schrift met een gewoon toetsenbord in te voeren, zonder gebruik te maken van een tekenset die afwijkt van het simpele US-ASCII. (zie: IPA/X-SAMPA chart by Andrew Mutchler)

Beide woorden bestaan uit een reeks van vier klanken, maar zijn in elektronische vorm opgeslagen als reeksen van acht en zeven tekens, in dit voorbeeld met één tot drie lettertekens per klank. Niet alleen accenten worden gecodeerd door extra tekens toe te voegen, ook basisklanken zelf worden nogal eens met meer dan één teken gecodeerd, zoals de combinatie p\ voor de tweede klank in het onderste woord.

Wat er gebeurt als je deze twee reeksen in deze vorm met elkaar vergelijkt met het Levenshtein-algoritme zie je in onderstaand diagram. (zie ook: Levenshtein-demonstratie)

   a p \ E _ - l
  0 1 2 3 4 5 6 7
a 1 0 1 2 3 4 5 6
_ 2 1 2 3 4 3 4 5
- 3 2 3 4 5 4 3 4
p 4 3 2 3 4 5 4 5
f 5 4 3 4 5 6 5 6
@ 6 5 4 5 6 7 6 7
_ 7 6 5 6 7 6 7 8
t 8 7 6 7 8 7 8 9

a           _  -  p  f  @  _  t
a  p  \  E  _  -              l

8.1 Opdeling in tokens

De eerste stap om te komen tot een nauwkeuriger meting is het opdelen van de reeks lettertekens in tokens. Elke groep van letters die staat voor één fonetisch basisteken of voor één accent wordt samengevoegd. Hiervoor kun je het programma xstokens gebruiken. Hoe na de samenvoeging de Levenshtein-vergelijking verloopt kun je hieronder zien:

   a p\ E _- l
  0 1 2 3 4 5
a 1 0 1 2 3 4
_- 2 1 2 3 2 3
p 3 2 3 4 3 4
f 4 3 4 5 4 5
@ 5 4 5 6 5 6
_t 6 5 6 7 6 7

a         _-  p  f  @  _t
a  p\  E  _-           l

Helaas is het in dit geval nog geen verbetering. Je zult nog een stap verder moeten gaan.

Klanken hebben allerlei kenmerken. Je zou kunnen zeggen dat hoe meer kenmerken tussen twee klanken van elkaar verschillen, hoe groter het verschil is tussen die twee klanken. In plaats van klanken als eenheid met elkaar te vergelijken, zou je de klank kunnen opsplitsen in een reeks kenmerken, en dus reeksen van kenmerken met elkaar vergelijken.

Klinkers verschillen onder andere van elkaar door de plaats in de mond van het hoogste deel van de tong: voorin, in het midden, of achterin. Je kunt deze plaats coderen als een reeks van twee tokens:

tongcodering
voorTa1 Tb1
middenTa0 Tb1
achterTa0 Tb0

Een voor-klinker verschilt dan met één token van een midden-klinker, en met twee tokens van een achter-klinker.

Hetzelfde kun je doen voor positie van de kaak:

kaakcodering
geslotenKa1 Kb1 Kc1
half geslotenKa0 Kb1 Kc1
half openKa0 Kb0 Kc1
openKa0 Kb0 Kc0

En voor de stand van de lippen:

lippencodering
gerondL1
niet gerondL0

Dan wordt een enkele klank vervangen door een hele reeks tokens, bijvoorbeeld de "i":

i:  Ta1 Tb1  Ka1 Kb1 Kc1  L0
     |   |    |   |   |   |
     |   |    |   |   |   +---> niet gerond
     |   |    |   |   |
     |   |    +---+---+---> gesloten
     |   |
     +---+---> voor

Dit verschilt maar weinig (1 token) van de "y":

y:  Ta1 Tb1  Ka1 Kb1 Kc1  L1
     |   |    |   |   |   |
     |   |    |   |   |   +---> gerond
     |   |    |   |   |
     |   |    +---+---+---> gesloten
     |   |
     +---+---> voor

Maar het verschil met de "o" is een stuk groter (4 tokens):

o:  Ta0 Tb0  Ka0 Kb1 Kc1  L1
     |   |    |   |   |   |
     |   |    |   |   |   +---> gerond
     |   |    |   |   |
     |   |    +---+---+---> half gesloten
     |   |
     +---+---> achter

Al dit soort hercoderingen van fonetische transcripties kun je uitvoeren met het programma xstokens, waarna je gewoon het programma leven kunt gebruiken om de verschillen te meten.

Deze methode is redelijk eenvoudig, en is nauwkeuriger dan een simpele Levenshtein-meting direct op de oorspronkelijke tekenreeksen. Maar perfect is het niet:

8.2 Samenvoeging van tokens tot klanken

We gaan nog een stap verder. We splitsen een reeks letters in basisklanken en accenten, en voegen daarna elke basisklank met bijbehorende accenten samen in één token. Een simpele Levenshtein-meting op basis van zulke tokens verloopt zo:

  
  0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

Twee reeksen van elk vier klanken, een geen van de klanken uit het ene woord komt overeen met een klank uit het andere woord, dus de gemeten afstand is maximaal. Dat is niet wat we willen. We willen dat een substitutie van twee ongelijke klanken niet de maximale afstand geeft, maar een afstand die gebaseerd is op de verschillen van beide klanken. Zoals hieronder:

  
  0.00 1.27 2.82 4.36 5.58
1.22 0.70 2.25 3.79 5.01
2.55 2.03 3.57 5.11 4.79
4.17 3.65 3.03 4.57 5.80
5.86 5.35 4.73 4.44 5.67

 
 

Je ziet eerst de vergelijking van twee a-klanken, dan de verwijdering van een p, dan de vergelijking van twee soorten f-klanken, dan de vergelijking tussen twee e-achtige klanken, en tenslotte de invoegen van een l.

De procedure om tot zo'n meting te komen bevat de volgende stappen:

  1. Het maken van een nauwkeurige omschrijving van tokens en hun bijbehorende eigenschappen, en hoe de eigenschappen van accenten combineren met de eigenschappen van basisklanken.
  2. Het omzetten van de dialectbestanden waarbij elke reeks tekens (basisklank plus accenten samen) die een unieke klank beschrijven wordt vervangen door een uniek token.
  3. Het bepalen van afstanden tussen tokens op basis van hun verschillen in eigenschappen (fonetische features). Stap 2 en 3 worden door het programma features uitgevoerd op basis van de definitie die je in stap 1 hebt gemaakt.
  4. Het bepalen van Levenshtein-afstanden met het programma leven van de opnieuw gecodeerde dialectgegevens, gemaakt in stap 2, waarbij de afstanden tussen tokens die in stap 3 zijn berekend worden gebruikt.
Stap 1 is helaas niet eenvoudig. Of deze procedure lonend is hangt deels af van de conditie van de data. Je kunt streven naar een wetenschappelijk zo verantwoord mogelijke definitie van features en feature-vergelijkingen, maar wanneer de data niet zeer zorgvuldig is verzameld, als er teveel ruis in zit, dan heeft het geen zin om hier nog tot het uiterste te gaan.