Problem 92 · Data Engineering & Streaming
Count-Min Sketch
01Problem
Implement a Count-Min Sketch supporting add(item, count), estimate(item), and merge, sized from error epsilon and failure probability delta.
02Key insight
d hash rows of width w; add increments one counter per row and estimate takes the min. Estimates never undercount, and overcount by at most eps*N with probability 1-delta when w=ceil(e/eps), d=ceil(ln(1/delta)). Sketches with equal shape and seeds merge by elementwise addition.
03Solution
Try it first.
TimeO(d) per add/estimate
SpaceO(w*d)
tests.py · 3 passing
tests.pypython13 lines
import random
from collections import Counter
rng = random.Random(7)
stream = [int(rng.paretovariate(1.2)) % 1000 for _ in range(20000)]
truth = Counter(stream)
a, b = CountMinSketch.from_error(0.002, 0.01), CountMinSketch.from_error(0.002, 0.01)
for i, x in enumerate(stream):
(a if i % 2 else b).add(x)
a.merge(b)
eps_n = 0.002 * len(stream)
assert all(a.estimate(k) >= v for k, v in truth.items()) # never undercounts
assert sum(a.estimate(k) - v > eps_n for k, v in truth.items()) <= 0.02 * len(truth)
assert a.estimate("never-seen") <= eps_n04Staff-level follow-up
Low-frequency items get large relative error - how do you improve it? Use conservative update (only raise counters that equal the current min), or pair the sketch with a small exact heap of heavy hitters; CMS is for heavy-hitter-ish point queries, not the long tail.