Quel est l'avantage d'utiliser des filtres de floraison?


108

Je lis sur les filtres de floraison et ils semblent juste idiots. Tout ce que vous pouvez accomplir avec un filtre de floraison, vous pouvez le faire dans moins d'espace, plus efficacement, en utilisant une seule fonction de hachage plutôt que plusieurs, ou c'est ce qu'il semble. Pourquoi utiliser un filtre de floraison et en quoi est-il utile?


5
avez-vous lu l'article de wikipedia? Cela explique assez bien les avantages. en.wikipedia.org/wiki/Bloom_filter
Alex Budovski

@david cela semble peu probable, cependant. Les fonctions de hachage k dans un espace constant auront beaucoup plus de collisions qu'une seule fonction de hachage dans un espace constant.
mal de tête

1
@Alex J'ai lu l'article de wikipedia. Je comprends ce qui est dit là-bas, mais je ne comprends pas pourquoi c'est mieux. Pourquoi cela fonctionne est intuitif. Pourquoi c'est utile ne l'est pas.
mal de tête

Cet écrivain fait un excellent travail avec michaelnielsen.org/ddi/why-bloom-filters-work-the-way-they-do
dranxo

2
@dranxo, l'article lié jasondavies.com/bloomfilter est meilleur.
Pacerier

Réponses:


155

De Wikipedia :

Les filtres Bloom ont un fort avantage d'espace par rapport aux autres structures de données pour représenter des ensembles, tels que les arbres de recherche binaires auto-équilibrés, les essais, les tables de hachage ou les tableaux simples ou les listes liées des entrées. La plupart d'entre eux nécessitent de stocker au moins les éléments de données eux-mêmes, ce qui peut nécessiter n'importe où d'un petit nombre de bits, pour les petits entiers, à un nombre arbitraire de bits, comme pour les chaînes (les essais sont une exception, car ils peuvent partager le stockage entre éléments avec des préfixes égaux). Les structures liées entraînent une surcharge d'espace linéaire supplémentaire pour les pointeurs. Un filtre Bloom avec une erreur de 1% et une valeur optimale de k, en revanche, ne nécessite qu'environ 9,6 bits par élément - quelle que soit la taille des éléments. Cet avantage vient en partie de sa compacité, héritée des tableaux, et en partie de sa nature probabiliste. Si un taux de faux positifs de 1% semble trop élevé, chaque fois que nous ajoutons environ 4,8 bits par élément, nous le diminuons de dix fois.

Assez clair pour moi.

Un filtre de floraison ne stocke pas les éléments eux-mêmes, c'est le point crucial. Vous n'utilisez pas de filtre de floraison pour tester si un élément est présent, vous l'utilisez pour tester s'il n'est certainement pas présent, car il ne garantit aucun faux négatif. Cela vous permet de ne pas effectuer de travail supplémentaire pour les éléments qui n'existent pas dans un ensemble (comme les E / S disque pour les rechercher).

Et le tout dans beaucoup moins d'espace que quelque chose comme une table de hachage (qui sera probablement partiellement sur le disque pour les grands ensembles de données). Bien que vous puissiez utiliser un filtre de floraison en conjonction avec une structure comme une table de hachage, une fois que vous êtes certain que l'élément a une chance d'être présent.

Ainsi, un exemple de modèle d'utilisation pourrait être:

Vous avez beaucoup de données sur le disque - vous décidez de la borne d'erreur que vous voulez (par exemple 1%), qui prescrit la valeur de m . Alors le k optimal est déterminé (à partir de la formule donnée dans l'article). Vous remplissez votre filtre à partir de ces données liées au disque une fois.

Vous avez maintenant le filtre en RAM. Lorsque vous devez traiter un élément, vous interrogez votre filtre pour voir s'il a une chance d'exister dans votre ensemble de données. Si ce n'est pas le cas, aucun travail supplémentaire n'est effectué. Aucune lecture de disque, etc. (ce que vous auriez à faire s'il s'agissait d'un hachage ou d'un arbre, etc.).

Sinon, si le filtre dit "Oui, c'est là-dedans", il y a 1% de chances que ce soit faux, donc vous faites le travail nécessaire pour le découvrir. 99% du temps, ce sera vraiment là, donc le travail n'était pas pour rien.


2
Si c'est clair, veuillez répondre. Comment cela pourrait-il être plus efficace en termes d'espace qu'une seule fonction de hachage sur le même ensemble de taille? Cela créera simplement plus de collisions. Vous passerez à la recherche sur des fonctions de hachage distinctes pour vous assurer d'avoir un 1 à toutes les fonctions de hachage. Je ne comprends pas son avantage par rapport à l'utilisation d'une seule fonction de hachage.
mal de tête

19
Une fonction de hachage est du code, pas des données. Avec quoi avez-vous l'intention d'utiliser la fonction de hachage? Une table de hachage? Dans ce cas, votre table devra stocker des clés, qui peuvent être de taille arbitraire, contrairement à un filtre de floraison. L'extrait le mentionne.
Alex Budovski

3
Considérons un filtre de floraison avec une seule fonction de hachage, plutôt que k. Quel est l'avantage d'ajouter plus de fonctions de hachage? Cela créera simplement plus de collisions. Ou ai-je tort?
mal de tête

2
Cela est répondu par le dernier paragraphe dans «Avantages spatiaux et temporels» de l'article de Wikipédia, et la section «Probabilité de faux positifs».
Alex Budovski

4
Il a juste cliqué. Merci beaucoup, cela me dérange depuis un moment. Cela diminue le nombre de faux positifs car un faux positif devrait soit a) être une collision sur toutes vos fonctions de hachage ou b) tous les espaces ont été remplis par d'autres valeurs. Le choix de la taille doit donc être un processus délicat, je suppose. Corrigez-moi si je me trompe, mais je pense que je comprends. Merci à tous.
mal de tête

156

Alex l'a assez bien expliqué. Pour ceux qui n'ont toujours pas bien compris, j'espère que cet exemple vous aidera à comprendre:

Disons que je travaille pour Google, dans l'équipe Chrome, et que je souhaite ajouter une fonctionnalité au navigateur qui avertit l'utilisateur si l'URL qu'il a saisie est une URL malveillante. J'ai donc un ensemble de données d'environ 1 million d'URL malveillantes, la taille de ce fichier étant d'environ 25 Mo. Comme la taille est assez grande (grande par rapport à la taille du navigateur lui-même), je stocke ces données sur un serveur distant.

Cas 1: j'utilise une fonction de hachage avec une table de hachage. Je décide d'une fonction de hachage efficace et j'exécute tous les 1 million d'URL via la fonction de hachage pour obtenir des clés de hachage. Je crée ensuite une table de hachage (un tableau), où la clé de hachage me donnerait l'index pour placer cette URL. Alors maintenant, une fois que j'ai haché et rempli la table de hachage, je vérifie sa taille. J'ai stocké les 1 million d'URL dans la table de hachage avec leurs clés. La taille est donc d'au moins 25 Mo. Cette table de hachage, en raison de sa taille, sera stockée sur un serveur distant. Lorsqu'un utilisateur arrive et entre une URL dans la barre d'adresse, je dois vérifier si elle est malveillante. Ainsi, j'exécute l'URL via la fonction de hachage (le navigateur lui-même peut le faire) et j'obtiens une clé de hachage pour cette URL. Je dois maintenant faire une demande à mon serveur distant avec cette clé de hachage, pour vérifier si l'URL particulière dans ma table de hachage avec cette clé particulière, est la même que ce que l'utilisateur a entré. Si oui, c'est malveillant et si non, ce n'est pas malveillant. Ainsi à chaque fois que l'utilisateur saisit une URL, une requête au serveur distant doit être faite pour vérifier s'il s'agit d'une URL malveillante. Cela prendrait beaucoup de temps et ralentirait ainsi mon navigateur.

Cas 2: j'utilise un filtre à fleurs. La liste entière de 1 million d'URL est exécutée à travers le filtre de floraison à l'aide de plusieurs fonctions de hachage et les positions respectives sont marquées comme 1, dans un énorme tableau de 0. Disons que nous voulons un taux de faux positifs de 1%, en utilisant un calculateur de filtre de bloom ( http://hur.st/bloomfilter?n=1000000&p=0.01), nous obtenons la taille du filtre de floraison requise comme seulement 1,13 Mo. Cette petite taille est attendue car, même si la taille du tableau est énorme, nous ne stockons que des 1 ou des 0 et non les URL comme dans le cas de la table de hachage. Ce tableau peut être traité comme un tableau de bits. Autrement dit, puisque nous n'avons que deux valeurs 1 et 0, nous pouvons définir des bits individuels au lieu d'octets. Cela réduirait l'espace occupé de 8 fois. Ce filtre de fleurs de 1,13 Mo, en raison de sa petite taille, peut être stocké dans le navigateur Web lui-même !! Ainsi, lorsqu'un utilisateur arrive et entre une URL, nous appliquons simplement les fonctions de hachage requises (dans le navigateur lui-même), et vérifions toutes les positions dans le filtre de floraison (qui est stocké dans le navigateur). Une valeur de 0 dans l'une des positions nous indique que cette URL n'est DEFINITIVEMENT PAS dans la liste des URL malveillantes et que l'utilisateur peut continuer librement. Ainsi, nous n'avons pas fait d'appel au serveur et donc gagné du temps. Une valeur de 1 nous indique que l'URL PEUT être dans la liste des URL malveillantes. Dans ces cas, nous appelons le serveur distant et là-bas, nous pouvons utiliser une autre fonction de hachage avec une table de hachage comme dans le premier cas pour récupérer et vérifier si l'URL est réellement présente. Étant donné que la plupart du temps, une URL n'est pas susceptible d'être malveillante, le petit filtre de floraison du navigateur le détecte et fait ainsi gagner du temps en évitant les appels au serveur distant. Seulement dans certains cas, si le filtre de floraison nous indique que l'URL PEUT être malveillante, seulement dans ces cas, nous faisons un appel au serveur. Ce «PEUT» est exact à 99%. Dans ces cas, nous appelons le serveur distant et là-bas, nous pouvons utiliser une autre fonction de hachage avec une table de hachage comme dans le premier cas pour récupérer et vérifier si l'URL est réellement présente. Étant donné que la plupart du temps, une URL n'est pas susceptible d'être malveillante, le petit filtre de floraison du navigateur le détecte et fait ainsi gagner du temps en évitant les appels au serveur distant. Seulement dans certains cas, si le filtre de floraison nous indique que l'URL PEUT être malveillante, seulement dans ces cas, nous faisons un appel au serveur. Ce «PEUT» est exact à 99%. Dans ces cas, nous appelons le serveur distant et là-bas, nous pouvons utiliser une autre fonction de hachage avec une table de hachage comme dans le premier cas pour récupérer et vérifier si l'URL est réellement présente. Étant donné que la plupart du temps, une URL n'est pas susceptible d'être malveillante, le petit filtre de floraison du navigateur le détecte et fait ainsi gagner du temps en évitant les appels au serveur distant. Seulement dans certains cas, si le filtre de floraison nous indique que l'URL PEUT être malveillante, seulement dans ces cas, nous faisons un appel au serveur. Ce «PEUT» est exact à 99%. le petit filtre de floraison dans le navigateur en tient compte et permet donc de gagner du temps en évitant les appels vers le serveur distant. Seulement dans certains cas, si le filtre de floraison nous indique que l'URL PEUT être malveillante, seulement dans ces cas, nous faisons un appel au serveur. Ce «PEUT» est exact à 99%. le petit filtre de floraison dans le navigateur en tient compte et permet donc de gagner du temps en évitant les appels vers le serveur distant. Seulement dans certains cas, si le filtre de floraison nous indique que l'URL PEUT être malveillante, seulement dans ces cas, nous faisons un appel au serveur. Ce «PEUT» est exact à 99%.

Ainsi, en utilisant un petit filtre de floraison dans le navigateur, nous avons gagné beaucoup de temps car nous n'avons pas besoin de faire des appels au serveur pour chaque URL saisie.

Nous pouvons voir que la table de hachage avec une seule fonction de hachage est utilisée dans un but complètement différent d'un filtre de floraison. Espérons que cela dissipe vos doutes :)

modifier :

J'ai implémenté un filtre de floraison pour la tâche de test d'URL malveillantes en Python. Le code peut être trouvé ici - https://github.com/tarunsharma1/Bloom-Filter Le code est très simple à comprendre et une description détaillée est fournie dans le fichier readme.


3
Merci pour un scénario d'utilisation.
Squiggs.

1
Je n'ai pas compris la partie de hachage et d'association d'une valeur de 0 ou 1. Si nous utilisons un tableau et stockons 0 et 1 dans ceux-ci, comment rechercher la valeur de hachage d'une URL lorsque nous effectuons le test ?
divinedragon

1
Donc, fondamentalement, nous utilisons quelque chose appelé une fonction de hachage..qui prend l'URL sous forme de chaîne..et donne un nombre..nous utilisons ce nombre et définissons la valeur d'index du tableau correspondant à 1. Un certain nombre de fonctions de hachage différentes existent, mais ce qui est important, c'est qu'à chaque fois que la même URL est passée par une fonction de hachage, elle doit générer le même numéro. Un exemple de fonction de hachage pourrait être d'additionner les valeurs ascii de tous les caractères d'une URL. Dans les filtres Bloom, nous utilisons de nombreuses fonctions de hachage et définissons toutes ces valeurs d'index de tableau sur 1. J'espère que cela a dissipé votre doute.
Tarun

1
Une table de hachage conventionnelle telle que C # HashSet<String>utilisera 16 octets par élément d'élément dans le meilleur des cas dans lequel la table de hachage est complètement pleine: 4 octets mappent d'un «compartiment» à une entrée dans une table d'entrées (un tableau contenant des liens simples list), 4 octets pour le hashcode mis en cache, 4 octets pour le pointeur "suivant", 4 octets pour un pointeur vers la clé. Et c'est sans compter les tailles de chaîne. Dans le pire des cas, c'est 40 octets: la moitié des entrées sont inutilisées et 20 octets par entrée une fois que le Stringpointeur se développe à 8 octets pour les architectures 64 bits.
Qwertie

Vous n'avez pas à enregistrer la chaîne elle-même dans le jeu de hachage. Vous pouvez enregistrer le hachage en tant que valeur, ce qui rend le hachage beaucoup plus petit. Ensuite, vous pouvez jouer avec la taille de hachage - plus elle est grande, plus le taux de faux positifs sera petit.
user1028741

24

Je vais commencer par expliquer ce qu'est un filtre de floraison, ce qu'il peut et ne peut pas faire, pourquoi en avons-nous besoin, montrer une description intuitive de son fonctionnement, puis donner un exemple quand ils peuvent être utiles.

Ainsi, un filtre de bloom standard est une structure de données probabiliste qui peut * :


  • ajouter un élément à un ensemble
  • vérifier si un élément est dans l'ensemble en disant definitely not in the setoupossibly in the set

C'est possibly in the setexactement pourquoi il est appelé probabiliste. En utilisant des mots intelligents, cela signifie que le faux positif sont possibles (il peut y avoir des cas où il pense à tort que l'élément est positif) mais que les faux négatifs sont impossibles.

Mais ça ne peut pas * :

  • supprimer un élément de l'ensemble
  • vous donner une liste de tous les éléments qui sont actuellement dans votre ensemble

* Cet ensemble de can / can't est pour un filtre de floraison de base. Comme il s'agit d'une structure de données utile qui a été créée il y a longtemps, les gens ont trouvé comment l' augmenter avec d'autres fonctionnalités utiles .


Mais attendez une minute: nous connaissons déjà une structure de données qui peut répondre à tout cela sans vague «possible» et aussi sans toutes les limitations (impossible de supprimer, de tout afficher). Et cela s'appelle un ensemble . Et voici un avantage principal d'un filtre de floraison: il est peu encombrant et constant dans l'espace .

Cela signifie que peu importe le nombre d'éléments stockés là-bas, l'espace sera le même. Oui, un filtre de floraison avec des 10^6éléments (filtre de floraison inutile) prendra la même quantité d'espace qu'un filtre de floraison avec des 10^20éléments et le même espace qu'un filtre de floraison avec des 0éléments. Alors, combien d'espace cela prendra-t-il? C'est à vous de décider (mais il y a un échange de: plus vous avez d'éléments, plus vous êtes incertain avec votre possible in the setréponse.

Une autre chose intéressante est que c'est une constante d'espace. Lorsque vous enregistrez les données dans un ensemble, vous devez réellement enregistrer ces données. Donc, si vous stockez, this long string in the setvous devez utiliser au moins 27 octets d'espace. Mais pour une erreur de 1% et une valeur optimale de k ** , vous aurez besoin d'environ 9,6 bits (<2 octets) par élément (qu'il s'agisse d'un int court ou d'un énorme mur de texte).

Une autre propriété est que toutes les opérations prennent un temps constant, ce qui n'est absolument pas le même que le temps constant amorti dans le cas des ensembles (rappelez-vous que si l'ensemble a des collisions, il peut se détériorer dans le O(n)temps).

** k est une valeur des fonctions de hachage utilisées dans le filtre bloom


Je ne décrirai pas le fonctionnement des filtres de floraison (l'article de wikipedia fait un très bon travail pour tout expliquer). Ici, je vais juste dire brièvement les bases.

  • vous lancez un tableau de bits vide de longueur m
  • vous sélectionnez kdifférentes fonctions de hachage (plus elles sont indépendantes, mieux c'est)
  • si vous souhaitez ajouter un élément, vous calculez tous les khachages de cette valeur et définissez les bits correspondants sur 1
  • si vous voulez vérifier si l'élément existe, vous calculez également tous les khachages et si au moins l'un d'entre eux n'est pas défini, il n'est sûrement pas dans l'ensemble. Sinon, il peut être dans l'ensemble.

Même cette description est suffisante pour comprendre pourquoi nous ne pouvons pas être sûrs (vous pouvez obtenir tous les bits définis à partir de diverses autres valeurs). Voici une très belle visualisation de son fonctionnement .

entrez la description de l'image ici


Alors, quand les filtres de floraison peuvent-ils être utiles? La réponse courte est partout où les faux positifs sont acceptables et où vous voudriez vérifier si quelque chose se trouve dans l'ensemble , mais même s'ils ne le sont pas, cela peut être une première ligne de défense pour écarter les appels coûteux aux vérificateurs.

Voici une liste de descriptions plus concrètes:

  • un exemple standard de sites Web malveillants et d'un navigateur est décrit dans presque tous les endroits où les gens parlent de filtres de floraison
  • est un mot de passe faible: au lieu d'avoir un énorme ensemble de tous les mots de passe faibles possibles, vous pouvez simplement vérifier si le mot de passe n'est sûrement pas faible avec un filtre de floraison beaucoup plus petit
  • si vous avez une liste d'articles et une liste d'utilisateurs, vous pouvez utiliser le filtre Bloom pour afficher les articles des utilisateurs qu'ils n'ont pas lus. Ce qui est intéressant, c'est que vous ne pouvez avoir qu'un seul filtre (vous vérifiez si la combinaison user_id + article_id est là)
  • Bitcoin utilise un filtre de floraison pour la synchronisation du portefeuille
  • Les serveurs Web d'Akamai utilisent des filtres Bloom pour empêcher les "one-hit-wonder" d'être stockées dans ses caches de disque. Les merveilles à un coup sont des objets Web demandés par les utilisateurs une seule fois, ce qu'Akamai a trouvé appliqué à près des trois quarts de son infrastructure de mise en cache. L'utilisation d'un filtre Bloom pour détecter la deuxième demande d'un objet Web et la mise en cache de cet objet uniquement lors de sa deuxième demande empêche les merveilles à un coup de pénétrer dans le cache disque, ce qui réduit considérablement la charge de travail du disque et augmente les taux de succès du cache disque (tirés des exemples du filtre Bloom article sur wiki)

13

Les filtres Bloom sont très utiles en bioinformatique. Ils peuvent être plus efficaces en termes d'espace par rapport à l'utilisation d'un hachage normal, en particulier lorsque la taille des chaînes avec lesquelles vous travaillez peut être des centaines de millions de lettres avec un très petit alphabet, c'est-à-dire {A, G, T, C}. Ils sont généralement utilisés pour évaluer si un certain k-mer est présent ou absent dans un génome. Il y a un exemple d'un utilisé pour quelque chose de pertinent ici .

ÉDITER:

Les multiples fonctions de hachage sont utilisées pour minimiser les faux positifs. L'espoir est qu'entre toutes les fonctions de k-hachage, chaque valeur aura une signature unique dans le tableau de bits par rapport à toutes les autres valeurs possibles. Cependant, les faux positifs existent, mais ils peuvent être réduits à un niveau gérable. En utilisant cette technique, vous hachez les éléments indépendamment de leur taille. Lorsque vous les recherchez, vous utilisez chaque fonction de hachage et vérifiez que leurs valeurs en bits sont toutes 1.

Comparez cela au génome humain, où une augmentation de la taille de l'élément augmente considérablement la taille de la table de hachage (la taille de la table est de 4 * 4 k ). Cela suppose que vous encodez les éléments en utilisant 2 bits / lettre.


1
Désolé, je ne comprends peut-être pas, mais comment peuvent-ils être plus efficaces en termes d'espace par rapport à un hachage ordinaire? Le hachage d'une chaîne est une sortie de longueur fixe, et vous définissez simplement cette valeur sur 0 ou 1. C'est également ce que feraient les filtres bloom, mais les filtres bloom le feraient sur plusieurs fonctions de hachage. Où suis-je mal compris?
mal de tête

Il n'est pas très utile de stocker un seul hachage. Ensuite, il n'aurait aucun moyen de gérer les collisions de hachage. La plupart des implémentations de table de hachage ont un moyen de gérer cela qui entraîne une surcharge. Les dictionnaires Python, par exemple, stockent la clé à côté du hachage et commencent à sonder de manière linéaire en cas de collision. Le filtre de floraison supprime cela et tente de minimiser les dommages inhérents à cette opération en utilisant plusieurs hachages.
Bret Fontecchio

1
Pourquoi ne pas créer un filtre de floraison mais avec une seule fonction de hachage? peut-être une fonction de hachage "relativement grande". Mais un au lieu de plusieurs
giorgim

7

Si un filtre Bloom renvoie qu'un élément est membre de l'ensemble, il y a une certaine probabilité pour un faux positif. Si une seule fonction de hachage était utilisée pour indiquer l'appartenance à l'ensemble, la probabilité d'un faux positif serait plus élevée que l'utilisation de plusieurs fonctions de hachage.


Besoin d'une élaboration sérieuse sur la viande de la réponse: " la probabilité d'un faux positif serait plus élevée que l'utilisation de plusieurs fonctions de hachage " ...
Pacerier
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.