Фільтр Блума (англ.Bloom filter) — заощадлива до пам'яті ймовірнісна структура даних, призначена для перевірки приналежності елементів до множини. Запропонована Бартоном Говардом Блумом (англ.Burton Howard Bloom) в 1970 році.
Допускає помилкові спрацювання, але пропуск події неможливий, тому фільтр Блума має 100 % потужність. Алгоритм дозволяє перевірити або «ймовірну приналежність до множини», або «точну не приналежність». Можна додавати нові елементи до множини, але не можна їх видаляти (хоча цю проблему можна вирішити «рахуючим» фільтром). Чим більше елементів у множині, тим вища ймовірність помилкового спрацювання.
Блум запропонував цей алгоритм для випадків, коли необхідно обробляти таку кількість даних, що звичайні алгоритми хешування потребуватимуть понад міру пам'яті. Як приклад, він навів алгоритм автоматичного перенесення слів зі словником 500 тисяч слів, 90 % яких підпадають під прості правила розбиття, а решта 10 % потребує повільного доступу до жорсткого диску для пошуку конкретних шаблонів розбиття. За умови достатнього обсягу оперативної пам'яті, звичайне хешування позбавило би потреби в зайвих зверненнях до жорсткого диску. Проте, якщо обсяг оперативної пам'яті обмежений, то фільтр Блума дозволяє позбутись більшості зайвих звернень і, при цьому, використовує менше пам'яті. Наприклад, при використанні лише 15 % пам'яті звичайного хеш-алгоритму, фільтр Блума позбувається 85 % запитів до жорсткого диску, що є варіантом 85-15 правила Парето[1].
Зазвичай, незалежно від кількості елементів в множині, достатньо не більше 10 біт на елемент для досягнення частки помилкового спрацювання в 1 %[2].
Опис алгоритму
Порожній фільтр Блума — це масив m біт, що мають значення 0. Також мають бути визначені kхеш-функцій, кожна з яких відображає або хешує елемент множини на одну з m позицій в масиві з рівномірним розподілом ймовірностей.
Аби додати елемент, слід обробити його k хеш-функціями і обчислити k позицій в масиві. Встановити значення біт в цих позиціях рівними 1.
Для перевірки присутності елемента в множині, його слід обробити кожною з k хеш-функцій та отримати k позицій в масиві. Якщо будь-який з біт на цих позиціях дорівнює 0, то елемент гарантовано не перебуває в множині. Якби елемент належав множині, то всі біти отримали б значення 1 при додаванні елемента до множини. Якщо всі біти мають значення 1, тоді або елемент належить множині, або ж біти отримали значення 1 при додаванні інших елементів, що призведе до помилкового спрацювання. Простий фільтр Блума не дозволяє уникнути помилкових спрацювань.
Задача створення k незалежних хеш-функцій може бути заскладною для великих k. Якщо хеш-функція обчислює якісні ключі з широким діапазоном значень, то можливо «розрізати» масив біт на k фрагментів. Як варіант, якщо хеш-функція використовує початкові значення, можна використати k різних початкових значень, або додати ці значення до ключа.
Прибрати елемент з простого фільтра Блума неможливо, оскільки пропуск подій неприпустимий. Якщо просто присвоїти значення 0 тим бітам, які отримані при хешування елемента, то будуть видалені інші елементи, хешування яких містить ці біти. Оскільки відсутня можливість перевірити, які іще елементи хешуються на ті самі біти, просте присвоєння 0 може призвести до пропуску подій.
Вилучення елементів з фільтра Блума можливо реалізувати з додатковим фільтром, в якому зберігатимуться вилучені елементи. Однак, помилкові спрацювання в додатковому фільтрі стануть пропусками подій в об'єднаному фільтрі, що може бути небажаним. При цьому, повернути раніше видалений елемент неможливо, оскільки цей елемент доведеться видаляти з додаткового фільтру.