bloom filter
Bloomův filtr je pravděpodobnostní datová struktura, která slouží k paměťově velmi úsporné reprezentaci množiny prvků. Umožňuje provádět dvě operace:
insert: Vložit prvek do množiny.find(query): Zjistit, zda prvek v množině je.
Klíčová vlastnost
Odpověď na doraz (find) není vždy 100% přesná:
- no false negative: Nikdy se nemýlí v negativní odpovědi. Pokud filtr nenajde prvek, určitě tam není
- false positives: Pokud filtr prvek najde, pravděpodobně tam je, ale může jít o omyl
[!important] Mazání Standardní Bloomův filtr neumožňuje mazání. —
Algoritmus
Struktura Máme pole $m$ bitů ($B[0…m−1]$), které jsou na začátku všechny nastaveny na $0$. Máme $k$ nezávislých hashovacích funkcí $h_1,…,h_k$, které mapují univerzum do rozsahu $[m]$.
insert(x)
Pro vkládaný prvek $x$ spočítáme všech $k$ hashovacích hodnot $h_1(x), \dots, h_k(x)$. V poli $B$ nastavíme bity na těchto indexech na 1.
find(x)
Opět spočítáme $h_1(x), \dots, h_k(x)$ a podíváme se do pole $B$.
- Pokud je každý z těchto bitů $=1$, odpovíme ano (prvek tam asi je)
- Pokud je alespoň jeden z těchto bitů $=0$, odpovíme NE (prvek tam určitě není)
Analýza
Jaká je šance, že se trefím do obsazeného místa?
1 krok: Jaká je šance, že bit zůstane 0? Máme $n$ prvků a hashujeme $k$ funkcemi. Celkem tedy nastavíme $kn$ bitů.
- Šance, že jednou šipkou trefím do konkrétního bitu je $1/m$
- Šance, že se do něj netrefím je $1 - 1/m$
- Aby bit zůstal prázdný ($0$), musím se do něj netrefit ani jednou ze všech $kn$ pokusů
Pravděpodobnost, že bit je $0$ ($P_0$) je tedy: \(P_0 = (1-\frac{1}{m})^{kn}\)
V matematice platí známá limita pro velká čísla: $(1-1/m)^m \approx 1/e$ . Tento vzorec tedy můžeme upravit jako: \(P_0 =((1-1/m)^m)^{\frac{kn}{m}} \approx e^{-\frac{kn}{m}}\) Zaplnění závisí na poměru počtu hodů ($kn$) a velikost tabulky $m$
2.krok: Jaká je šance na false positive? false positive nastane, když se ptáme na prvek $Y$ (který v množině není), ale filtr nám řekne ANO. TO se stane, pokud všech $k$ funkcí pro prvek $Y$ dopadne do již nastavených bitů.
- pravděpodobnost, že bit je $1$, je prostě opak toho, že je $0$: \(P_1 = 1-P_0\)
- Aby nastala chyba, musíme mít smůlu $k$-krát za sebou (všech $k$ hashů trefilo jedničku:) \(P_\text{chyba} = (P_1)^k = (1-P_0)^k\) Dosadíme náš odhad z kroku 1: \(P_\text{chyba} \approx (1-e^{-\frac{kn}{m}})^k\)
3.krok: Intuitivní optimalizace (pravidlo 50%)
[!note] Poznámka Tady je důležité si uvědomit, že bloom filtry se většinou vytvářejí nad statickými daty, takže $n$ je dané a $m$ je nějaká zeshora omezená paměť (RAM). Abychom tedy tabulku co nejvíce využili musíme zvolit optimální $k$
Teď přichází ta nejdůležitější myšlenka.
Kdy nese pole nejvíc informace?
- Když je skoro prázdné (samé 0): Plýtváme místem. Hashovacích funkcí ($k$) je málo
- Když je skoro plně (samé 1): Všechno koliduje. Každý dotaz vrátí “ANO”. Hashovacích funkcí ($k$) je moc.
Filtr funguje nejlépe, když je v poli zhruba stejný počet nul a jedniček (balanc mezi počtem uložených informací a pravděpodobností false positive). Pravděpodobnost, že bit je nula, by měla být $1/2$.
Pokud dosadíme tuto logickou úvahu ($P_0 = 1/2$) do rovnice z kroku 1: \(e^{- \frac{kn}{m}} = \frac{1}{2}\) Zlogaritmujeme (přirozený logaritmus $ln$): \(\begin{align} -\frac{kn}{m} &= \ln(1/2) = -\ln 2 \\ \frac{kn}{m} &= \ln 2 \end{align}\)
Z toho jednoduše vyjádříme optimální počet hashovacích funkcí $k$: \(k=\frac{m}{n} \cdot \ln 2 \approx 0.7 \cdot \frac{m}{n}\)
Příklad praktického použití
Typické použití je jako rychlý filtr před náročnou operací. Chceme rychle vyloučit prvky, které “určitě neexistují”, abychom nemuseli sahat na pomalý disk nebo do sítě.
Příklad: Detekce škodlivých URL (webový prohlížeč) Prohlížeč chce zkontrolovat, zda URL adresa, kterou uživatel navštívil, není na seznamu známých škodlivých stránek.
- Seznam škodlivých stránek je obrovský (miliony), stahovat ho celý do paměti uživatele je neefektivní.
- Prohlížeč si stáhne pouze kompaktní Bloomův filtr reprezentující tento seznam.
- Při návštěvě stránky se prohlížeč zeptá filtru:
- Odpověď NE: Stránka je bezpečná (určitě není na seznamu). → Rychlé, bez sítě.
- Odpověď ANO: Stránka je asi škodlivá. → Prohlížeč pošle dotaz na server (pomalé), aby to ověřil na 100 %. (V tomto případě nevadí malé % falešných pozitiv, protože se jen provede zbytečný dotaz na server, ale uživatel není ohrožen falešným negativem).