Предположим, вы создаете учетную запись в Geekbook, хотите ввести классное имя пользователя, вы ввели его и получили сообщение «Имя пользователя уже занято». Вы добавили свою дату рождения вместе с именем пользователя, но все равно не повезло. Теперь вы также добавили номер своего университетского списка и получили «Имя пользователя уже занято». Это действительно расстраивает, не так ли?
Но вы когда-нибудь задумывались, как быстро Geekbook проверяет доступность имени пользователя, выполняя поиск по миллионам зарегистрированных пользователей. Есть много способов сделать эту работу —
- Линейный поиск : плохая идея!
- Бинарный поиск : сохраняйте все имена пользователей в алфавитном порядке и сравнивайте введенное имя пользователя со средним в списке. Если оно совпадает, то используется имя пользователя, в противном случае выясняется, будет ли введенное имя пользователя идти до или после среднего и, если оно будет после, пренебречь всеми именами пользователей до середины (включительно). Теперь ищите после среднего и повторяйте этот процесс, пока не получите совпадение или конец поиска без совпадения. Этот метод лучше и перспективнее, но все же требует нескольких шагов.
Но должно быть что-то лучше!
Bloom Filter — это структура данных, которая может выполнять эту работу.
Для понимания фильтров Блума, вы должны знать, что такое хэширование . Хеш-функция принимает входные данные и выводит уникальный идентификатор фиксированной длины, который используется для идентификации входных данных.
Что такое Bloom Filter?
Фильтр Блума — это компактная вероятностная структура данных, которая используется для проверки того, является ли элемент членом набора. Например, проверка доступности имени пользователя задается проблемой членства, где набор представляет собой список всех зарегистрированных имен пользователей. Цена, которую мы платим за эффективность, заключается в том, что она носит вероятностный характер, что означает, что могут быть некоторые ложноположительные результаты. Ложное положительное значение может означать , что данное имя пользователя уже занято, но на самом деле это не так.
Интересные свойства Bloom Filters
- В отличие от стандартной хеш-таблицы, фильтр Блума фиксированного размера может представлять набор с произвольно большим количеством элементов.
- Добавление элемента никогда не завершится неудачей. Однако частота ложных срабатываний постоянно увеличивается по мере добавления элементов, пока все биты в фильтре не будут установлены в 1, после чего все запросы дают положительный результат.
- Фильтры Блума никогда не генерируют ложно-отрицательный результат, т. Е. Сообщают вам, что имя пользователя не существует, когда оно действительно существует.
- Удаление элементов из фильтра невозможно, потому что, если мы удаляем один элемент путем очистки битов по индексам, сгенерированным k хэш-функциями, это может привести к удалению нескольких других элементов. Пример — если мы удалим «geeks» (в приведенном ниже примере), очистив биты в 1, 4 и 7, мы можем в конечном итоге удалить также «nerd», поскольку бит с индексом 4 становится равным 0, а фильтр Bloom утверждает, что «nerd» не является настоящее время.
Работа фильтра Блума
Пустой фильтр Блума — это битовый массив из m битов, все установлены в ноль, например:
Нам нужно k количество хеш-функций для вычисления хешей для данного входа. Когда мы хотим добавить элемент в фильтр, устанавливаются биты при k индексах h1 (x), h2 (x),… hk (x), где индексы рассчитываются с использованием хеш-функций.
Пример. Предположим, что мы хотим ввести «гиков» в фильтр, мы используем 3 хеш-функции и битовый массив длиной 10, изначально все они установлены в 0. Сначала мы вычислим хэши следующим образом:
h1(“geeks”) % 10 = 1 h2(“geeks”) % 10 = 4 h3(“geeks”) % 10 = 7
Примечание: эти результаты являются случайными только для объяснения.
Теперь мы установим биты на индексы 1, 4 и 7 на 1
Мы снова хотим ввести «ботаник», так же мы будем вычислять хэши
h1(“nerd”) % 10 = 3 h2(“nerd”) % 10 = 5 h3(“nerd”) % 10 = 4
Установите биты в индексах 3, 5 и 4 в 1
Теперь, если мы хотим проверить, есть ли «гики» в фильтре или нет. Мы сделаем тот же процесс, но на этот раз в обратном порядке. Мы вычисляем соответствующие хэши, используя h1, h2 и h3, и проверяем, установлены ли все эти индексы в 1 в битовом массиве. Если все биты установлены, то мы можем сказать, что «гики», вероятно, присутствуют . Если какой-либо из битов этих индексов равен 0, то «гиков» определенно нет .
Ложный позитив в фильтрах Блума
Вопрос в том, почему мы сказали «вероятно, присутствует» , почему эта неопределенность. Давайте разберемся с этим на примере. Предположим, мы хотим проверить, присутствует «кошка» или нет. Мы будем вычислять хэши, используя h1, h2 и h3
h1(“cat”) % 10 = 1 h2(“cat”) % 10 = 3 h3(“cat”) % 10 = 7
Если мы проверим битовый массив, биты этих индексов будут установлены в 1, но мы знаем, что «cat» никогда не добавлялся в фильтр. Бит по индексам 1 и 7 был установлен, когда мы добавили «гиков», а бит 3 был установлен, мы добавили «ботаник».
Таким образом, поскольку биты в вычисленных индексах уже установлены каким-либо другим элементом, фильтр Блума ошибочно утверждает, что присутствует «кот» и генерирует ложноположительный результат. В зависимости от приложения, это может быть огромным недостатком или относительно хорошо.
Мы можем контролировать вероятность получения ложного срабатывания, контролируя размер фильтра Блума. Больше места означает меньше ложных срабатываний. Если мы хотим уменьшить вероятность ложноположительного результата, мы должны использовать большее количество хеш-функций и больший массив битов. Это добавило бы задержку в дополнение к пункту и проверке членства.
Вероятность ложной положительности: Пусть m будет размером битового массива, k будет числом хеш-функций и n будет числом ожидаемых элементов, которые будут вставлены в фильтр, тогда вероятность ложноположительного значения p можно рассчитать как:
Размер битового массива: если ожидаемое количество элементов n известно и желаемая вероятность ложного положительного результата равна p, то размер битового массива m можно рассчитать как:
Оптимальное количество хеш-функций: количество хеш-функций k должно быть положительным целым числом. Если m — это размер битового массива, а n — количество элементов, которые нужно вставить, то k можно рассчитать как:
Космическая эффективность
Если мы хотим , чтобы хранить большой список элементов в наборе для целей членства набора, мы можем хранить его в HashMap , пытается или простой массив или связанный список . Все эти методы требуют хранения самого элемента, что не очень эффективно для памяти. Например, если мы хотим сохранить «гиков» в hashmap, мы должны сохранить фактическую строку «гиков» в виде пары «ключ-значение» {some_key: «geeks»}.
Фильтры Блума не хранят элемент данных вообще. Как мы уже видели, они используют битовый массив, который допускает коллизию хешей. Без столкновения хэшей это не было бы компактно.
Выбор хеш-функции
Хеш-функция, используемая в фильтрах Блума, должна быть независимой и равномерно распределенной. Они должны быть максимально быстрыми. Быстрые простые некриптографические хеши, которые достаточно независимы, включают ропот , ряд хэш-функций FNV и хеш-функции Дженкинса .
Генерация хэша является основной операцией в фильтрах Блума. Криптографические хеш-функции обеспечивают стабильность и гарантию, но дороги в расчете. С увеличением числа хеш-функций k фильтр Блума становится медленным. Несмотря на то, что некриптографические хеш-функции не гарантируют, а обеспечивают значительное улучшение производительности.
Базовая реализация класса Bloom Filter в Python3. Сохранить как bloomfilter.py
|
Давайте проверим фильтр Блума. Сохраните этот файл как bloom_test.py
|
Выход
Size of bit array:124
False positive Probability:0.05
Number of hash functions:4
'war' is definitely not present!
'gloomy' is definitely not present!
'humanity' is definitely not present!
'abundant' is probably present!
'bloom' is probably present!
'coherent' is probably present!
'cohesive' is probably present!
'bluff' is definitely not present!
'bolster' is probably present!
'hate' is definitely not present!
'racism' is definitely not present!
'bonus' is probably present!
'abounds' is probably present!
'genial' is probably present!
'geeksforgeeks' is definitely not present!
'nuke' is definitely not present!
'hurt' is definitely not present!
'twitter' is a false positive!
'cheater' is definitely not present!
'generosity' is probably present!
'facebook' is definitely not present!
'abundance' is probably present!
Применение фильтров Блума
- Средний использует фильтры Блума для рекомендации пользователям постов путем фильтрации постов, которые просматривал пользователь.
- Quora внедрила общий фильтр Блума в бэкэнд-канал, чтобы отфильтровать истории, которые люди видели раньше.
- В веб-браузере Google Chrome использовался фильтр Блума для выявления вредоносных URL-адресов.
- Google BigTable, Apache HBase и Apache Cassandra, а также Postgresql используют фильтры Блума, чтобы уменьшить количество обращений к диску для несуществующих строк или столбцов.
Ссылки
- https://en.wikipedia.org/wiki/Bloom_filter
- https://blog.medium.com/what-are-bloom-filters-1ec2a50c68ff
- https://www.quora.com/What-are-the-best-applications-of-Bloom-filters
Эта статья предоставлена Атулом Кумаром . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
- Random Walk (реализация в Python)
- Реализация дерева решений с использованием Python
- Python | Реализация полиномиальной регрессии
- Реализация динамического массива в Python
- Линейная регрессия (реализация Python)
- Python | Внедрение системы рекомендации фильмов
- Игра жизни Конвея (реализация Python)
- Интересная реализация Python для следующих больших элементов
- Python-реализация автоматической игры в крестики-нолики с использованием случайного числа
- ML | Алгоритм обучения подкреплению: реализация Python с использованием Q-обучения
- Python | Введение в Matplotlib
- Введение в свертки с использованием Python
- Многопроцессорная обработка в Python | Комплект 1 (Введение)
- Введение в язык Python
- Python | Введение в PyQt5
0.00 (0%) 0 votes