Позвольте мне попытаться дать этому шанс, чтобы увидеть, насколько я могу убить его. :-)
Итак, для начала вам нужно иметь возможность создать регулярный фильтр Блума, который допускает конечное число элементов с максимальной вероятностью ложного срабатывания. Добавление этих функций в базовый фильтр необходимо, прежде чем пытаться создать масштабируемую реализацию.
Прежде чем мы попытаемся контролировать и оптимизировать вероятность, давайте выясним, какова вероятность для данного размера фильтра Блума.
Сначала мы разбиваем битовое поле на количество хеш-функций (общее количество бит / количество хеш-функций = срезы), чтобы получить k срезов битов, которые представляют каждую хеш-функцию, поэтому каждый элемент всегда описывается k битами.
Если вы увеличите количество срезов или количество битов на срез, вероятность ложных срабатываний уменьшится.
Из этого также следует, что при добавлении элементов для большего количества битов устанавливается значение 1, поэтому ложные срабатывания увеличиваются. Мы называем это «коэффициент заполнения» каждого среза.
Когда фильтр содержит большой объем данных, мы можем предположить, что вероятность ложных срабатываний для этого фильтра - это коэффициент заполнения, увеличенный до количества срезов (если бы нам нужно было фактически считать биты вместо использования отношения, это упрощается в перестановка с проблемой повторения).
Итак, как нам выяснить, как выбрать вероятность ложных срабатываний в фильтре Блума? Мы можем изменить количество срезов (что повлияет на коэффициент заполнения).
Чтобы выяснить, сколько ломтиков у нас должно быть, мы начнем с определения оптимального коэффициента заполнения для ломтика. Поскольку коэффициент заполнения определяется количеством битов в срезе, равным 1, по сравнению с количеством битов, равным 0, мы можем определить, что каждый бит останется неустановленным с вероятностью (100% - (1 / бит в срезе) ). Поскольку мы собираемся вставить несколько элементов, у нас есть еще одна перестановка с проблемой репутации, и мы расширяем вещи до ожидаемого коэффициента заполнения, который равен (100% - ((100% - (1 / бит в срезе)) ^ "элементы вставлены")). Что ж, получается, что это очень похоже на другое уравнение. В статье они связывают коэффициент заполнения с другим уравнением, поэтому оно хорошо вписывается в ряд Тейлора (1-e ^ (- n / m)). После небольшого возмущения получается, что оптимальный коэффициент заполнения всегда составляет около 50%,
Таким образом, поскольку вероятность фильтра - это коэффициент заполнения, увеличенный до количества срезов, мы можем заполнить 50% и получить P = (50%) ^ k или k = log_2 (1 / P). Затем мы можем использовать эту функцию для вычисления количества срезов, которые мы должны сгенерировать для данного фильтра в списке фильтров для масштабируемого фильтра Блума.
def slices_count(false_positive_probability):
return math.ceil(math.log(1 / false_positive_probability, 2))
Редактирование: После написания этого я столкнулся с упоминанием о «правиле пятидесяти процентов» при чтении динамического распределения памяти на основе системы друзей в TAoCP Vol 1, стр. 442-445, с более чистыми рассуждениями по сравнению с подгонкой кривой к (1 -e ^ (- п / м)). Кнут также ссылается на статью «Пересмотрено правило пятидесяти процентов» с небольшим фоном концепции ( pdf доступен здесь ).