Definition · A Bloom filterA Bloom filter for a set is an array of m bits, initially all clear, together with k hash functions into 0..m − 1. To insert x, set the bits h₁(x), …, hₖ(x). To query x, report present if all k of those bits are set and absent otherwise. The structure stores no keys.
That last sentence is the point of it. Sixteen keys at ten bits each is 160 bits — twenty bytes — for a set that would take at least sixteen machine words to store exactly. The saving is what the false-positive rate is paid for, and the rate is what this lesson computes.
Theorem · The false-positive rateSuppose n keys have been inserted into m bits with k hash functions, each of the kn settings choosing a bit uniformly at random and independently. Then a key that was never inserted is reported present with probability (1 − (1 − 1/m)^{kn})^k.
Fix a bit. Each of the kn settings misses it with probability 1 − 1/m, and the settings are independent, so the bit is clear with probability (1 − 1/m)^{kn} and set with probability 1 − (1 − 1/m)^{kn}.
A query on an absent key reports present exactly when all k of its bits are set. Treating those k events as independent gives the product, which is the k-th power.
□
The second step is where the honesty is required. The k bits of a query are not independent: knowing that one of them is set is mild evidence that the filter is full, which makes the others more likely to be set too. So the expression above is itself an idealisation of the truth for a real filter, and this library's arithmetic computes it exactly as the expression it is, while labelling the further e^{−kn/m} step as approximate. The lab's measured column — the false positives an actual filter returned — is the only figure on the page with no model in it.
Example · Sixteen keys, ten bits each, seven hashesm = 160, n = 16, k = 7. The exact rate is 0.008319, which the panel also prints as about 1 in 120. The idealised (1 − e^{−kn/m})^k gives 0.008194, a difference of 1.25 × 10⁻⁴. The filter the lab built set 74 of its 160 bits and returned 1 false positive in 200 queries of keys it had never seen.
Three numbers again, in the shape this course has used throughout. 0.008319 is exact under the stated model. 0.008194 is an approximation of it and is labelled. 1 of 200 is a measurement on one filter with one seed, and 200 queries cannot resolve a rate of one in 120 — the expected number of false positives in 200 queries is about 1.66, so 1 is unremarkable and so would 0 or 4 be.
Choosing k, by scanning rather than by a rule of thumb
More hash functions set more bits, which raises the chance that any given bit is set, and they also require more bits to be set for a false positive, which lowers it. The two effects compete and there is an optimum. The usual rule is k* = (m/n)·ln 2, which at ten bits per key suggests 6.93. The panel does not use it: it evaluates the exact rate at every k from 1 to 10 and reports the smallest.
m = 160, n = 16 exact rate by k
k = 1 0.095446 k = 6 0.008553
k = 2 0.033045 k = 7 0.008319 <- the best
k = 3 0.017551 k = 8 0.008595
k = 4 0.011934 k = 9 0.009287
k = 5 0.009545 k = 10 0.010373
The curve is flat near its minimum — k = 6, 7 and 8 are within four per cent of each other — and it climbs sharply on the left. So under-hashing is expensive and over-hashing is cheap, which is worth knowing when the rule of thumb lands between two integers. At twelve keys and twelve bits each the panel's scan puts the optimum at k = 8 with a rate of 0.003204, and a filter running at k = 10 there pays 0.003414 — six per cent worse for 25 per cent more work.
The operation that does not exist
A Bloom filter cannot delete. Clearing the k bits of a removed key would clear bits that other keys had set, and those keys would then be reported absent — a false negative, which is the one answer the structure exists never to give. The one-sided error is the whole guarantee, and deletion would destroy it rather than degrade it.
That is also why the structure is used where a certain no is what matters: a cheap pre-filter in front of an expensive lookup. Storage Engines and Indexes, on the System Design path, puts one in front of a disk read for exactly that reason, and the consequence of a false positive there is a wasted read rather than a wrong answer.
The rate is a design parameter and it is computable in advance, which is the unusual thing about this structure. Choose the bits per key and k and the false-positive rate follows exactly; there is no measurement to run and no instance-dependence to worry about. What must not happen is quoting the idealised figure as the rate when the exact one is available, or quoting either without saying which.