Bloom Filter: una nuova libreria Ruby
A cosa serve un filtro di Bloom?
Un filtro di Bloom è utile quando si tratta di fare ricerche con un dataset di grandi dimensioni. I filtri di Bloom esistono in più tipi, la gemma BloomFilter è l’implementazione di un filtro di Bloom semplice e potete installarla semplicemente con:
1 gem install bloomfilter
Che cosa è un Bloom Filter?
Il filtro di Bloom (da H. Bloom che lo concepì nel 1970), è una struttura dati probabilistica space-efficient ed è utilizzato per stabilire se un elemento è appartenente ad un dataset prestabilito di elementi. Sono possibili falsi positivi ma non falsi negativi. Quindi più elementi appartegono al dataset di elementi prestabiliti, più aumenta la possibilità di falsi positivi.
Come funziona?
Un Bloom Filter è un vettore di bit definito da due parametri:
- Un array di M bit
- K funzioni di Hash indipendenti con codominio in [1,M]
Inizialmente gli M bit dell’array sono settati tutti a zero (0), il passo successivo è riempire il filtro di Bloom con quegli elementi che creano il dataset sul quale poi fare i confronti. Per riempire il filtro si deve applicare k funzioni hash ad ogni elemento, i k risultati dell’hash sono la posizione di ogni bit che verranno settati ad uno (1). Può succedere che più di una chiave setti lo stesso bit ad uno.
Questo è quello che succede applicando ad esempio 3 funzioni di hash all’elemento bicchiere:

Per creare il dizionario di parole iniziali si adotterà questo procedimento per tutti gli elementi che voglio inserire:

A questo punto vedere se un oggetto appartiene al set è semplice: si applicano k funzioni hash all’elemento da cercare per ottenere le k posizioni dei bit sull’array e si controlla che queste siano settate ad uno (1), se tutti i bit sono uno (1) allora l’oggetto potrebbe appartenere al set, altrimenti no.
Vediamo come potrebbero essere alcuni risultati di ricerca:

Adesso invece vediamo un esempio di falso positivo, applicando 3 funzioni hash alla parola cartella si ottengono 3 bit dell’array di Bloom; Controllando sul “filtro pieno”, i bit, sono tutti impostati ad “1″ (colorati nel disegno). Il problema però è che i colori per modo di dire non corrispondono, cioè il fatto che la parola cartella sia un falso positivo dipende dal fatto che i 3 bit sono settati ad uno perchè la parola piatto e la parola bicchiere del dataset avevano impostato quei bit ad uno (1).

Il filtro di Bloom consente l’inserimento e la ricerca ma non la rimozione, infatti per rimuovere un oggetto si dovrebbe settare a zero (0) i k bit risultanti dall’applicazione delle k funzioni di hash, ma questo potrebbe accidentalmente cancellare altri oggetti del dataset.
Il filtro di Bloom descritto precedentemente, implementato nella libreria Ruby, è un filtro semplice che ad esempio non funziona per mappare un dataset multilivello come potrebbe essere un documento XML. I filtri di Bloom esistono anche BBF (Breadth Bloom Filters) e DBF (Depth Bloom Filters) con differenti prestazioni a seconda della grandezza del dataset.
Alcuni risultati
I ragazzi di Rapleaf hanno dumpato 40 Milioni di hash su un file creando un filtro di Bloom; come risultato hanno ottenuto un un array di 100MB di bit, successivamente hanno controllato una lista di 500 Milioni di hash creando una lista di possibili match. Hanno impiegato circa 8 ore contro i 20 giorni previsti per fare gli stessi controlli usando comparazioni su database Mysql. Hanno trovato che dei match trovati il 98% erano positivi veri, mentre il 2% erano falsi positivi.


Mi imbatto per la prima volta in questo blog… e trovo quest’artico interessante, su un argomento da approfondire assolutamente. Complimenti.
Grazie LP,
prossimamente farò degli esempi di codice con la libreria per rails poi mi piacerebbe estendere il comportamente del Bloom Filter semplice, per applicarlo a file Xml.
Il tempo è tiranno come sempre, ma cercherò comunque di pubblicare.
Chiarissima la spiegazione. Da quello che capisco, leggendo anche l’esempio linkato l’applicazione sulle ricerche di un subset all’interno di un grosso dataset prevede di: a) popolare l’array hash con il subset interessato e b) applicare le funzioni di hash sui singoli elementi del dataset completo. Le risposte negative sono “sicure” mentre quelle positive dovrebbero essere verificate con riscontro sul subset iniziale. Cosa si puo` fare per gestire anche la cancellazione?
Ricrei tutto l’hash…
non è possibile fare altrimenti credo.
Perchè quando cancelli un lemento potresti inavvertitamente cancellarne anche altri.
Mi sono imbattuto in questo articolo perché cercavo di capire il funzionamento dei filtri di Bloom per il controllo delle password e devo fare i miei complimenti per la chiarezza dell’articolo.
Dario.
Grazie!!
ciao, sei stato chiarissimo…per questioni universitarie dovevo capire che roba erano sti filtri…mica sai spiegarmi come funzionano i filtri con compressione??? grazie mille
Non so per quando ti serve… spero nel giro di qualche giorno di fare un post sui bloom filter con compressione!!!
Ho fatto un post che ne parla, prova a dargli un’occhiata!
Il bloom filter non offre la possibilita’ di eliminare gli elementi una volta inseriti pero’ esiste un’estensione chiamata Counting filter che permette l’eliminazione.
Il tutto chiaramente ha un costo: si usa piu’ memoria.
Per informazioni:
http://en.wikipedia.org/wiki/Bloomfilter#Countingfilters