markdown
Bayesova-klasifikace.md
markdown
# Bayesova klasifikace Test na vzácnou nemoc má devadesátidevítiprocentní spolehlivost a tobě vyšel pozitivní. Kolik je pravděpodobnost, že jsi nemocný? Většina lidí řekne 99 %. Když nemoc postihuje jednoho z deseti tisíc, je správná odpověď **necelé jedno procento**. Rozdíl mezi těmi dvěma čísly je celý obsah téhle stránky a jmenuje se **apriorní pravděpodobnost**. Bayesův klasifikátor je jediný klasifikátor v téhle wiki, který má **dokazatelně minimální chybu**, pokud znáš správná rozdělení. Zbytek téhle stránky je o tom, proč je nikdy neznáš a co se s tím dá dělat. Předpokládá to [klasifikaci a rozpoznávání](Klasifikace-a-rozpoznavani), zejména diskriminační funkce a zápis `arg max`. Základní pravděpodobnost stačí na úrovni „co je podmíněná pravděpodobnost", nic víc. ## K čemu to je Cílem je **klasifikace v situacích, kdy se třídy překrývají**. To je normální stav věcí - dva různé objekty můžou mít stejné příznaky a žádná hranice je od sebe neoddělí bezchybně. [Minimální vzdálenost](Priznakove-metody#klasifikátor-na-principu-minimální-vzdálenosti) ani [perceptron](Neuron-a-perceptron) s tím neumí nic udělat. Nakreslí hranici a hotovo. Bayesův přístup místo hranice počítá **pravděpodobnost každé třídy** a vybere nejpravděpodobnější - a tím zároveň řekne, jak si je jistý. ## Dvě věci, které musíš znát **Apriorní pravděpodobnost `P(ωr)`** je předpoklad o výskytu třídy **před pozorováním dat**. Kolik procent klientů banky dostane úvěr. Kolik procent e-mailů je spam. Kolik procent lidí má tu nemoc. **Podmíněná hustota `p(x|ωr)`** je rozložení dat uvnitř třídy, anglicky *likelihood*. Jak vypadají příznaky u lidí, kteří tu nemoc mají. **Rozdíl mezi `p(x|ω)` a `P(ω|x)` je to jediné, co musíš na téhle stránce pochopit.** První říká „jak vypadají data, když je to spam". Druhá říká „jaká je šance, že je to spam, když data vypadají takhle". Prohození těch dvou je klasický omyl a je to přesně ta chyba, kterou lidi udělají u testu na vzácnou nemoc. ## Bayesův vzorec ```P(ωr|x) = p(x|ωr) · P(ωr) / p(x)``` Slovy: **aposteriorní pravděpodobnost je likelihood krát apriorní, děleno normalizací.** Jmenovatel je normalizační konstanta, které se říká *evidence*: ```p(x) = Σ p(x|ωi) · P(ωi) přes všechna i = 1..R``` Rozhodovací pravidlo se pak jmenuje **MAP** (maximum a posteriori): ```ω* = arg max [ p(x|ωr) · P(ωr) ] r=1..R``` **Všimni si, že `p(x)` ve vzorci pro `ω*` chybí, a je to správně.** Je stejné pro všechny třídy, takže na `arg max` nemá vliv. Počítat ho musíš jen tehdy, když chceš skutečnou pravděpodobnost a ne jen rozhodnutí - třeba když chceš říct „spam s pravděpodobností 0,97". ## Spočítej si to: rozhodování o úvěru Modelový příklad. Apriorní pravděpodobnosti: ```P(PUJ) = 0,667 úvěr poskytnoutP(NEP) = 0,333 úvěr neposkytnout``` Podmíněné hustoty pro příznak „vysoký zůstatek": ```p(x_vys | PUJ) = 0,91p(x_vys | NEP) = 0,12``` Výpočet: ```P(PUJ) · p(x_vys|PUJ) = 0,667 · 0,91 ≈ 0,607P(NEP) · p(x_vys|NEP) = 0,333 · 0,12 ≈ 0,040``` `0,607 > 0,040`, tedy `ω* = PUJ` - **úvěr poskytnout**. Zkus si na tom, co apriorní pravděpodobnost dělá. Kdyby byly obě třídy stejně časté (`0,5` a `0,5`), poměr by byl `0,455` proti `0,060` - tedy pořád ve prospěch úvěru, ale těsněji. **Apriorní pravděpodobnost rozhoduje hlavně tam, kde jsou likelihoody blízko sebe**, a přesně to je případ vzácné nemoci z úvodu. ## Naivní Bayes Až sem to bylo hezké, ale je tu problém. **Pro odhad `p(x|ω)` u vektoru s `n` příznaky bys potřeboval sdružené rozdělení všech `n` proměnných.** U dvaceti binárních příznaků to je milion hodnot na každou třídu a ty je z dat nikdy neodhadneš. Naivní Bayesův klasifikátor to řeší předpokladem, který je zjevně nepravdivý: **příznaky `xj` jsou podmíněně nezávislé při znalosti třídy `ωs`.** ```p(x|ωs) = Π p(xj|ωs) přes j = 1..n``` Rozhodovací pravidlo: ```ω* = arg max [ P(ωs) · Π p(xj|ωs) ] s``` Z milionu hodnot se rázem stane dvacet. **To je celý přínos naivního předpokladu a je to důvod, proč se používá.** **A teď to zajímavé: i přes porušení předpokladu nezávislosti dosahuje NBC překvapivě vysoké přesnosti.** Slova ve větě zjevně nezávislá nejsou - po „úrokové" následuje „sazby" mnohem častěji než náhoda. Klasifikátor přesto funguje. Důvod je v tom, že **NBC nepotřebuje správné pravděpodobnosti, potřebuje správné pořadí.** Odhady jsou špatné, často o řády, ale chyba táhne oběma třídám stejným směrem a `arg max` vyjde správně. Využití: **klasifikace textu (spam filtry)** a **diagnostika**. ### Spočítej si to: úvěr podruhé Trénovací data o dvanácti klientech. Uchazeč má **středně vysoký zůstatek** a je **nezaměstnaný**. ```P(ANO) · P(STRED|ANO) · P(NE|ANO) = 0,667 · 0,25 · 0,625 = 0,1042P(NE) · P(STRED|NE) · P(NE|NE) = 0,333 · 0,5 · 0,25 = 0,0416``` `0,1042 > 0,0416`, tedy **uchazeč bude zařazen do třídy ÚVĚR (ANO)**. Podívej se na to podrobněji, protože je to poučné. Jednotlivé podmíněné pravděpodobnosti mluví **proti** úvěru: `P(STRED|ANO) = 0,25` je menší než `P(STRED|NE) = 0,5`. Přesto vyhraje ANO, protože **apriorní pravděpodobnost `0,667` a vyšší `P(NE|ANO)` to přetlačí**. Takhle přesně se ta metoda chová - jednotlivé indicie se násobí a rozhoduje součin, ne jednotlivosti. ## Kde Bayesova klasifikace přestává platit **Nulová pravděpodobnost zabije celý součin.** Když se v trénovacích datech nějaká hodnota příznaku pro danou třídu nevyskytla, je `p(xj|ωs) = 0` a celý součin je nula - bez ohledu na to, jak dobře sedí ostatních devatenáct příznaků. U spamového filtru stačí jedno neznámé slovo. Řeší se to **vyhlazováním** (Laplaceovo, aditivní): ke každému čítači se přičte malá konstanta, typicky jedna. **Tohle je věc, kterou musíš mít, ne kterou si můžeš vybrat.** **Podtečení při násobení.** Násobíš dvacet čísel menších než jedna a v `float` z toho vyjde nula. V praxi se proto počítá **součet logaritmů** místo součinu: ```log P(ωs) + Σ log p(xj|ωs)``` `arg max` se tím nezmění, protože logaritmus je rostoucí. **Silně závislé příznaky metodu položí.** Ne že by přestala fungovat, ale začne být přehnaně sebejistá. Když do modelu dáš tentýž příznak dvakrát, jeho vliv se umocní na druhou. Odtud plyne, proč se před NBC vyplatí [vybrat příznaky](Priznakove-metody#výběr-příznaků) a odstranit duplicity. **Apriorní pravděpodobnosti z trénovacích dat nemusí platit v provozu.** Když natrénuješ spamový filtr na datech, kde je 50 % spamu, a nasadíš ho tam, kde je 5 %, bude nadhodnocovat spam. Apriorní pravděpodobnosti se dají nastavit ručně a **u nevyvážených úloh se to dělat má**. **Bayes je optimální jen se správnými rozděleními.** Věta o minimální chybě platí, když `p(x|ω)` a `P(ω)` znáš přesně. V praxi je odhaduješ z konečného vzorku, takže optimalita je teoretická meta, ne záruka. ## Co se na tom nejčastěji rozbije | Příznak | Kde je problém ||---|---|| Klasifikátor vrací pořád stejnou třídu | dominuje apriorní pravděpodobnost, data jsou příliš nevyvážená || Jeden neznámý příznak vyhodí klasifikaci | chybí Laplaceovo vyhlazování || Všechny pravděpodobnosti vyjdou 0,0 | podtečení - přejdi na součet logaritmů || Vysoká přesnost, nesmyslné pravděpodobnosti | důsledek porušené nezávislosti; rozhodnutí sedí, jistoty ne || Model funguje na testu, ne v provozu | jiné apriorní rozdělení v provozu než v trénovacích datech || Zaměněné `p(x|ω)` a `P(ω|x)` | klasická chyba - zkontroluj, co je v čitateli | ## Co si odnést **`P(ω|x) = p(x|ω)·P(ω) / p(x)`.** Aposteriorní = likelihood krát apriorní, děleno evidencí. **`p(x)` se u `arg max` počítat nemusí.** Je stejné pro všechny třídy. **Apriorní pravděpodobnost rozhoduje u vzácných tříd.** Test s 99% spolehlivostí na nemoc jednoho z deseti tisíc dá pozitivní výsledek správně v necelém procentu případů. **Naivní předpoklad je nepravdivý a přesto funguje.** Klasifikátor potřebuje správné pořadí, ne správná čísla. **Vyhlazování je povinné.** Jedna nulová pravděpodobnost zabije celý součin. **Počítej v logaritmech.** Jinak podtečeš. ## Kam dál - **[Příznakové metody](Priznakove-metody)** - odkud se berou ta `xj`, do kterých se dosazuje- **[Metriky a vyhodnocení](Metriky-a-vyhodnoceni)** - jak porovnat NBC s ostatními klasifikátory- **[Klasifikace a rozpoznávání](Klasifikace-a-rozpoznavani)** - kam Bayes zapadá mezi ostatní přístupy- **[Nástroje pro UI](Nastroje-pro-UI)** - `GaussianNB` a `MultinomialNB` ve scikit-learn