Přeskočit na obsah
coden

Naivní Bayesův klasifikátor: spamový filtr, který funguje lépe, než by měl

Bayesova věta jako klasifikátor, učení počítáním slov, výpočet krok za krokem, problém nulové četnosti a Laplaceovo vyhlazení, přehnaná jistota a kalibrace, a proč naivní Bayes vyhrává, když je dat málo.

13 minut Matěj Žalmánek 2026-10-16

Série Základy AI Díl 51 z 83
  1. Mapa umělé inteligence: co je co a jak to do sebe zapadá
  2. Stručná historie umělé inteligence: od Turinga po jazykové modely
  3. Data, model, trénink, inference: základní pojmy na jednom příkladu
  4. Jak číst matematický zápis: symboly, indexy, sumy a kvantifikátory
  5. Množiny a relace: stavebnice, ze které se skládají definice v AI
  6. Funkce a zobrazení: proč je každý model v AI funkce
  7. Logika a důkazy: pravidla, podle kterých se v AI uvažuje
  8. Grafy a stromy: struktura, na které stojí hledání i neuronové sítě
  9. Lineární algebra pro strojové učení: vektory, matice a proč AI hlavně násobí
  10. Derivace, gradient a řetízkové pravidlo: jak model zjistí, kterým směrem se učit
  11. Gradientní sestup: jak se model učí
  12. Co je pravděpodobnost: od hodu kostkou ke Kolmogorovovým axiomům
  13. Podmíněná pravděpodobnost a Bayesova věta: jak změnit odhad, když se dozvíte něco nového
  14. Náhodná veličina a distribuční funkce: jedna funkce, která o rozdělení řekne všechno
  15. Funkce hustoty a pravděpodobnostní funkce: proč má spojitá veličina v bodě pravděpodobnost nula
  16. Střední hodnota, rozptyl a kovariance: kde rozdělení leží, jak je široké a co s čím souvisí
  17. Přehled pravděpodobnostních rozdělení: Bernoulli, binomické, Poisson, rovnoměrné, normální a exponenciální
  18. Zákon velkých čísel a centrální limitní věta: proč se průměry chovají tak předvídatelně
  19. Statistika a odhady parametrů: maximální věrohodnost, MAP a intervaly spolehlivosti
  20. Teorie informace: entropie, křížová entropie a KL divergence — odkud se berou ztrátové funkce
  21. Prohledávání stavového prostoru: BFS, DFS, UCS a A* s animacemi
  22. Hry a protivník: minimax, alfa-beta ořezávání a Monte Carlo tree search
  23. Splňování omezujících podmínek: backtracking, propagace omezení a AC-3 na sudoku a mapě krajů
  24. Logika a znalostní systémy: dopředné a zpětné řetězení, rezoluce a expertní systémy
  25. Plánování: STRIPS, svět kostek, heuristiky z relaxace a plánování v AI agentech
  26. Lokální hledání a simulované žíhání: obchodní cestující přes krajská města
  27. Genetické algoritmy: populace, křížení, mutace a výběr na batohu na výlet
  28. Evoluční strategie a genetické programování: od pravidla jedné pětiny po Keplerův zákon
  29. Optimalizace mravenčí kolonií: jak feromonová stopa najde krátkou cestu
  30. Optimalizace hejnem částic: setrvačnost, vlastní zkušenost a zkušenost hejna
  31. Neuroevoluce: evoluce vah i tvaru neuronových sítí a algoritmus NEAT
  32. Fuzzy množiny a funkce příslušnosti: jak zapsat „trochu teplo“
  33. Fuzzy logika a pravděpodobnost: proč „trochu teplo“ neznamená „pravděpodobně teplo“
  34. Fuzzy logika: t-normy, implikace a pravidla KDYŽ–PAK
  35. Fuzzy řízení: Mamdani a Sugeno od ventilátoru po kyvadlo na vozíku
  36. Fuzzy shlukování: algoritmus fuzzy c-means a body mezi shluky
  37. Neuro-fuzzy systémy (ANFIS): fuzzy pravidla, která se učí z dat
  38. Markovovy řetězce: přechodová matice, stacionární rozdělení a PageRank
  39. Skryté Markovovy modely: Viterbiho algoritmus a nepoctivé kasino
  40. Bayesovské sítě: proč je tráva mokrá a co z toho plyne pro postřikovač
  41. Kalmanův filtr: jak z nepřesných měření odhadnout, kde auto je a jak rychle jede
  42. Druhy strojového učení: s učitelem, bez učitele, s částečným učitelem a další
  43. Přeučení a regularizace: proč model, který zná data nazpaměť, selže
  44. Vyhodnocení modelu: křížová validace, F1 a křivka ROC
  45. Shlukování a snížení dimenze: k-means, PCA a t-SNE
  46. Klasifikace a regrese: dvě úlohy učení s učitelem
  47. Lineární regrese: nejmenší čtverce geometricky i maticově
  48. Polynomiální a nelineární regrese: jak přímku ohnout
  49. Logistická regrese: sigmoida, šance a křížová entropie
  50. Vícetřídní klasifikace a softmax: od dvou tříd k mnoha
  51. Naivní Bayesův klasifikátor: spamový filtr, který funguje lépe, než by měl
  52. Ztrátové funkce: co přesně model minimalizuje
  53. Rozhodovací stromy a k nejbližších sousedů: modely bez vzorců
  54. Ansámbly: náhodný les a gradient boosting
  55. SVM a jádrový trik: nejširší hranice a jak ji ohnout
  56. Signál a vzorkování: proč platí Nyquistův teorém
  57. Fourierova transformace: rozklad signálu na frekvence
  58. Filtry a konvoluce: vyhlazení, hrany a odstranění šumu
  59. Zvuk a řeč: spektrogram, melová škála a MFCC
  60. Obraz jako signál: pixely, barvy, konvoluce a hrany
  61. Perceptron a umělý neuron: nejjednodušší neuronová síť a co neumí
  62. Neuronová síť od nuly: zpětné šíření chyby krok za krokem
  63. Aktivace, inicializace a normalizace: drobnosti, na kterých hluboká síť stojí
  64. Konvoluční sítě: jak síť poznává obrázky
  65. Rekurentní sítě: paměť pro posloupnosti a mizející gradient
  66. LSTM a GRU: brány, které rozhodují, co si síť zapamatuje
  67. Autoenkodéry: síť, která se učí data stlačit a zase rozbalit
  68. Embeddingy a word2vec: jak se slovo stane vektorem
  69. Mechanismus pozornosti: jak se model naučí, kam se dívat
  70. Transformery a velké jazykové modely: architektura krok za krokem
  71. Tokenizace: jak se text rozseká na kousky pro model
  72. Předtrénování a škálování: proč větší model a víc dat funguje
  73. Doladění a RLHF: jak se z doplňovače textu stane asistent
  74. Prompty, kontext a RAG: jak modelu dát správné informace
  75. Variační autoenkodéry (VAE): nové obrázky ze spojitého latentního prostoru
  76. Generativní adversariální sítě (GAN): padělatel proti detektivovi
  77. Difúzní modely: jak se z čistého šumu stane obrázek
  78. Markovovy rozhodovací procesy: stavy, akce, odměny a Bellmanovy rovnice
  79. Q-learning a DQN: učení hodnoty akcí od tabulky po neuronovou síť
  80. Policy gradient a PPO: učení přímo strategie
  81. Jak funguje AI agent: jazykový model ve smyčce s nástroji
  82. Programování s AI agenty: zadání, testy a kontrola
  83. Vyhodnocení a bezpečnost AI systémů: jak měřit a jak hlídat

Celá osnova série 83 z 83 témat hotovo

Co si odnesete
  • Jak naivní Bayes klasifikuje text a proč se učí jen počítáním.
  • Proč je potřeba vyhlazení a co způsobuje naivní předpoklad nezávislosti.
  • Kdy naivnímu Bayesovi věřit rozhodnutí, ale ne pravděpodobnost — a kdy porazí logistickou regresi.

Co se hodí znát předem: Podmíněná pravděpodobnost a Bayesova věta: jak změnit odhad, když se dozvíte něco nového, Logistická regrese: sigmoida, šance a křížová entropie

Koncem 90. let zaplavil e-mailové schránky spam a ručně psaná pravidla („zahoď vše, kde je VIAGRA“) přestávala stačit. V roce 2002 popsal Paul Graham v eseji A Plan for Spam filtr, který se pravidla naučí sám ze zpráv, které uživatel označil — a zachytil přes 99 % spamu. Za filtrem stála Bayesova věta a jedno odvážné zjednodušení. Tomu zjednodušení se říká „naivní“, protože skoro nikdy neplatí. A přesto model funguje překvapivě dobře. V tomhle dílu si ho postavíme a ukážeme, proč funguje — i kde lže.

Navazuje na díly Podmíněná pravděpodobnost a Bayesova věta a Logistická regrese.

1. Bayesova věta jako klasifikátor

Definice — naivní Bayesův klasifikátor

Nechť 𝒞 je konečná množina tříd, C náhodná veličina s hodnotami v 𝒞 (třída) a X1, …, Xn diskrétní náhodné veličiny (příznaky) na témž pravděpodobnostním prostoru, P(C = c) > 0 pro každé c ∈ 𝒞. Zkráceně píšeme P(c) = P(C = c), P(xi | c) = P(Xi = xi | C = c) a podobně. Pro pozorované hodnoty x1, …, xn s P(x1, …, xn) > 0 dává Bayesova věta (díl Podmíněná pravděpodobnost)

P(c | x1, …, xn) = P(c) · P(x1, …, xn | c)/P(x1, …, xn).

Naivní předpoklad: příznaky jsou podmíněně nezávislé při dané třídě (definice níže), tj. pro každé c ∈ 𝒞 a všechny hodnoty x1, …, xn

P(x1, …, xn | c) = ∏i=1n P(xi | c).

Naivní Bayesův klasifikátor přiřadí pozorování (x1, …, xn) třídu

ĉ = argmaxc ∈ 𝒞 P(c) ∏i=1n P(xi | c).

Jmenovatel P(x1, …, xn) na c nezávisí, proto je ĉ právě třída s největší aposteriorní pravděpodobností; píšeme P(c | x) ∝ P(c) ∏i P(xi | c), kde ∝ znamená „rovná se až na kladný násobek, který nezávisí na c“.

Laicky řečeno

Každé slovo zprávy je malý svědek. „Zdarma“ svědčí pro spam, „porada“ pro normální poštu. Naivní Bayes vyslechne svědky jednoho po druhém a jejich výpovědi vynásobí — jako by se mezi sebou nikdy nedomlouvali. To je ta naivita: slova „klikněte“, „na“ a „odkaz“ chodí skoro vždycky spolu, ale model je počítá jako tři nezávislé důkazy.

P(c | x1, …, xn) = P(c) · ∏i=1n P(xi | c)/P(x1, …, xn)

P(c | x1, …, xn)
aposteriorní pravděpodobnost — jak pravděpodobná je třída c (spam), když už známe slova zprávy; to jediné nás zajímá
P(c)
apriorní pravděpodobnost — jak častá je třída, než zprávu vůbec otevřeme; když chodí devět spamů z deseti, potřebuje normální zpráva silnější důkazy
∏ P(xi | c)
věrohodnost — jak dobře třída „vysvětluje“ pozorovaná slova; součin místo jedné společné pravděpodobnosti je právě ten naivní předpoklad
P(x1, …, xn)
pravděpodobnost zprávy samé — pro všechny třídy stejná, takže pořadí tříd nemění; při rozhodování se vynechá (proto „∝“ v definici) a dopočte se jen jako součet čitatelů přes třídy, aby výsledky daly dohromady 1
Aposteriorní = apriorní × věrohodnost, vydělené tak, aby se pravděpodobnosti sečetly na jedničku.

Proč takové zjednodušení? Bez něj bychom potřebovali znát pravděpodobnost každé možné kombinace slov. Se slovníkem o 10 000 slovech je kombinací víc než atomů ve vesmíru. S naivním předpokladem stačí pro každé slovo a každou třídu jedno číslo — dají se spočítat z pár desítek zpráv.

Definice — podmíněná nezávislost

Nechť X, Y, C jsou diskrétní náhodné veličiny na témž pravděpodobnostním prostoru. X a Y jsou podmíněně nezávislé při daném C, právě když pro všechny hodnoty x, y, c s P(C = c) > 0 platí

P(X = x, Y = y | C = c) = P(X = x | C = c) · P(Y = y | C = c).

Ekvivalentně: pro všechna x, y, c s P(Y = y, C = c) > 0 platí P(X = x | Y = y, C = c) = P(X = x | C = c) — když třídu známe, druhé slovo o prvním nic dalšího neprozradí.

Obecněji jsou X1, …, Xn (vzájemně) podmíněně nezávislé při daném C, právě když pro všechny hodnoty x1, …, xn, c s P(C = c) > 0 platí P(X1 = x1, …, Xn = xn | C = c) = ∏i=1n P(Xi = xi | C = c). To naivní Bayes předpokládá pro všechna slova zprávy zároveň (z toho plyne podmíněná nezávislost každé dvojice i každé podmnožiny).

Podmíněná nezávislost není totéž co nezávislost. Slova „výhra“ a „zdarma“ spolu bez znalosti třídy souvisí (obě ukazují na spam, takže chodí spolu); naivní předpoklad tvrdí jen to, že uvnitř spamu už spolu nesouvisí.

Příklad — kolik čísel model potřebuje

Zjednodušme zprávu na to, které z 10 000 slov slovníku v ní jsou a které ne. Možných zpráv je 210 000 ≈ 103 010 (10 000 · log10 2 ≈ 3 010,3). Úplný model by pro každou třídu potřeboval pravděpodobnost každé z nich, tedy 2 · (210 000 − 1) čísel; atomů ve viditelném vesmíru je řádově 1080. S naivním předpokladem stačí pro každou třídu a každé slovo jedno P(slovo | třída): 2 · 10 000 = 20 000 čísel, plus jedno pro apriorní P(spam).

2. Učení je počítání

Napsali jsme si 24 trénovacích zpráv: 12 spamových a 12 normálních.

Všech 24 trénovacích zpráv

Spam:

  • Vyhrajte nový iPhone zdarma, stačí kliknout na odkaz
  • Gratulujeme, vyhráli jste 10 000 Kč, klikněte a získejte výhru
  • Zdarma půjčka bez registru, peníze ihned na účet
  • Exkluzivní nabídka jen dnes: sleva 90 % na hodinky
  • Klikněte zde a získejte bonus zdarma
  • Vaše výhra čeká, potvrďte údaje na odkazu
  • Zhubněte 10 kg za týden, zázračné tablety zdarma
  • Peníze z domova bez práce, klikněte na odkaz
  • Poslední šance: výhra 50 000 Kč čeká jen na vás
  • Levné léky bez receptu, doprava zdarma
  • Váš účet byl zablokován, ihned potvrďte údaje na odkazu
  • Získejte exkluzivní slevu, nabídka platí jen dnes

Normální:

  • Ahoj, zítra v deset máme poradu, přineseš ty podklady
  • Posílám fotky z výletu, byl to krásný den
  • Můžeš prosím koupit cestou domů chleba a mléko
  • Schůzka se přesouvá na čtvrtek, dej vědět, jestli ti to vyhovuje
  • Díky za včerejšek, večeře byla výborná
  • V příloze posílám fakturu za září, splatnost je za týden
  • Zítra nepřijdu, jsem nemocný, doktor mi dal neschopenku
  • Nezapomeň, že v sobotu má babička narozeniny
  • Ahoj, máš čas v pátek na kafe
  • Posílám podklady k poradě, kouknu na ně ještě dnes večer
  • Vlak má zpoždění, budu doma až v osm
  • Děkuji za rychlou odpověď, objednávku potvrzuji
Definice — multinomický naivní Bayes a Laplaceovo vyhlazení

Nechť V je slovník — konečná neprázdná množina slov, |V| počet jejích prvků — a 𝒞 konečná množina tříd. Trénovací data jsou zprávy, každá je posloupnost slov z V a má třídu z 𝒞. Pro s ∈ V a c ∈ 𝒞 označme

  1. počet(s, c) — počet výskytů slova s ve všech trénovacích zprávách třídy c;
  2. Nc = ∑s ∈ V počet(s, c) — celkový počet slov v trénovacích zprávách třídy c;
  3. Mc — počet trénovacích zpráv třídy c a M = ∑c ∈ 𝒞 Mc počet všech trénovacích zpráv.

V multinomickém naivním Bayesovi je zpráva x posloupnost slov (s1, …, sm), sj ∈ V, a v rámci třídy c se každé slovo táhne nezávisle z rozdělení P(· | c) na V, takže P(x | c) = ∏j=1m P(sj | c). Bez vyhlazení se P(s | c) odhaduje relativní četností počet(s, c)/Nc. S Laplaceovým vyhlazením se ke každému počtu přičte 1:

P(s | c) = počet(s, c) + 1/Nc + |V|,   s ∈ V.

Apriorní pravděpodobnost se odhaduje podílem zpráv, P(c) = Mc/M.

Laicky řečeno

Učení naivního Bayese je jedno projití dat a sčítání: kolikrát se které slovo objevilo ve spamu a kolikrát v normální poště. Žádný gradientní sestup, žádné iterace. Proto je tak rychlý — a proto ho šlo v roce 2002 pustit v každém poštovním programu. Naše spamové zprávy mají dohromady 95 slov, normální 98 a ve slovníku je 136 různých slov.

P(s | c) = počet(s, c) + 1/Nc + |V|

P(s | c)
odhad, jak pravděpodobné je, že náhodně vybrané slovo zprávy třídy c bude právě s
počet(s, c)
kolikrát se slovo objevilo v trénovacích zprávách třídy — jediná informace, kterou z dat bereme
+ 1
„pseudopočet“ — jako bychom každé slovo slovníku viděli v každé třídě o jednou víc; žádná pravděpodobnost pak nevyjde nulová
Nc
počet všech slov ve zprávách třídy (u nás 95 a 98) — dělením z počtu uděláme podíl, takže delší zprávy jedné třídy nezvýhodní její slova
+ |V|
vyrovná přičtené jedničky: přičetli jsme 1 každému z |V| = 136 slov, jmenovatel musí vzrůst o 136, aby se pravděpodobnosti přes slovník dál sčítaly na 1
Relativní četnost slova ve třídě, ke které jsme každému slovu přidali jeden vymyšlený výskyt.
Příklad — „zdarma“ a „klikněte“

„Zdarma“ je ve spamových zprávách 5× a v normálních ani jednou, „klikněte“ 3× a 0×. S Nspam = 95, Nnormální = 98 a |V| = 136:

P(zdarma | spam) = 5 + 1/95 + 136 = 6/231 ≈ 0,0260,   P(zdarma | normální) = 0 + 1/98 + 136 = 1/234 ≈ 0,0043.

P(klikněte | spam) = 3 + 1/95 + 136 = 4/231 ≈ 0,0173,   P(klikněte | normální) = 0 + 1/98 + 136 = 1/234 ≈ 0,0043   (barvy podle vzorce výše).

Poměry 6/231/1/234 = 6 · 234/231 ≈ 6,08 a 4 · 234/231 ≈ 4,05 jsou ty, které uvidíme v tabulce níže. Bez vyhlazení by byl P(zdarma | spam) = 5/95 ≈ 0,0526 a P(zdarma | normální) = 0 — poměr nekonečný.

Věta — proč zrovna relativní četnost

Nechť V je konečný slovník, N ∈ ℕ, N ≥ 1, a pro každé s ∈ V nechť ns ∈ {0, 1, 2, …} je počet výskytů slova s mezi N slovy třídy, ∑s ∈ V ns = N. Uvažujme model, který každé z N slov táhne nezávisle z V s pravděpodobnostmi θ = (θs)s ∈ V, kde θs ≥ 0 a ∑s θs = 1. Věrohodnost dat je

L(θ) = ∏s ∈ V θsns.

Pak L nabývá maxima pro θs = ns/N, s ∈ V — odhad maximální věrohodnosti je relativní četnost.

Důkaz. Slova s ns = 0 do L nepřispívají, a jakákoli kladná θs by jen ubrala ostatním, proto u nich θs = 0 = 0/N. Pro zbylá slova maximalizujeme ln L = ∑s ns ln θs za podmínky ∑s θs = 1. Lagrangeova funkce ∑ ns ln θs − λ(∑ θs − 1) má derivaci podle θs rovnou ns/θs − λ = 0, takže θs = ns/λ; z podmínky λ = ∑ ns = N. Funkce ln L je konkávní, jde tedy o maximum. ∎

Laplaceovo vyhlazení dostaneme, když na θ položíme rovnoměrné apriorní rozdělení (Dirichletovo s parametry 1) a vezmeme střední hodnotu aposteriorního rozdělení: ns + 1/N + |V|. Stejný vzorec je i odhad MAP při Dirichletově rozdělení s parametry 2.

3. Výpočet krok za krokem

Přijde zpráva „Klikněte na odkaz a potvrďte výhru zdarma“. Pro každé slovo spočteme, kolikrát je pravděpodobnější ve spamu než v normální zprávě:

SlovoP(slovo | spam)P(slovo | normální)poměr
klikněte0,01730,00434,05×
na0,03460,01712,03×
odkaz0,01300,00433,04×
a0,01300,00851,52×
potvrďte0,01300,00433,04×
výhru0,00870,00432,03×
zdarma0,02600,00436,08×

Všech sedm slov svědčí pro spam, nejsilněji „zdarma“ (6,08×) a „klikněte“ (4,05×). Apriorní pravděpodobnosti jsou stejné (12 a 12 zpráv), takže výsledné šance jsou prostě součin poměrů. V praxi se nenásobí pravděpodobnosti, ale sčítají jejich logaritmy — součin stovek malých čísel by v počítači podtekl na nulu. Výsledek: P(spam | zpráva) = 99,93 %.

s = ln P(spam)/P(normální) + ∑i ln P(xi | spam)/P(xi | normální),
P(spam | x) = 1/1 + e−s

s
logaritmus šancí spam : normální — kladný znamená spam, záporný normální zprávu; rozhoduje jen jeho znaménko
ln P(spam)/P(normální)
výchozí náklon ještě před přečtením zprávy; u nás 12 : 12, takže ln 1 = 0 a nenaklání nikam
∑ ln P(xi | spam)/P(xi | normální)
příspěvky slov — logaritmus změní součin poměrů na součet, takže každé slovo jen přičte své „body“ (kladné pro spam, záporné pro normální) a nic nepodteče
1/1 + e−s
sigmoida převede šance zpátky na pravděpodobnost; dělá totéž co jmenovatel P(x) v Bayesově větě — srovná obě třídy tak, aby daly dohromady 1
Stejná Bayesova věta, jen pro poměr dvou tříd a v logaritmech; P(x) se v poměru zkrátí.
Příklad — první zpráva v logaritmech

Přirozené logaritmy poměrů z tabulky (pro slova v pořadí „klikněte“, „na“, „odkaz“, „a“, „potvrďte“, „výhru“, „zdarma“):

1,399 + 0,706 + 1,112 + 0,418 + 1,112 + 0,706 + 1,805 ≈ 7,257

(součet nezaokrouhlených hodnot; barvy podle vzorce výše). Apriorní člen je ln 12/12 = 0, takže s ≈ 7,257. Šance jsou e7,257 ≈ 1 419 : 1 a P(spam) = 1/1 + e−7,257 ≈ 99,93 %.

Proč logaritmy: samotné součty ln P(spam) + ∑ ln P(xi | spam) = -29,544 a pro normální třídu -36,801 odpovídají pravděpodobnostem kolem 10−13 a 10−16, a to má zpráva jen sedm slov. Dlouhý e-mail s 200 slovy po P ≈ 0,004 by dal 0,004200 ≈ 10−480, což je pod nejmenším kladným číslem typu double (asi 4,9 · 10−324) — počítač vrátí 0. Jeho logaritmus 200 · ln 0,004 ≈ −1 104,3 je naopak úplně obyčejné číslo.

Druhá zpráva: „Posílám odkaz na fotky, potvrďte prosím, jestli dorazily“. Slova „odkaz“ a „potvrďte“ svědčí pro spam (3,04×), méně i „na“ (2,03×), ale „posílám“ (0,25×), „fotky“, „prosím“ a „jestli“ (každé 0,51×) pro normální zprávu. Slovo „dorazily“ model nikdy neviděl, a tak ho vynechá. Výsledek: P(spam) = 38,1 % — normální zpráva.

Celý model — učení i klasifikace — v pseudokódu:

# učení: jedno projití dat
for c in {spam, normální}:
    apriorní[c] = (počet zpráv třídy c) / (počet všech zpráv)
    for každé slovo s ve zprávách třídy c:
        počet[c][s] += 1
        N[c] += 1
V = množina všech slov ze všech trénovacích zpráv

# klasifikace zprávy x
for c in {spam, normální}:
    skóre[c] = ln apriorní[c]
    for každé slovo s ve zprávě x:
        if s not in V: continue          # neviděné slovo vynecháme
        skóre[c] += ln((počet[c][s] + 1) / (N[c] + |V|))
s = skóre[spam] − skóre[normální]
return P(spam | x) = 1 / (1 + e^(−s))

4. Problém nulové četnosti

Proč to přičítání jedničky? Zkusme ho vynechat. Slovo „klikněte“ se v normálních trénovacích zprávách neobjevilo ani jednou, takže P(„klikněte“ | normální) = 0. Celý součin pro normální třídu je pak nula, ať jsou ostatní slova jakákoli: první zpráva je spam se stoprocentní jistotou.

Laicky řečeno

Jeden svědek, který řekne „tohle jsem v normální poště nikdy neviděl“, přehlasuje všechny ostatní. U druhé zprávy je to ještě horší: „posílám“ ve spamu nebylo nikdy a „odkaz“ v normální poště nikdy, takže obě třídy vyjdou nulové a P(spam) = 0/0 — model neumí odpovědět vůbec. Přičtení jedničky každému slovu říká: „co jsme neviděli, není nemožné, jen vzácné.“ Je to stejný nápad jako bayesovský odhad MAP z dílu Statistika a odhady parametrů.

5. Naivita: správná rozhodnutí, přehnaná jistota

Co se stane, když stejný důkaz započítáme víckrát? Napíšeme druhou zprávu tak, že každé slovo zopakujeme dvakrát, potom třikrát. Žádná nová informace nepřibyla — ale naivní Bayes počítá každé opakování jako nezávislého svědka.

Každé slovo napsané1×2×3×
P(spam), druhá zpráva38,1 %27,5 %18,9 %
P(spam), první zpráva99,93 %99,99995 %99,99999996 %

Rozhodnutí se nezmění — druhá zpráva zůstane normální, první spamem — ale jistota roste bez důvodu. Skutečné zprávy jsou plné závislých slov („klikněte na odkaz“, „bez registru“), a tak naivní Bayes stejný důkaz započítává pořád znovu. Pedro Domingos a Michael Pazzani v roce 1997 ukázali, proč to často nevadí: pro správnou klasifikaci stačí, aby správná třída vyšla největší, ne aby pravděpodobnosti byly přesné. Přehnaná jistota posune obě třídy, ale pořadí obvykle nezmění.

Věta — zopakování slov násobí logaritmus šancí

Nechť x = (x1, …, xm) je zpráva ze slov slovníku V (neviděná slova jsou vynechaná), P(· | spam) a P(· | normální) jsou vyhlazené pravděpodobnosti multinomického modelu (všechny kladné) a k ∈ ℕ, k ≥ 1. Nechť x(k) je zpráva, ve které je každé slovo xi napsané k-krát, a sk její logaritmus šancí podle vzorce výše. Pak

sk = ln P(spam)/P(normální) + k · ∑i=1m ln P(xi | spam)/P(xi | normální).

Důkaz. Zpráva x(k) obsahuje každé slovo xi k-krát, takže se každý člen součtu ve vzorci pro s objeví k-krát, kdežto apriorní člen na zprávě nezávisí a je tam jen jednou. ∎

U nás je apriorní člen 0, takže sk = k · s1: znaménko (rozhodnutí) zůstane, velikost (jistota) roste bez omezení. Pro druhou zprávu je s1 ≈ −0,485, tedy (barvy podle vzorce výše)

  • k = 2: s ≈ −0,970, P(spam) = 1/1 + e0,970 ≈ 27,5 %,
  • k = 3: s ≈ −1,455, P(spam) = 1/1 + e1,455 ≈ 18,9 %.

Pro první zprávu (s1 ≈ 7,257) dává k = 2 hodnotu s ≈ 14,515 a P(spam) ≈ 1 − 5,0 · 10−7 = 99,99995 %. Totéž se děje se skutečně závislými slovy: dvě slova, která chodí vždy spolu, nesou informaci jednoho, ale model jejich příspěvek přičte dvakrát.

6. Kdy mu nevěřit: kalibrace

Na pár ručně psaných zprávách se nic změřit nedá, proto si zprávy vygenerujeme. Každá se skládá ze dvou až pěti frází jako „klikněte na odkaz“ nebo „posílám podklady“; některé fráze jsou společné oběma třídám a část frází je „z cizí třídy“, aby úloha nebyla triviální. Slova uvnitř frází jsou silně závislá — přesně to, co naivní Bayes neumí.

Definice — kalibrace

Nechť (X, Y) je náhodný příklad se třídou Y ∈ {0, 1} (1 = pozitivní, u nás spam) a nechť klasifikátor každému vstupu x přiřadí předpověď p̂(x) ∈ [0, 1] pravděpodobnosti, že Y = 1. Klasifikátor je kalibrovaný, právě když pro každé p ∈ [0, 1], které předpovídá s kladnou pravděpodobností, platí

P(Y = 1 | p̂(X) = p) = p,

tj. mezi příklady, kterým přisoudí pravděpodobnost p, je podíl skutečně pozitivních p. Na konečných datech (x1, y1), …, (xn, yn) se to ověřuje kalibračním grafem:

  1. interval [0, 1] se rozdělí na koše — disjunktní intervaly B1, …, Bm;
  2. pro každý koš j se vezmou indexy Ij = {i : p̂(xi) ∈ Bj} a pro neprázdné Ij se spočte průměrná předpověď 1/|Ij| ∑i ∈ Ij p̂(xi) a skutečný podíl pozitivních 1/|Ij| ∑i ∈ Ij yi;
  3. každý koš je bod (průměrná předpověď, skutečný podíl).

Body dokonale kalibrovaného modelu leží (až na náhodné kolísání) na diagonále.

Laicky řečeno

Když předpověď počasí řekne „70 % déšť“, mělo by pršet asi v sedmi dnech z deseti takových. Když prší v pěti, předpověď je přehnaně sebejistá. Kalibrace neměří, jestli model trefuje, ale jestli jeho jistota odpovídá skutečnosti.

000,50,511 předpovězená P(spam) (0–1) skutečný podíl spamu (0–1) ● naivní Bayes ● logistická regrese - - dokonalá kalibrace
Kalibrace na 4 000 generovaných zprávách (modely naučené na 512)

Naivní Bayes je přehnaně sebejistý na obou koncích. Když tvrdí „spam s jistotou nad 95 %“ (průměrně 98,9 %), je to spam jen v 85,1 % případů. Když tvrdí „pod 5 %“ (průměrně 0,9 %), je spamem 6,9 % zpráv. Logistická regrese, která váhy slov učí společně a závislosti tak bere v úvahu, leží skoro na diagonále: její nejjistější koš má předpověď 97,6 % a skutečnost 96,5 %. Pokud tedy pravděpodobnost z naivního Bayese chcete použít jako pravděpodobnost — třeba k výpočtu očekávané ztráty — musíte ji nejdřív překalibrovat.

Definice — Plattova překalibrace

Nechť původní klasifikátor dává pro vstup x logaritmus šancí s(x) ∈ ℝ a nechť (x1, y1), …, (xm, ym), yi ∈ {0, 1}, je kalibrační množina — data, která model při učení neviděl; si = s(xi). Plattova překalibrace nahradí předpověď modelu funkcí

p′(x) = σ(a · s(x) + b),

kde σ je sigmoida a parametry a, b ∈ ℝ minimalizují křížovou entropii na kalibrační množině,

(a, b) = argmina, b −1/m ∑i=1m [yi ln σ(asi + b) + (1 − yi) ln(1 − σ(asi + b))].

Je to tedy logistická regrese s jediným vstupem s. Postup navrhl John Platt (1999) pro skóre metody SVM; funguje pro jakýkoli model, jehož skóre je správně seřazené, jen špatně škálované.

p′ = σ( a · s + b )

p′
překalibrovaná pravděpodobnost spamu — to, co chceme, aby „80 %“ znamenalo spam v osmi případech z deseti
σ
sigmoida σ(z) = 1/1 + e−z —výsledek musí zůstat mezi 0 a 1 a pro a = 1, b = 0 vrátí přesně původní předpověď naivního Bayese
a
„ztlumení“ — přehnaně sebejistý model má logaritmy šancí příliš velké; a < 1 je stáhne k nule, a protože a > 0, pořadí zpráv (a tedy ani to, která je spamovější) se nezmění
s
logaritmus šancí podle naivního Bayese (oranžová křivka v grafu) — veškerá informace o zprávě, kterou máme
+ b
posun — opraví systematický náklon k jedné třídě, např. když se podíl spamu v provozu liší od trénovacích dat

Na 1 000 dalších generovaných zprávách vyjde a ≈ 0,38 a b ≈ -0,33. Logaritmy šancí naivního Bayese jsou tedy zhruba 2,6× větší, než by měly být — sedí to s tím, že slova u nás chodí ve frázích po dvou až třech a model je počítá jako samostatné svědky. Zpráva, které naivní Bayes přisoudí 99 % (s = ln 99 ≈ 4,595), dostane po překalibraci σ(0,379 · 4,595 − 0,326) ≈ 80,5 % (barvy podle vzorce výše). Na 4 000 testovacích zprávách se nejjistější koš (nad 95 %) změní z předpovědi 98,9 % a skutečnosti 85,1 % na 97,2 % a 98,4 %, nejnižší (pod 5 %) z 0,9 % a 6,9 % na 2,6 % a 2,3 %. Do košů „pod 5 %“ a „nad 95 %“ ale teď padne méně zpráv (519 a 124 místo 1464 a 879) — model přestal být jistý tam, kde k tomu neměl důvod.

7. Proč ho přesto používat: málo dat

Andrew Ng a Michael Jordan v roce 2002 porovnali naivního Bayese s logistickou regresí a ukázali, že naivní Bayes se k nejlepší přesnosti, které je schopný, přiblíží s mnohem menším počtem trénovacích příkladů. Logistická regrese pak má nakonec často přesnost vyšší, ale potřebuje k ní víc dat. Na našich generovaných zprávách:

60 %70 %80 % 48163264128256512 trénovací zprávy (počet, log. měřítko) přesnost (% správně)
Přesnost podle počtu trénovacích zpráv (průměr z 20 opakování) naivní Bayes logistická regrese

Se 32 zprávami má naivní Bayes 74,0 % a logistická regrese 71,6 %; se 128 zprávami 78,9 % proti 77,3 %. U 256 zpráv jsou skoro stejně (79,6 % a 79,5 %) a u 512 už vede logistická regrese, 80,9 % proti 80,2 %. Naivní předpoklad je silné omezení: model se nemusí učit nic o tom, jak slova spolupracují, takže vystačí s málem dat — ale ani se to nikdy nenaučí.

Definice — generativní a diskriminativní model

Nechť X je náhodný vektor příznaků a C náhodná třída s hodnotami v konečné množině 𝒞.

  1. Generativní model popisuje, jak data vznikají: odhaduje P(c) a P(x | c) pro všechna c ∈ 𝒞 (tím i společné rozdělení P(x, c) = P(c) P(x | c)) a aposteriorní pravděpodobnost dopočítá Bayesovou větou P(c | x) = P(c) P(x | c)/∑c′ ∈ 𝒞 P(c′) P(x | c′).
  2. Diskriminativní model odhaduje přímo P(c | x) jako funkci x (nebo jen rozhodovací pravidlo, tj. hranici mezi třídami) a o rozdělení x nepředpokládá nic.

Naivní Bayes je generativní, logistická regrese diskriminativní.

Překvapivé je, že oba modely mají stejný tvar. Když v logaritmu šancí sečteme stejná slova dohromady (ns = kolikrát je slovo s ve zprávě), dostaneme:

s(x) = w0 + ∑s ∈ V ns · ws

s(x)
logaritmus šancí spam : normální; přes sigmoidu dává P(spam | x) — přesně jako u logistické regrese
w0
práh: u naivního Bayese ln P(spam)/P(normální), u logistické regrese naučený posun
ns
příznak — počet výskytů slova ve zprávě; oba modely vidí zprávu jako „pytel slov“ a pořadí slov je jim jedno
ws
váha slova: naivní Bayes ji spočítá z četností, každou zvlášť, jako ln P(s | spam)/P(s | normální); logistická regrese ji hledá gradientním sestupem všechny najednou, takže si dvě slova z jedné fráze mohou váhu rozdělit
Naivní Bayes je lineární klasifikátor — liší se od logistické regrese jen tím, jak si váhy najde.

Odtud i výsledek Nga a Jordana: když má zpráva d možných příznaků, naivní Bayes se ke své nejlepší přesnosti dostane už s počtem příkladů řádu log d (každou váhu odhaduje zvlášť z prostých četností), logistická regrese obecně potřebuje řádově d příkladů — zato může dojít k lepší hranici, protože ji neomezuje předpoklad nezávislosti.

Proto naivní Bayes dodnes slouží jako první model, se kterým se cokoli porovnává: učí se okamžitě, běží na čemkoli, zvládne milion slov ve slovníku a dá se mu rozumět — u každého slova vidíte, kolikrát posouvá šance. Nasazuje se na klasifikaci textů, třídění zákaznických dotazů nebo jako rychlý filtr před dražším modelem.

8. Shrnutí

  • Naivní Bayes počítá P(třída) · ∏ P(slovo | třída) a předpokládá, že slova jsou v rámci třídy nezávislá.
  • Učení je jen počítání slov; zprávu s „klikněte na odkaz … zdarma“ označil za spam s pravděpodobností 99,93 %.
  • Bez Laplaceova vyhlazení rozhodne jediné neviděné slovo — nebo model neodpoví vůbec (0/0).
  • Zdvojením slov se rozhodnutí nemění, ale jistota roste; na generovaných zprávách „98,9 %“ znamenalo ve skutečnosti 85,1 %.
  • S málo daty je lepší než logistická regrese (74,0 % proti 71,6 % na 32 zprávách), s hodně daty ho logistická regrese předežene.

Chcete si to osahat? Nechte AI agenta postavit naivního Bayese na vlastní poště — exportujte složku spamu a složku doručené pošty — a nechte si vypsat deset slov, která nejvíc posouvají šance na spam.

Máte na to jiný názor? Napište na support@coden-app.com.

Agent na vašem počítači, ovládaný z telefonu