布隆过滤器是一种以牺牲一部分正确率来换取空间复杂度的数据结构,其中误报指的是可能会判断不存在的元素为可能存在,但在判断不存在的元素时不会出现误报,即返回为True时元素可能存在,返回False时元素一定不存在。
下表是布隆过滤器的误报率,m为元素总个数,n为过滤器长度,k为hash函数的个数。
m/n | k | k=1 | k=2 | k=3 | k=4 | k=5 | k=6 |
---|---|---|---|---|---|---|---|
2 | 1.39 | 0.393 | 0.400 | ||||
3 | 2.08 | 0.283 | 0.237 | 0.253 | |||
4 | 2.77 | 0.221 | 0.155 | 0.147 | 0.160 | ||
5 | 3.46 | 0.181 | 0.109 | 0.092 | 0.092 | 0.101 | |
6 | 4.16 | 0.154 | 0.0804 | 0.0609 | 0.0561 | 0.0578 | 0.0638 |
7 | 4.85 | 0.133 | 0.0618 | 0.0423 | 0.0359 | 0.0347 | 0.0364 |
由表中数据可以得出误报率最小时k≈0.7m/n
import mmh3
from bitarray import bitarray
class BloomFilter:
def __init__(self, size, hash_count):
self._bit_size = size
self._bit = bitarray(self._bit_size)
self._hash_count = hash_count
def _get_hash_index(self, data):
return [mmh3.hash(str(data), i) % self._bit_size for i in range(self._hash_count)]
def add(self, data):
index_list = self._get_hash_index(data)
for index in index_list:
self._bit[index] = 1
def is_contains(self, data):
index_list = self._get_hash_index(data)
for index in index_list:
if self._bit[index] == 0:
return False
return True