So Bloom Filter sind ziemlich cool - sie sind Sätze , dass die Unterstützung der Mitglieder ohne falsche Negative Kontrolle, aber eine kleine Chance eines falsch positiven Ergebnisses . Kürzlich wollte ich jedoch einen "Bloom-Filter", der das Gegenteil garantiert: keine falschen Positiven, sondern potenziell falsche Negative.
Meine Motivation ist einfach: Angesichts einer großen Anzahl von zu verarbeitenden Elementen (mit Duplikaten) möchten wir vermeiden, Elemente zu verarbeiten, die wir zuvor gesehen haben. Es tut nicht weh, ein Duplikat zu verarbeiten, es ist nur Zeitverschwendung. Wenn wir es versäumen, ein Element zu verarbeiten, wäre dies katastrophal. Mit einem "Reverse Bloom-Filter" könnte man die mit geringem Platzaufwand gesehenen Objekte speichern und vermeiden, dass Duplikate mit hoher Wahrscheinlichkeit verarbeitet werden, indem man auf Mitgliedschaft in der Gruppe prüft.
Trotzdem kann ich nichts dergleichen finden. Das nächstliegende, was ich gefunden habe, sind " retuschierte Bloom-Filter ", mit denen man ausgewählte falsch-positive Ergebnisse gegen eine höhere falsch-negative Rate eintauschen kann. Ich weiß jedoch nicht, wie gut ihre Datenstruktur funktioniert, wenn man alle Fehlalarme entfernen möchte .
Hat jemand so etwas gesehen? :)
quelle
Antworten:
Eine Antwort ist, eine große Hash-Tabelle zu verwenden und, wenn sie voll ist, die darin enthaltenen Elemente zu ersetzen, anstatt für sie an anderer Stelle (nicht vorhandene) leere Slots zu finden. Sie erhalten nicht die schöne feste Rate falscher Antworten, die Sie mit Bloom-Filtern erhalten, aber es ist besser als nichts. Ich glaube, dies ist Standard, zB in Schachsoftware, um Positionen zu verfolgen, die bereits gesucht wurden.
quelle
Die Antwort auf diese Frage lautet "nein". Um zu sehen, warum, können wir über einen extremen Fall nachdenken und wie ein regulärer Bloom-Filter im Vergleich zu einem theoretischen "Bizzaro World" Bloom-Filter, den wir "Gloom-Filter" nennen können, funktionieren würde.
Das Besondere an einem Bloom-Filter ist, dass Sie einseitige Tests für die Zugehörigkeit von Elementen (mit falsch positiven Ergebnissen) mithilfe einer Datenstruktur durchführen können, die eine feste Größe in Bezug auf die Fehlerwahrscheinlichkeit und die Anzahl der gespeicherten Elemente aufweist. Die Größe der Artikel selbst spielt keine Rolle. Wenn zum Beispiel ein Bloom-Filter eingerichtet wäre, um bis zu 1.000 Elemente mit weniger als 3% Fehler zu speichern, könnten 1.000 leicht unterschiedliche Versionen des gesamten Wikipedia-Korpus mit jeweils einem geänderten Buchstaben gespeichert werden Holen Sie sich die gewünschten Metriken, und die Datenstruktur wäre sehr klein (weniger als ein Kilobyte). Natürlich wird das Berechnen dieser Hashes eine Herausforderung sein, aber das Prinzip bleibt bestehen.
Ziehen Sie nun in Betracht, dieselben massiven Zeichenfolgen in einem dunklen Filter zu speichern! Wir können jetzt nur falsche Negative haben. Wenn wir also sagen "Ja, diese Version des gesamten Wikipedia-Korpus ist in diesem Set", dann müssen wir absolut Recht haben. Das heißt, Hashing hilft uns nicht weiter, da es immer eine andere Zeichenfolge gibt, die auf den gleichen Wert hasht. Die einzige Möglichkeit, "Ja" zu sagen und sicher zu sein, besteht darin, die gesamte Zeichenfolge oder einige äquivalente Daten derselben Länge zu speichern. Wir konnten es immer nicht speichern und "nein" sagen, aber irgendwann wird uns die Fehlerrate einholen. Das Beste, was wir tun können, ist die Komprimierung, bei der die Größe der Struktur auf das Produkt aus der Entropie der gespeicherten Daten und der von uns gewünschten Genauigkeit reduziert wird.
Leider gibt es den Düsternisfilter nicht. Zwischenspeichern ist die einzige Lösung, aber es ist nicht wirklich das Gegenteil eines Bloom-Filters, da seine Größe proportional zum Produkt aus der Menge der gespeicherten Informationen und der gewünschten Genauigkeitsrate des Filters ist. Natürlich können in vielen realen Szenarien große Datenmengen durch eine ID dargestellt werden, sodass das Zwischenspeichern immer noch akzeptabel ist. Aber es ist grundlegend anders als der mächtige Blütenfilter.
quelle
Sie möchten nur einen Cache , denken aber auf seltsame Weise darüber nach.
quelle
HAFTUNGSAUSSCHLUSS: Ich bin kein Cachespezialist, daher könnte dies eine naive Idee sein und auch eine bekannte Idee, von der ich noch nie zuvor gehört habe. Entschuldigen Sie mich, wenn ich den Verweis nicht zitiere (falls vorhanden). und informieren Sie mich bitte, wenn es einen Verweis dafür gibt, um den Beitrag zu bearbeiten und hinzuzufügen. (Ich vermute, es könnte eine Referenz haben, weil es so intuitiv ist).
Eine schnelle Lösung, nachdem Sie sich von Strilanc inspirieren lassen, vielleicht, um nur eine assoziative Karte des Maximums zu erstellenc Einträge (wo c ist eine Konstante), die einen Gegenstand mit der Häufigkeit verknüpft, mit der er gesehen wurde. Wenn die assoziative Karte voll ist und Sie auf ein neues Objekt stoßen, das nicht in der Karte enthalten ist, werfen Sie eine Münze, um es hinzuzufügen, oder nicht. Wenn Sie es hinzufügen möchten, entfernen Sie ein Element mit einer Wahrscheinlichkeit, die umgekehrt proportional zu der Häufigkeit ist, mit der es bisher gesehen wurde.
quelle
Ich habe AVL-Bäume (und manchmal rot-schwarze) mit Teilelementen verwendet, um als Filter ohne falsche Negative zu fungieren. Verwenden Sie nur die ersten X Bytes des Elements, wenn Sie den Baum einfügen oder abfragen. Da die Datenstruktur in ihrer Form nicht probabilistisch ist, besteht nicht die Gefahr eines Fehlalarms durch Bitkollision. Und im Gegensatz zum Zwischenspeichern des gesamten Elements erhalten Sie auf diese Weise einen kalkulierbaren maximalen Speicherplatz. Sie können die Rate falsch positiver Ergebnisse optimieren, indem Sie unterschiedliche Präfixlängen / Baumtiefen im Vergleich zu den Kosten für falsch positive Ergebnisse und Speicherplatz berücksichtigen.
quelle
Ich denke, man kann eine Untergrenze beweisen, die besagt, dass die obige Datenstruktur nicht existieren kann. Wenn die Datenstruktur m Bits verwendet, kann ein fester Bitvektor (Darstellung einer Eingabe) im Grunde höchstens (((un) + n eps) \ choose (un)) Mengen durch ein Zählargument entsprechen. Da das 2 ^ m-fache dieser Zahl mindestens (u \ choose n) sein muss (alle Mengen müssen dargestellt werden), erhalten wir eine Untergrenze, die im Grunde der genauen Speicherung der Menge S sehr nahe kommt.
quelle