Pređi na sadržaj

Viterbijev algoritam

S Vikipedije, slobodne enciklopedije

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 | uredi izvor]

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 | uredi izvor]

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 | uredi izvor]

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 | uredi izvor]

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 | uredi izvor]

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 | uredi izvor]

Reference[uredi | uredi izvor]

  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/0504020v2Slobodan pristup. 
  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 1538822Slobodan pristup. PMID 16845043. doi:10.1093/nar/gkl200. 
  7. ^ Xing E, slide 11

Literatura[uredi | uredi izvor]

Literatura[uredi | uredi izvor]

Implementacije[uredi | uredi izvor]

Spoljašnje veze[uredi | uredi izvor]