Lassen Sie mich versuchen, dies zu versuchen, um zu sehen, wie viel ich es schlachten kann. :-)
Zu Beginn müssen Sie also in der Lage sein, einen regulären Bloom-Filter zu erstellen, der eine begrenzte Anzahl von Elementen mit einer maximalen Wahrscheinlichkeit für ein falsches Positiv zulässt. Das Hinzufügen dieser Funktionen zu Ihrem Basisfilter ist erforderlich, bevor Sie versuchen, eine skalierbare Implementierung zu erstellen.
Bevor wir versuchen, die Wahrscheinlichkeit zu steuern und zu optimieren, ermitteln wir die Wahrscheinlichkeit für eine bestimmte Bloom-Filtergröße.
Zuerst teilen wir das Bitfeld nach der Anzahl der verfügbaren Hash-Funktionen (Gesamtzahl der Bits / Anzahl der Hash-Funktionen = Slices) auf, um k Slices von Bits zu erhalten, die jede Hash-Funktion darstellen, sodass jedes Element immer durch k Bits beschrieben wird.
Wenn Sie die Anzahl der Slices oder die Anzahl der Bits pro Slice erhöhen, verringert sich die Wahrscheinlichkeit von Fehlalarmen.
Daraus folgt auch, dass beim Hinzufügen von Elementen mehr Bits auf 1 gesetzt werden, so dass falsch-positive Ergebnisse zunehmen. Wir bezeichnen dies als das "Füllverhältnis" jeder Scheibe.
Wenn der Filter eine große Datenmenge enthält, können wir davon ausgehen, dass die Wahrscheinlichkeit falsch positiver Ergebnisse für diesen Filter das Füllungsverhältnis ist, das auf die Anzahl der Schichten angehoben wurde eine Permutation mit Wiederholungsproblem).
Wie können wir also herausfinden, wie eine Wahrscheinlichkeit für falsch positive Ergebnisse in einem Bloom-Filter ermittelt werden kann? Wir können die Anzahl der Slices ändern (was sich auf den Füllungsgrad auswirkt).
Um herauszufinden, wie viele Slices wir haben sollten, müssen wir zunächst den optimalen Füllgrad für ein Slice ermitteln. Da das Füllverhältnis durch die Anzahl der Bits in einem Slice bestimmt wird, die 1 gegenüber der Anzahl der Bits, die 0 sind, können wir bestimmen, dass jedes Bit mit einer Wahrscheinlichkeit von (100% - (1 / Bits in einem Slice) nicht gesetzt wird. ). Da wir mehrere Elemente einfügen werden, haben wir eine weitere Permutation mit Reputationsproblemen und erweitern die Dinge auf den erwarteten Füllungsgrad, der (100% - ((100% - (1 / Bit in einem Slice)) ^ beträgt "Elemente eingefügt")). Nun, es stellt sich heraus, dass dies einer anderen Gleichung sehr ähnlich ist. In der Arbeit wird der Füllgrad mit einer anderen Gleichung in Beziehung gesetzt, sodass er gut in eine Taylor-Reihe (1-e ^ (-n / m)) passt. Nach einigem Nachdenken stellt sich heraus, dass der optimale Füllgrad immer bei ca. 50% liegt.
Da also die Wahrscheinlichkeit eines Filters ist, dass der Füllgrad auf die Anzahl der Schichten angehoben wird, können wir 50% ausfüllen und P = (50%) ^ k oder k = log_2 (1 / P) erhalten. Mit dieser Funktion können wir dann die Anzahl der Schichten berechnen, die für einen bestimmten Filter in der Filterliste für einen skalierbaren Bloom-Filter generiert werden sollen.
def slices_count(false_positive_probability):
return math.ceil(math.log(1 / false_positive_probability, 2))
Bearbeiten: Nachdem ich dies geschrieben hatte, stieß ich auf eine Erwähnung der "Fünfzig-Prozent-Regel", als ich in TAoCP Vol. 1, S. 442-445 über die dynamische Speicherzuweisung auf Buddy-System-Basis nachlas -e ^ (-n / m)). Knuth verweist auch auf ein Papier "Die Fünfzig-Prozent-Regel überarbeitet" mit ein wenig Hintergrundinformationen zum Konzept ( pdf hier verfügbar ).