Viterbijev algoritam

Viterbijev algoritam predstavlja algoritam dinamičkog programiranja koji služi za pronalaženje najverovatnije sekvence skrivenih stanja, takozvanog Viterbijevog puta, koja proizilazi iz sekvence posmatranih događaja, posebno u kontekstu Markovljevih izvora informacija i Markovljevih skrivenih modela.

Algoritam je našao univerzalnu primenu u dekodiranju konvulcionih kodova, koji se koriste u CDMA i GSM digitalnim mobilnim telefonima, dajl-ap modemima, satelitima, komunikaciji u dubokom svemiru, i 802.11 bežičnom LAN-u. Takođe je opšte korišćen u prepoznavanju govora, sintezi govora, diarizaciji,[1] računarskoj lingvistici i bioinformatici. Na primer, kod prepoznavanja govora zvučni signal se tretira kao posmatrana sekvenca događaja, a niska teksta se smatra "skrivenim uzrokom" zvučnog signala. Viterbijev algoritam pronalazi najverovatniju nisku teksta za dati zvučni signal.

Istorija

uredi

Viterbijev algoritam je dobio ime po Endruu Viterbiju, koji ga je predložio 1967. kao dekodirajući algoritam konvulcionih kodova za ispravljanje šuma u digitalnoj komunikaciji.[2] Međutim, do nezavisnog otkrića algoritma došlo je čak sedam naučnika, među kojima i Nidlman i Vanš, kao i Vagner i Fišer.[3]

"Viterbijev (put, algoritam)" je postao standardni izraz za primenu algoritama dinamičkog programiranja radi maksimizacije problema koji uključuju verovatnoću.[3] Na primer, u statičkoj sintaksnoj analizi algoritam dinamičkog programiranja može da se iskoristi za otkrivanje jednog najverovatnijeg kontekstno slobodnog člana niske, koji se naziva „Viterbijev član“.[4][5][6]

Algoritam

uredi

Pretpostavimo da nam je dat skriveni Markovljev model sa sledećim vrednostima: stanje prostora  , inicijalna verovatnoća   da je u stanju   i tranziciona verovatnoća   prelaska iz stanja   u stanje  . Recimo da posmatramo izlaz  , najverovatnija sekvenca stanja   koja proizvodi opažanje je data rekurentnim relacijama:[7]

 

Ovde je   verovatnoća najverovatnije sekvence stanja   odgovorne za prvih   opservacija koje imaju   za svoje konačno stanje. Viterbijev put se može rekonstruisati čuvanjem pokazivača koji pamte koje stanje   je korišćeno u drugoj jednačini. Neka je   funkcija koja vraća vrednost   korišćenu da se izračuna   ako je  , ili   ako je  . Onda:

 

Ovde koristimo standardnu definiciju argumenta maksimuma (arg max).
Složenost ovog algoritma je  .

Primer

uredi

Posmatrajmo selo gde su svi seljani ili zdravi ili imaju groznicu i jedino seoski lekar može da utvrdi ko ima groznicu. Doktor dijagnostikuje groznicu tako što pita pacijente kako se osećaju. Seljani samo mogu da odgovore da se osećaju normalno, ošamućeno ili da im je hladno.

Doktor veruje da se zdravstveno stanje njegovih pacijenata ponaša kao diskretan Markovljev lanac. Postoje dva stanja, "zdrav" i "groznica", ali doktor ne može da ih posmatra direktno, ona su skrivena od njega. Svakog dana postoji izvesna mogućnost da će pacijent reći doktoru da se oseća "normalno", "ošamućeno" ili da mu je "hladno" u zavisnosti od svog zdravstvenog stanja.

Opservacije (normalno, ošamućeno, hladno) uz skriveno stanje (zdrav, groznica) formiraju skriveni Markovljev model i mogu se predstaviti u programerskom jeziku Pajton na sledeći način:

стања = ('Здрав', 'Грозница')
запажања = ('нормалано', 'хладно', 'ошамућено')
почетна_вероватноћа = {'Здрав': 0.6, 'Грозница': 0.4}
вероватноћа_преласка = {
   'Здрав' : {'Здрав': 0.7, 'Грозница': 0.3},
   'Грозница' : {'Здрав': 0.4, 'Грозница': 0.6}
   }
вероватноћа_емисије = {
   'Здрав' : {'нормално': 0.5, 'хладно': 0.4, 'ошамућено': 0.1},
   'Грозница' : {'нормално': 0.1, 'хладно': 0.3, 'ошамућено': 0.6}
   }

U ovom odlomku koda почетна_вероватноћа predstavlja lekarevo uverenje o tome u kome je stanju skrivenog Markovljevog modela bio pacijent kada ga je prvi put posetio (sve što zna je da je pacijent inače zdrav). Konkretna distribucija verovatnoće koja se ovde koristi nije ekvilibrijumska, koja je (za date verovatnoće prelaska) približno {'Здрав': 0.57, 'Грозница': 0.43}. вероватноћа_преласка predstavlja promenu zdravstvenog stanja u Markovljevom lancu. U ovom primeru postoji samo 30% šanse da će pacijent sutra imati groznicu ako je danas zdrav. вероватноћа_емисије predstavlja verovatnoću kako će se pacijent osećati svakog dana. Ako je zdrav, postoji 50% verovatnoće da će se osećati normalno, ako ima groznicu postoji 60% verovatnoće da se oseća ošamućeno.

 
Grafički prikaz datog skrivenog Markovljevog modela

Pacijent dolazi na pregled tri dana za redom i doktor otkriva da se on prvog dana osećao normalno, da mu je drugog dana hladno i da je trećeg dana ošamućen. Doktor ima pitanje: koja je najverovatnija sekvenca zdravstvenih stanja pacijenta koja bi objasnila ove opservacije? Odgovor na to pitanje daje Viterbijev algoritam.

def viterbi(obs, states, start_p, trans_p, emit_p):
    V = [{}]
    for st in states:
        V[0][st] = {"prob": start_p[st] * emit_p[st][obs[0]], "prev": None}
    # Позови Viterbi када је t > 0
    for t in range(1, len(obs)):
        V.append({})
        for st in states:
            max_tr_prob = max(V[t-1][prev_st]["prob"]*trans_p[prev_st][st] for prev_st in states)
            for prev_st in states:
                if V[t-1][prev_st]["prob"] * trans_p[prev_st][st] == max_tr_prob:
                    max_prob = max_tr_prob * emit_p[st][obs[t]]
                    V[t][st] = {"prob": max_prob, "prev": prev_st}
                    break
    for line in dptable(V):
        print line
    opt = []
    # Највећа вероватноћа
    max_prob = max(value["prob"] for value in V[-1].values())
    previous = None
    # Узми највероватније стање и његове прошле кораке
    for st, data in V[-1].items():
        if data["prob"] == max_prob:
            opt.append(st)
            previous = st
            break
    # Прати претходне кораке све до првог запажања
    for t in range(len(V) - 2, -1, -1):
        opt.insert(0, V[t + 1][previous]["prev"])
        previous = V[t][previous]["prev"]

    print 'Редослед стања је ' + ' '.join(opt) + ' са највећом вероватноћом од %s' % max_prob

def dptable(V):
    # Испиши талицу корака из речника 
    yield " ".join(("%12d" % i) for i in range(len(V)))
    for state in V[0]:
        yield "%.7s: " % state + " ".join("%.7s" % ("%f" % v[state]["prob"]) for v in V)

Funkcija viterbi ima sledeće argumente: obs je sekvenca zapažanja npr ['нормално', 'хладно', 'ошамућено']; states je skup skrivenih stanja; start_p je početna verovatnoća; trans_p su verovatnoće prelaska; i emit_p su verovatnoće emisije.

Radi jednostavnosti koda pretpostavimo da je sekvenca zapažanja obs neprazna i da su trans_p[i][j] i emit_p[i][j] definisani za sva stanja i,j.

U tekućem primeru Viterbijev algoritam se koristi na sledeći način:

витерби (запажања,
                   стања,
                   почетна_вероватноћа,
                   вероватноћа_преласка,
                   вероватноћа_емисије)

Izlaz je:

$ python витерби_пример.py
         0          1          2
Здрав: 0.30000 0.08400 0.00588
Грозница: 0.04000 0.02700 0.01512
Редослед стања је Здрав Здрав Грозница са највећом вероватноћом од 0.01512

Ovo otkriva da su zapažanja ['нормално', 'хладно', 'ошамућено'] najverovatnije generisana od stanja ['Здрав', 'Здрав', 'Грозница']. Drugim rečima, s obzirom na uočene aktivnosti najverovatnije je da je pacijent bio zdrav i prvog dana kada se osećao normalno kao i drugog dana kada se osećao hladno, a onda je trećeg dana dobio groznicu.

Rad Viterbijevog algoritma se može videti pomoću trelis dijagrama. Viterbijev algoritam je u suštini najkraći put kroz trelis dijagram. Klinički primer za trelis dijagram je pokazan na slici ispod gde je naznačen odgovarajući Viterbijev put.

 
Animacija trellis dijagrama za Viterbijev algoritam. Posle tri dana najverovatniji mogući put je ['Здрав', 'Здрав', 'Грозница']

Prilikom primene Viterbijevog algoritma treba napomenuti da mnogi jezici koriste aritmetiku u pokretnom zarezu -kao npr. p je malo, što može dovesti do potkoračenja u rezultatima. Uobičajena tehnika da se ovo izbegne je korišćenje algoritma verovatnoće tokom obračuna, istom tehnikom koja se koristi u logaritamskom brojčanom sistemu. Kada se algoritam zaustavi, precizna vrednost se može dobiti izvođenjem odgovarajućeg stepenovanja.

Ekstenzije

uredi

Generalizacija Viterbijevog algoritma, nazvana algoritmom max-sum (algoritam maksimalnog proizvoda) može se koristiti da se pronađu najverovatniji podaci svih ili nekih podskupova latentnih varijabli u velikom broju grafičkih modela, npr Bajesove mreže, Markovljeva slučajna polja i uslovna slučajna polja. Latentne varijable treba da budu povezane na način donekle sličan sa skrivenim Markovljevim modelom, sa ograničenim brojem veza između varijabli i neke vrste linearnih struktura između varijabli. Opšti algoritam obuhvata prosleđivanje poruka i suštinski je sličan algoritmu širenja poverenja (belief propagation algorithm), koji je generalizacija napred-nazad algoritma.

Algoritam koji se zove iterativno Viterbijevo dekodiranje može naći podniz opažanja koji najbolje odgovara (u proseku) datom skrivenom Markovljevom modelu. Koristi se za rad sa turbo kodom. Iterativno Viterbijevo dekodiranje radi pomoću iterativnog pozivanja modifikovanog Viterbijevog algoritma, ponovo procenjujući rezultat datoteke do konvergencije.

Alternativni algoritam lenji Viterbijev algoritam, predložen je nedavno. Za mnoge kodekse praktičnog interesa, pod razumnim poteškoćama, lenji dekoder (koristeću lenji Viterbijev algoritam) je mnogo brži od originalnog Viterbijevog dekodera (koji koristi Viterbijev algoritam). Ovaj algoritam radi tako što ne širi nikakve čvorove dok zaista ne bude potrebno i obično uspeva da izbegne puno posla (u softveru) od običnog Viterbijevog algoritma za isti rezultat -međutim nije moguće to reći i za hardver.

Pseudokod

uredi

S obzirom na prostor za zapažanje  , prostor za moguća stanja  , sekvenca zapažanja  , tranziciona matrica   veličine   tako da   čuva tranzicionu verovatnoću stanja   u stanje  , emisiona matrica   velicine   tako da   čuva verovatnoću zapažanja   stanja  , niz inicijalnih verovatnoća   veličine   tako da   čuva verovatnoću  . Mi kažemo da je put   sekvenca slučaja koji generišu zapažanja  .

U ovom dinamičkom programiranju problem smo konstruisali u dve dvodimenzionalne tabele   veličine  . Svaki element od  ,  , čuva verovatnoću najverovatnijeg puta do sada   sa   koji generiše  . Svaki element iz  ,  čuva  , najverovatniji put do sada  , za  .

Punimo unose dve tabele   po rastućem redosledu  .

 , i
 

Treba napomenuti da   ne treba da se pojavi u drugim izrazima, jer je konstanta sa   i  , i ne utiče na argmax.

ULAZ
  • prostor zapažanja  ,
  • prostor mogućih stanja  ,
  • sekvenca zapažanja   tako da   za trenutno zapažanje   je  ,
  • tranziciona matrica   veličine   tako da   čuva tranuicionu verovatnoću stanja   u stanje  ,
  • emisiona matrica   veličine   tako da   čuva verovatnoću zapažanja   stanja  ,
  • niz inicijalnih verovatnoća   veličine   tako da   čuva verovatnoću  
IZLAZ
  • najverovatnija sekvenca slučaja je  
  function VITERBI( O, S, π, Y, A, B ) : X
     for each state si do
         T1[i,1] ← πi·Biy1
         T2[i,1] ← 0
     end for
     for i2,3,...,T do
         for each state sj do
              
              
         end for
     end for
      
     xT ← szT
     for iT,T-1,...,2 do
         zi-1T2[zi,i]
         xi-1szi-1
     end for
     return X
 end function

Vidi još

uredi

Reference

uredi
  1. ^ Xavier Anguera et Al, "Speaker Diarization: A Review of Recent Research" Arhivirano na sajtu Wayback Machine (12. maj 2016), retrieved 19. August 2010, IEEE TASLP
  2. ^ Forney, David (2005). „29 Apr 2005, G. David Forney Jr: The Viterbi Algorithm: A Personal History”. arXiv:cs/0504020v2 . 
  3. ^ a b Jurafsky, Daniel; Martin, James H. (2014). Speech and Language Processing. Pearson Education International. str. 246. 
  4. ^ Schmid, Helmut (2004). Efficient parsing of highly ambiguous context-free grammars with bit vectors (PDF). Proc. 20th Int'l Conf. on Computational Linguistics (COLING). doi:10.3115/1220355.1220379. 
  5. ^ Klein, Dan; Manning, Christopher D. (2003). A* parsing: fast exact Viterbi parse selection (PDF). Proc. 2003 Conf. of the North American Chapter of the Association for Computational Linguistics on Human Language Technology (NAACL). str. 40—47. doi:10.3115/1073445.1073461. Arhivirano iz originala (PDF) 05. 03. 2016. g. Pristupljeno 19. 05. 2016. 
  6. ^ Stanke, M.; Keller, O.; Gunduz, I.; Hayes, A.; Waack, S.; Morgenstern, B. (2006). „AUGUSTUS: Ab initio prediction of alternative transcripts”. Nucleic Acids Research. 34 (Web Server issue): W435—W439. PMC 1538822 . PMID 16845043. doi:10.1093/nar/gkl200. 
  7. ^ Xing E, slide 11

Literatura

uredi

Literatura

uredi

Implementacije

uredi

Spoljašnje veze

uredi