Privacy Lab 04 — k-Anonymity Generalization

WARMUP: Chapters 7–8 (de-identification, k-anonymity).

The idea

Lab 02 measured k-anonymity; this lab achieves a target k. Each quasi-identifier has a generalization hierarchy (level 0 = exact 02138; coarser levels 0213*021***). You raise the global generalization level until every equivalence class has ≥ k records, optionally suppressing records still stuck in too-small classes — the classic generalization/suppression tradeoff between privacy (higher k) and utility (less detail).

What you build (lab.py)

  • equivalence_classes / k_anonymity — the grouping and achieved-k (self-contained).
  • generalize_record / generalize — apply each QI's hierarchy at a level (capped per QI).
  • max_level — the highest meaningful global level.
  • generalize_to_k(records, hierarchies, k) — the smallest level reaching k (best-effort if k is unreachable).
  • suppress_small_classes(records, qi, k) — drop records in classes < k; return (kept, suppressed).

Cases the tests cover

  • Level 0 is all-unique (k=1); level-1 generalization produces the expected coarse values (non-QI fields untouched, order preserved); generalize_to_k finds the minimum level for k=2, fully collapses for k=4, and returns a best-effort max level when k is unreachable; suppression removes exactly the small-class records.

Run

pip install -r requirements.txt
LAB_MODULE=solution pytest -q
pytest -q

Hardening / extensions

  • Implement Mondrian (multidimensional, per-partition generalization) instead of a uniform global level, and report information loss.
  • Add a suppression budget (suppress up to X% rather than all small classes).
  • Combine with Lab 02's l-diversity so generalization also guarantees sensitive-value diversity.

Interview / resume

"Built a generalization/suppression engine that achieves a target k-anonymity by raising quasi-identifier generalization levels and suppressing residual small classes — making the privacy/utility tradeoff explicit."

Limitations: uniform global generalization level (not per-partition Mondrian); no information-loss metric; hierarchies are supplied as callables.