Jak už jsem říkal, Viterbiho algoritmus je optimalizovaný algoritmus dynamického programování, který slouží k nalezení sekvence transformací vnitřních stavů skrytého Markovova modelu, které generují příslušné pozorovatelné emise stavů vnějších s největší pravděpodobností.
Ač to může na první pohled vypadat složitě, myšlenka je podobně jednoduchá jako u zarovnávání řetězců – pravděpodobnosti pro jednotlivé vnější pozorovatelné emise počítáme po krocích a pro všechny možné způsoby jejich vzniku na základě toho kterého stavu vnitřního, přičemž si zapamatujeme jenom ty nejlepší. Přidáme-li totiž v dalším kroku opět to nejlepší řešení, automaticky tím protáhneme dosud nejlepší řešení o krok dále.
Uvedený algoritmus je zjevně konečný (někdy se dostaneme na konec pozorované sekvence stavů) a zpětnou cestou po zaznamenaných optimálních vnitřních stavech snadno zjistíme hledanou nejpravděpodobnější sekvenci stavů vnitřních.
Zkusme Viterbiho algoritmus aplikovat na náš příklad s brankáři, který jest zadán tímto grafem:
Protože pozorovaná sekvence nájezdů na branku je dosti dlouhá – celých 50 prvků..
01000000100000000000001000000010001010010001001001
..bude mnohem lepší počítat pstnosti sčítáním, tedy v podobě logaritmů (zde při základu 2), než násobením (při kterém bychom velmi brzo narazili na omezení přesnosti výpočtu v plovoucí řádové čárce):
Jak jsem předesílal, Viterbiho algoritmus počítá nejpravděpodobnější cestu postupně krok za krokem od prvního pozorovaného stavu dále. V našem příkladě s brankáři máme pro první emisi – branka byla chycena (tedy 0) – celkem dvě možnosti, jak k ní mohlo dojít:
Celkově pro obě možnosti dostáváme (teď už přímo v logaritmech dvou):
Nepřekvapivě „souboj“ našich brankářů pro první nájezd „vyhrává“ Míra, protože je prostě lepší. Otázka ovšem zní, jak to bude dál? Jelikož do dalších kroků musíme započítat i pstnosti výměny brankářů, třeba se nakonec ukáže, že je výhodnější, aby na začátku v brance stál Pepa. Ale to zjistíme až na konci.
Každý další krok po prvním je sice stále ještě jednoduchý, ale přeci jen trochu komplikovanější – danou emisi sice mohl vyprodukovat opět pouze jeden konkrétní vnitřní stav (tedy buď byl v bráně Míra, nebo Pepa), ale nyní již musíme započítat i možnost, že se brankáři v brance vyměnili!
Konkrétně ve druhém kroku (kdy brankář nájezd pustil za svá záda) tak mohou nastat následující situace:
Zajímat nás přitom samozřejmě bude pouze nejlepší možný výsledek, takže z obou dvojic možností realizace (tedy konkrétní obsazení branky) vybereme pro každý možný vnitřní stav pouze tu lepší (maximální pstnost). A protože nám jde o celkovou pstnost uvedené vnitřní cesty po transmisích, přičteme pochopitelně i pstnost odpovídajícího vybraného lepšího předchozího kroku.
Pro náš příklad tedy bude celková pstnost průběhu transmisí při daných emisích po druhém kroku vypadat takto:
Při druhém kroku je tedy vidět, že přítomnost Pepy v brance je pravděpodobnější (výsledná
Formálně tedy
Průhledněji se to dá zapsat do tabulky. První tři kroky i s naznačenými optimálními cestami (pomocí šipek) vypadají takto:
0 | 1 | 0 | 0 | … | 1 | ||||
---|---|---|---|---|---|---|---|---|---|
Pepa | -1,415 | → | -3,737 | → | -4,474 | → | -5,211 | … | |
Míra | -1,120 | → | -5,086 | → | -5,528 | → | -5,971 | … |
Dopočítáme-li tabulku až do konce, tedy po poslední (padesátou) emisi, získáme následující (koncové) pstnosti:
0 | … | 1 | 0 | 0 | 1 | ||||
---|---|---|---|---|---|---|---|---|---|
Pepa | -1,415 | … | -48,554 | → | -49,291 | → | -50,028 | → | -52,349 |
Míra | -1,120 | … | -52,345 | ↘ | -51,733 | → | -52,175 | → | -56,141 |
Z kompletní tabulky je tedy mimo jiné vidět, že:
-52,349
), a proti směru šipek od konce to pak znamená, že i všechny čtyři poslední nájezdy byl v brance Pepa (což je naznačenou zelenou barvou).Projdeme-li naznačeným způsobem celou tabulku od konce (začínaje vyšší pravděpodobností, tedy v našem případě, že u posledního nájezdu stál v brance Pepa), dostaneme (zde v pořadí zleva doprava od prvního nájezdu po poslední) pro zadanou sekvenci branek (1) a úspěšných zásahů (0) uvedenou sekvenci přítomností brankářů v brance:
01000000100000000000001000000010001010010001001001 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMPPPPPPPPPPPPPPPPPPPP
Ukažme si nyní obdobný příklad, avšak s bioinformatickým zaměřením (pochází z knihy Problems and Solutions in Biological Sequence Analysis autorů Marka Borodovského a Světlany Jekišejevy):
Mějme zadánu sekvenci bází GGCACTGAA
a následující HMM-model, který určuje pravděpodobnosti, že báze na konkrétním místě sekvence patří do úseku s vysokým obsahem GC (označeno H
) nebo naopak s nízkým obsahem GC (označeno L
):
PS: Vysoký obsah GC může například představovat kódující úsek sekvence, zatímco nízký zase nekódující.
Opět nás zajímá, jaká realizace vnitřních stavů (tedy transformací mezi částmi sekvence s nízkým a vysokým obsahem GC) při zadaném modelu (tedy s uvedenými koeficienty) nejpravděpodobněji vygenerovala sekvenci GGCACTGAA
(tedy posloupnost emisí).
Je jasné, že jednotlivé báze mohou principielně náležet do libovolné části obsahu GC (H nebo L), ale každé z možných rozložení (tedy cest po příslušných transformacích) bude mít jinou pravděpodobnost (kterou můžeme snadno spočítat ze zadané tabulky jako součin příslušných úkonů, které je třeba provést pro realizaci dané posloupnosti transformací).
LLHHHHLLL
je pravděpodobnost zjevně
kde Ze všech možných rozložení H versus L dynamické programování v podobě Viterbiho algoritmu vybere právě tu nejpravděpodobnější cestu.
Zadaná sekvence není příliš dlouhá, mohli bychom proto asi celkem v klidu zůstat u pravděpodobností a jejich násobení. Nicméně při převodu na sčítání pomocí logaritmů (zde opět při základu 2) se nám zadání modelu změní na:
Zapíšeme-li výpočet opět do tabulky (zde pro pohodlnost upravený výpis programu), obdržíme
H L A : -25.66 L |-24.49 L A : -22.86 H |-22.01 L G : -19.54 L |-19.54 L T : -17.33 H |-16.48 L C : -14.01 L |-14.01 L A : -11.53 H |-10.95 H C :-8.211 H | -8.796 H G :-5.474 H | -6.059 H G :-2.737 | -3.322
což znamená, že nejpravděpodobnější rozložení vnitřního stavu (vyznačené opět zeleně) jest HHHLLLLLL
.
Mimochodem pravděpodobnost této cesty jest $2^{-24,49}=0,000000042=4,2*10^{-8}$. Což vypadá (a koneckonců také je) jako úděsně malé číslo. Ale jen do té doby, než si přepočítáte pravděpodobnost druhé možnosti: $2^{-25,66}=0,000000019=1,9*10^{-8}$ . Řád sice stejný, ale i tak více než 2,2× menší číslo.
Viterbiho algoritmus slouží ke (relativně) snadnému nalezení nejpravděpodobnější cesty systému skrze pro nás neznámé přechody vnitřních stavů, které se projevují jistými konkrétními vnějšími pozorováními. Metodami dynamického programování dokáže tuto na první pohled skoro neřešitelnou úlohu vyřešit relativně snadno a s nepříliš velkými strojovými nároky.
Nicméně nezapomeňte, že se stále pohybujeme v oblasti pravděpodobností – že je něco méně pravděpodobné, neznamená, že se to zrovna jako na potvoru nemůže stát! Že nám vyšlo nějaké pořadí brankářů, neznamená, že si Míra, který jinak chytá málem jak bůh, nevybral černý den a zrovna mu to chytání vůbec nešlo, takže jeho aktuální chování vůbec neodpovídalo modelu, který jsme si vytvořili. Prostě náš model může krásně popisovat veškeré naše do té doby známé vědomosti o problému, ale to neznamená, že zabere stejně dobře i v dalším případě. Ale je to pravděpodobné ^_~