markdown
Metriky-a-vyhodnoceni.md
markdown
# Metriky a vyhodnocení modelů Mám klasifikátor rakoviny s přesností 99 %. Zní to výborně. Nemocný je jeden pacient ze sta, takže model, který napíše „zdravý" úplně všem, má přesnost 99 % taky - a nenajde ani jednoho nemocného. **Přesnost (accuracy) je nejpoužívanější a nejzavádějící metrika ve strojovém učení.** U nevyvážených dat neříká vůbec nic a přesto se uvádí jako první číslo v každé práci. Tahle stránka je o tom, čím ji nahradit, jak se čte matice záměn a proč se model nesmí testovat na datech, na kterých se učil. Předpokládá to [klasifikaci a rozpoznávání](Klasifikace-a-rozpoznavani). Nepotřebuješ k tomu žádnou statistiku nad rámec zlomků. ## Základní typy dat Než se začne měřit, musí se data uvést do stavu, ve kterém se měřit dají. **Intervalové proměnné** - poloha, váha, výška. Normalizují se do `[0, 1]`: ```x' = (x − xmin) / (xmax − xmin)``` **Tohle není kosmetika.** Když má váha rozsah 50-120 a výška 1,5-2,0, každá euklidovská vzdálenost bude určena výhradně vahou a výška se v ní ztratí. Bez normalizace ti [k-NN](Priznakove-metody#k-nejbližších-sousedů-k-nn) i [shlukování](Shlukovani) měří něco jiného, než sis myslel. **Binární proměnné** - dva stavy, `1` (přítomnost) a `0` (nepřítomnost). Normalizovat se nemusí. ## Metriky vzdálenosti **Eukleidovská vzdálenost.** Přímá čára, to, co si pod vzdáleností představíš: ```d(X, Y) = √( Σ (xi − yi)² )``` **Manhattanská vzdálenost.** Součet absolutních rozdílů, tedy cesta po ulicích pravoúhlého města: ```d(X, Y) = Σ |xi − yi|``` Je **odolnější vůči odlehlým hodnotám**, protože nemocní rozdíly na druhou. Jeden příznak, který se liší o deset, přispěje deseti, ne stem. **Kosinová podobnost.** Úhel mezi vektory: ```sim(X, Y) = (X · Y) / (‖X‖ · ‖Y‖)``` Všimni si, že to není vzdálenost, ale **podobnost** - vyšší je lepší, hodnota 1 znamená stejný směr. A hlavně: **ignoruje délku vektorů**. Proto se používá na texty. Dokument o třiceti slovech a dokument o třech tisících se stejným tématem mají skoro stejný směr, ale obrovskou euklidovskou vzdálenost. **Volba metriky je součást návrhu, ne detail.** Fyzikální veličiny → euklidovská. Data se šumem a odlehlými body → manhattanská. Texty a četnosti → kosinová. ## Přesnost klasifikace Chybovost a přesnost, nejzákladnější dvojice: ```ER = E / ALL chybovost (error rate)ACC = OK / ALL = 1 − ER přesnost (accuracy)``` U úloh typu **rozpoznávání 1-n** (spojitá řeč, sekvence znaků) to nestačí, protože model může slovo nejen zaměnit, ale i vynechat nebo přidat: ```ACC = (N − D − S − I) / N``` kde `N` je počet jednotek, `D` vynechané (deletions), `S` zaměněné (substitutions) a `I` vložené (insertions). **Ta `I` je důvod, proč tahle metrika může vyjít záporná.** Když model vygeneruje víc jednotek, než jich ve skutečnosti bylo, `I` může být větší než `N`. To není chyba vzorce, to je poctivé měření. ## Matice záměn Tabulka skutečných proti predikovaným třídám. Pro dvě třídy: | | Predikce + | Predikce − ||---|---|---|| **Skutečnost +** | TP | FN || **Skutečnost −** | FP | TN | - **TP** (true positive) - správně označený pozitiv,- **FN** (false negative) - **prošvihnutý** pozitiv,- **FP** (false positive) - falešný poplach,- **TN** (true negative) - správně označený negativ. **Nejdůležitější věc na téhle stránce: FN a FP nejsou stejně drahé.** U testu na rakovinu je FN prošvihnutá diagnóza a FP zbytečné vyšetření navíc. U spamového filtru je FP ztracený důležitý e-mail a FN otravná reklama v inboxu. **Která z těch dvou chyb tě víc bolí, rozhoduje o tom, kterou metriku máš sledovat.** Pozor na orientaci tabulky. Používají se obě konvence a liší se, jestli je řádek skutečnost, nebo odhad: | Odhad / Reál | 1 | 0 ||---|---|---|| **1** | TP | FP || **0** | FN | TN | **Před interpretací si vždycky zkontroluj, co je řádek.** Ve scikit-learn (`ConfusionMatrixDisplay`) je **řádek skutečná třída** a sloupec predikce. Pro víc tříd je matice `R × R`. Příklad ze tří tříd: | | a | b | c ||---|---|---|---|| **a** | 88 | 4 | 12 || **b** | 8 | 65 | 4 || **c** | 11 | 15 | 33 | Na diagonále jsou správné klasifikace, mimo ni záměny. **Z téhle matice se toho dá vyčíst mnohem víc než z jednoho čísla přesnosti.** Třída `c` má jen 33 správných ze 59 a nejčastěji se plete s `b`. Přesnost by ti řekla „78 %" a to, že jedna třída skoro nefunguje, bys nezjistil. Přesně to je důvod, proč se u [datasetu Digits](Nastroje-pro-UI#příklad-klasifikace-datové-sady-digits) kreslí matice záměn - je z ní vidět, že si model plete osmičku s trojkou, což z přesnosti 96 % nepoznáš. ## Precision, Recall, F-míra ```Precision = TP / (TP + FP)Recall = TP / (TP + FN)F1 = 2 · Precision · Recall / (Precision + Recall)``` Slovy, a tohle si zapamatuj v téhle podobě: **Precision odpovídá na otázku: „Kolik z toho, co jsem označil, bylo správně?"** Jmenovatel je všechno, co model označil za pozitivní. **Recall odpovídá na otázku: „Kolik z toho, co existovalo, jsem našel?"** Jmenovatel je všechno, co skutečně pozitivní bylo. **Jdou proti sobě a to je celý smysl toho, že jsou dvě.** Model, který označí za pozitivní úplně všechno, má recall 1,0 a mizernou precision. Model, který označí jediný nejjistější případ, má precision 1,0 a mizerný recall. **Jednu z nich vždycky zvedneš na úkor druhé posunutím prahu rozhodování.** `F1` je jejich harmonický průměr. Používá se harmonický, ne aritmetický, protože **tvrdě trestá nerovnováhu**. Precision 1,0 a recall 0,0 dá aritmetický průměr 0,5, ale `F1 = 0`. To je správně - takový model je k ničemu. Vrať se k příkladu z úvodu. Model „všichni zdraví" má accuracy 0,99, recall 0,0 a `F1 = 0`. **Jedna metrika říká výborně, druhá říká úplně nefunguje, a pravdu má ta druhá.** ## Křížová validace Data se rozdělí na `k` částí, typicky `k = 10`. Model se `k`-krát natrénuje, pokaždé s jinou částí jako testovací a zbytkem jako trénovací. Výsledná přesnost je průměrem. ```mermaidflowchart LR A["data rozdělená na 10 dílů"] --> B["běh 1: test = díl 1"] A --> C["běh 2: test = díl 2"] A --> D["..."] A --> E["běh 10: test = díl 10"] B --> F["průměr přesností"] C --> F D --> F E --> F``` **Odstraňuje závislost na konkrétním rozdělení dat.** Jeden náhodný split ti může dát 96 % nebo 91 % podle toho, jak padly těžké případy - a ty pak měříš náhodu, ne model. Druhá výhoda: každý vzorek je právě jednou v testovací množině, takže **využiješ všechna data na trénování i na testování**, jen ne naráz. U malých datasetů je to zásadní. **Kde křížová validace přestává platit:** u časových řad ji nepoužívej. Náhodné rozdělení znamená, že se model učí na budoucnosti a testuje na minulosti, a výsledek bude nesmyslně dobrý. Tam se dělí chronologicky. Druhý případ: když děláš výběr příznaků nebo ladění parametrů, musí se to dělat **uvnitř** každého běhu. Když vybereš příznaky na celých datech a pak křížově validuješ, testovací data už model ovlivnila a přesnost je nadhodnocená. ## Učební křivka Závislost chyby na velikosti trénovací množiny, případně na počtu epoch. Kreslí se dvě křivky - trénovací a validační chyba - a z jejich vzájemné polohy se čte diagnóza: | Co vidíš | Co to znamená | Co s tím ||---|---|---|| Obě chyby vysoké, blízko sebe | **podtrénování** (underfitting) | větší model, víc příznaků, delší trénink || Trénovací nízká, validační vysoká | **přetrénování** (overfitting) | víc dat, regularizace, dropout, jednodušší model || Obě nízké a blízko | model sedí | hotovo || Validační klesá a pak roste | přetrénování začalo v tom minimu | early stopping právě tam | **Tahle tabulka je nejužitečnější věc na celé stránce**, protože převádí obrázek na konkrétní akci. Bez ní se ladí naslepo. Podrobněji jsou příčiny a protiopatření u [MLP a backpropagation](MLP-a-backpropagation#problémy-při-trénování). ## Praktická pravidla **Nikdy netestuj na trénovacích datech.** Zní to samozřejmě a stane se to každému, typicky přes příznaky vybrané na celém datasetu. **U nevyvážených dat neuváděj accuracy.** Uváděj precision, recall a `F1`, nebo rovnou matici záměn. **Rozhodni předem, jestli tě víc bolí FP, nebo FN.** Podle toho se pak volí práh a metrika, ne obráceně. **Vždycky se podívej na matici záměn, ne jen na číslo.** Jedno číslo skryje, že jedna třída vůbec nefunguje. **Normalizuj příznaky před vším, co počítá vzdálenost.** k-NN, k-means, SVM, neuronové sítě. Rozhodovací stromy to nepotřebují. **Křížovou validaci použij, kdykoliv máš míň než pár tisíc vzorků.** Jeden split tam měří náhodu. ## Co si odnést **Accuracy u nevyvážených dat nic neříká.** 99 % může znamenat model, který nenajde ani jeden pozitiv. **Precision = kolik z označených sedělo. Recall = kolik z existujících jsem našel.** Jdou proti sobě. **F1 je harmonický průměr, aby tvrdě trestal nerovnováhu.** **Matice záměn řekne víc než jakákoliv jedna metrika.** Podívej se na ni vždycky. **FN a FP nejsou stejně drahé.** Která chyba bolí víc, je rozhodnutí zadání, ne modelu. **Křížová validace měří model, jeden split měří náhodu.** **Normalizace patří před každý výpočet vzdálenosti.** ## Kam dál - **[Příznakové metody](Priznakove-metody)** - co se vlastně vyhodnocuje- **[Bayesova klasifikace](Bayesova-klasifikace)** - klasifikátor, který vrací pravděpodobnosti a dá se u něj posouvat práh- **[MLP a backpropagation](MLP-a-backpropagation)** - přetrénování a jak se proti němu bojuje- **[Nástroje pro UI](Nastroje-pro-UI)** - `accuracy_score`, `ConfusionMatrixDisplay` a křížová validace ve scikit-learn