Módulo 3: Privacy and Data Protection Fundamentals
3. Anonymization vs Pseudonymization
Descripción de la cápsula
Cuando data minimization no alcanza (necesitás algunos datos), la siguiente capa es transformar los datos para reducir privacy risk:
- Pseudonymization: reversible. Reemplazás identifiers con codes; podés reverse con clave.
- Anonymization: irreversible. Una vez aplicada, no podés identificar al individuo original.
Esta cápsula cubre:
- Definiciones formales y diferencias técnicas.
- Cuándo cada una aplica.
- Re-identification attacks — por qué anonymization perfecta es difícil.
- K-anonymity, L-diversity, T-closeness — técnicas progresivamente robustas.
- Differential Privacy — el gold standard.
- Aplicación a AI: cuándo anonymizar training data y trade-offs.
Al terminar, vas a poder elegir la técnica apropiada para tu data y entender sus limitations.
Pseudonymization
Definición
Reemplazar identifiers personales con pseudónimos (códigos opacos). Mantenés una mapping table que permite reverse el proceso si tenés la key.
Real: Pseudonymized:
maria@gmail.com → user_42af8b2
2024-03-15 → 2024-03-15 (unchanged)
NYC → NYC (unchanged)
Solo el email se reemplazó. Resto del data permanece.
Implementación simple
import hashlib
def pseudonymize_email(email, secret_key):
"""
Pseudonymize email manteniendo deterministic mapping.
Same email → always same pseudonym (joinable).
"""
combined = f"{email}{secret_key}"
hash_obj = hashlib.sha256(combined.encode())
return f"user_{hash_obj.hexdigest()[:16]}"
# Uso
secret_key = load_secret_from_env() # never commit!
pseudonym = pseudonymize_email("maria@gmail.com", secret_key)
# pseudonym = "user_42af8b2c..."
Características
Pros:
- Reversible: con la key, podés mapear pseudónimo → real.
- Mantenés joinability: same person → same pseudonym, así que podés joinear datasets.
- Reduce surface area: data exposed no contiene PII directo.
Cons:
- NO es anonymization: si la key se compromete, todo se reversa.
- Bajo GDPR: pseudonymized data sigue siendo personal data y aplican obligations.
- Re-identification: aún sin la key, otros features pueden identificar individuos.
Cuándo usar pseudonymization
Apropiada cuando:
- Necesitás joinability entre datasets pero no PII directo.
- Operations requieren reverse ocasional (auditing, customer support).
- Como capa, combined con otras techniques.
NO suficiente cuando regulation requires "anonymized" data específicamente.
Anonymization
Definición
Transformar data tal que no se pueda re-identificar al individuo original, ni con auxiliary information.
GDPR Recital 26: anonymized data es data NO personal data — fuera del scope de GDPR.
Por qué anonymization perfecta es difícil
Re-identification attacks:
-
Linkage attacks: combinar datasets "anonymized" con auxiliary data revela individuos.
Caso real: Netflix Prize Dataset (2006). Anonymized movie ratings de 480K users. Researchers linked to IMDB public ratings → re-identificaron users con 80%+ accuracy.
-
Quasi-identifiers: combinations de features que individually no son PII pero combined identifican.
Caso real: Sweeney (2000) demostró que {date of birth, ZIP code, gender} identifica unique a 87% de US population. None es PII por sí sola.
-
Background knowledge attacks: atacante con info parcial (sabe que María vive en NYC, working in tech) puede triangulate en small datasets.
Implementación: simplemente eliminar identifiers no es suficiente
# ❌ Insuficiente
def fake_anonymize(record):
"""Eliminar email y nombre. ¿Suficiente?"""
record.pop('email', None)
record.pop('name', None)
return record
# Result: aún tenés ZIP, age, gender, occupation, etc.
# Combinaciones identifican individuos.
Anonymization seria requiere:
- Drop direct identifiers (name, email, SSN).
- Generalize quasi-identifiers (age → bracket, ZIP → first 3 digits).
- Suppress outliers que serían unique.
- Add noise o aggregar para limitar precisión.
K-Anonymity
Concepto
Un dataset es k-anonymous si cada record es indistinguishable de al menos k-1 otros records en términos de quasi-identifiers.
Dataset NO k-anonymous (k=1, identifiable):
| Age | ZIP | Occupation |
|-----|-------|----------------|
| 23 | 10001 | Software eng | ← unique
| 45 | 10003 | Doctor | ← unique
| 31 | 10002 | Teacher | ← unique
Dataset 3-anonymous (each row matches at least 2 others):
| Age | ZIP | Occupation |
|-------|---------|------------|
| 20-30 | 100** | Tech |
| 20-30 | 100** | Tech |
| 20-30 | 100** | Tech |
| 30-40 | 100** | Education |
| 30-40 | 100** | Education |
| 30-40 | 100** | Education |
K=3 significa que cada record matches at least 2 others en quasi-identifiers. Re-identification requires distinguir entre 3 indistinguishable individuals.
Implementación con generalization
import pandas as pd
def k_anonymize(df, quasi_identifiers, k=3):
"""
Simplified k-anonymity con generalization.
"""
# Generalize age to bracket
if 'age' in quasi_identifiers:
df['age'] = pd.cut(df['age'],
bins=[0, 20, 30, 40, 50, 60, 100],
labels=['<20', '20-29', '30-39', '40-49', '50-59', '60+'])
# Generalize ZIP to first 3 digits
if 'zip' in quasi_identifiers:
df['zip'] = df['zip'].astype(str).str[:3] + '**'
# Find equivalence classes
grouped = df.groupby(quasi_identifiers).size().reset_index(name='count')
# Suppress records que están en classes < k
valid_classes = grouped[grouped['count'] >= k][quasi_identifiers]
df_anonymized = df.merge(valid_classes, on=quasi_identifiers, how='inner')
return df_anonymized
Limitations de k-anonymity
K-anonymity protege contra identity disclosure pero no contra attribute disclosure:
Equivalence class (3 individuals all in 30-39, NYC):
| Age | ZIP | Diagnosis |
|-------|--------|----------------|
| 30-39 | 100** | HIV positive |
| 30-39 | 100** | HIV positive |
| 30-39 | 100** | HIV positive |
K=3 pero todos tienen el same diagnosis. Si sabés que alguien specific está en este equivalence class, sabés su diagnosis.
L-diversity y T-closeness abordan este gap.
L-Diversity
Concepto
Un dataset es l-diverse si cada equivalence class tiene at least l distinct values en sensitive attributes.
3-diverse en "Diagnosis":
| Age | ZIP | Diagnosis |
|-------|--------|----------------|
| 30-39 | 100** | HIV positive |
| 30-39 | 100** | Diabetes |
| 30-39 | 100** | Healthy |
Aún si sabés que alguien está en el class, no sabés cuál de los 3 diagnoses tiene.
L-diversity protege contra attribute disclosure básico.
Limitations
L-diversity puede aún leak información:
- Si attacker sabe que el target NO tiene diabetes, queda 50% chance de cada uno de los otros dos.
- Si los values están skewed (90% un value), poco protección.
T-Closeness
Concepto
Un dataset es t-close si la distribución de values en cada equivalence class es close to la distribución global (within threshold t).
Garantiza que conocer que alguien está en X class no te dice más sobre su sensitive attribute que conocer the general population.
Implementación es matemáticamente compleja (Earth Mover's Distance). En práctica, librerías como ARX (open source) lo implementan.
Differential Privacy
El gold standard
Differential Privacy (Dwork et al., 2006) provides mathematical guarantee sobre privacy:
Adding o removing un single individual del dataset cambia el output del análisis solo por un small bounded amount.
Significa: el output NO depende significativamente de any single individual. Por lo tanto, information about any individual no puede ser inferred.
Mecanismo: agregar noise
DP works by adding calibrated noise a queries o outputs:
import numpy as np
def differentially_private_count(data, epsilon=1.0):
"""
Count con DP guarantee.
epsilon: privacy budget (lower = more private, less accurate).
"""
true_count = len(data)
# Add Laplace noise calibrated to sensitivity / epsilon
noise = np.random.laplace(0, 1/epsilon)
return true_count + noise
Privacy budget (epsilon)
- ε = 0: perfect privacy (output no depende del data).
- ε = ∞: no privacy (output exactamente determined by data).
- Practical range: 0.1 - 10.
Lower ε = better privacy + more noise + less accuracy.
DP en ML training
DP-SGD (Abadi et al., 2016): variant de stochastic gradient descent que adds noise a gradients during training. Resultante modelo es differentially private.
# Pseudo-code
def dp_sgd_step(model, batch, epsilon, delta):
# Compute gradients per-sample
per_sample_grads = compute_per_sample_grads(model, batch)
# Clip gradients to limit sensitivity
clipped_grads = clip(per_sample_grads, max_norm=1.0)
# Average + add noise
avg_grad = mean(clipped_grads)
noise = sample_gaussian_noise(scale=clipped_norm/epsilon)
private_grad = avg_grad + noise
# Update model
model.params -= learning_rate * private_grad
Trade-offs de DP
Pros:
- Mathematical guarantee — no es heuristic.
- Composable: combining queries each with budget ε₁, ε₂ gives total privacy ε₁ + ε₂.
- Future-proof: protege contra attacks no descubiertos.
Cons:
- Accuracy cost: noise reduces utility. Significant.
- Privacy budget management: cada query gasta budget. Eventually runs out.
- Implementación compleja: bugs in DP implementations have been published frequently.
Cuándo usar DP
- Sensitive medical o census data.
- Sistemas que liberan stats públicos (US Census 2020 used DP).
- Federated learning con strong privacy.
Para most AI engineering applications, DP es overkill — pseudonymization + k-anonymity + access controls son sufficient. DP es para casos donde mathematical guarantee es required.
Aplicación a AI training data
Scenario: training un classifier
Tu data tiene PII. Necesitás training data, querés minimize privacy risk.
Opciones:
Opción 1: drop direct identifiers (basic)
training_data.drop(columns=['email', 'name', 'phone', 'address'], inplace=True)
Insuficiente solo. Quasi-identifiers remain.
Opción 2: pseudonymize identifiers
training_data['email_id'] = pseudonymize(training_data['email'])
training_data.drop(columns=['email', 'name'], inplace=True)
Mejor pero pseudonymized → still personal data.
Opción 3: k-anonymize
quasi_ids = ['age', 'zip', 'gender']
training_data = k_anonymize(training_data, quasi_ids, k=5)
Protege contra identity disclosure. Suficiente para most cases.
Opción 4: DP-SGD
model = train_with_dp_sgd(data, epsilon=1.0)
Mathematical guarantee, pero accuracy cost.
Decision matrix
| Risk level | Recommendation |
|---|---|
| Low (público anyway) | Drop direct identifiers |
| Medium (proprietary internal) | Pseudonymize + access controls |
| High (regulated, PII heavy) | K-anonymize + pseudonymize |
| Critical (medical, legal) | DP-SGD or federated learning |
Trampas comunes
1. "Eliminamos los nombres, está anonimizado"
Falso. Quasi-identifiers (age + ZIP + gender) frecuentemente identifican uniquely.
2. Confiar en hashing como anonymization
hash(email) is deterministic — same email always same hash. Re-identification trivial con rainbow table o brute force.
Para anonymization real, requiere added randomness o k-anonymity.
3. Pseudonymization sin securing key
Si pseudonymization key se compromete, todo se reversa. Treat key con same level que master password.
4. Anonymization once-and-done
Datasets son dinámicos. Anonymization que was sufficient last year puede ser insufficient today con new auxiliary data available.
5. Olvidar quasi-identifiers temporal
Timestamp + location → very identifying. "User accessed at 14:32 from NYC" puede ser unique daily.
Auto-verificación
1. ¿Cuál es la diferencia clave entre anonymization y pseudonymization?
Reversibilidad:
-
Pseudonymization: reversible con key. Mismo individuo → mismo pseudónimo (joinable). Pero con la key, podés recover identity.
-
Anonymization: irreversible. No hay key. No hay forma matemática de recover identity (idealmente).
Implicación legal (GDPR):
- Pseudonymized data es personal data — aplican todas las obligations (Art 6, etc.).
- Anonymized data no es personal data — out of GDPR scope.
Implicación práctica:
- Pseudonymization es easier to implement y útil cuando necesitás operations reverse (auditing).
- Anonymization es harder to achieve genuinely debido a re-identification attacks.
Para muchos AI use cases, pseudonymization + access controls + minimization es la combination correcta.
2. ¿Por qué k-anonymity sola no es suficiente?
K-anonymity protege contra identity disclosure (saber WHICH individuo) pero NO contra attribute disclosure (saber QUÉ atributos sensitive tienen).
Caso ejemplo: 3-anonymous group donde todos tienen mismo diagnosis. K=3 satisfecho. Pero si sabés que target está en el group, sabés su diagnosis.
L-diversity addresses esto: requires equivalence classes con at least l distinct sensitive values.
T-closeness addresses further: requires distribución dentro del class similar a global distribución.
En la práctica:
- K-anonymity es basic privacy — minimum bar.
- L-diversity es standard privacy — sufficient for many uses.
- T-closeness es strong privacy — for highly sensitive contexts.
- Differential privacy es mathematical guarantee — strongest pero accuracy-costly.
3. ¿Cuándo es differential privacy worth el accuracy cost?
Cuando:
-
Mathematical guarantee es required: para regulated industries (medical research) o public data releases (census).
-
Future-proof matters: querés protection contra attacks no descubiertos aún.
-
Composability: vas a hacer múltiples queries y necesitás privacy budget tracking.
-
High-risk PII: medical records, legal data, financial sensitive.
NO worth para:
- Standard ML applications con normal PII.
- Cuando pseudonymization + k-anonymity son sufficient.
- Cuando accuracy es critical (e.g., medical diagnosis where false negatives kill).
Práctica común: usar DP para published statistics, pseudonymization + minimization para internal ML training. Best of both worlds.
4. ¿Cómo abordás re-identification attacks?
Multiple defenses:
-
Drop direct identifiers: name, email, SSN, etc.
-
Generalize quasi-identifiers: age bracket, ZIP first 3 digits, etc.
-
Suppress outliers: records que serían unique se eliminan o generalizan más.
-
K-anonymity (k≥5): each record matches at least 4 others.
-
L-diversity (l≥3): equivalence classes tienen diverse sensitive values.
-
Limit auxiliary data: minimize what context attackers have.
-
Access controls: data anonymizada aún restricted access.
-
Re-evaluate periodically: with new data sources, what was anonymous becomes identifiable.
-
Differential privacy for highest stakes.
Defense en profundidad — múltiples layers, no single technique. Asumí que individual layers will fail; combination provides robustness.
Resumen y siguiente paso
- Pseudonymization: reversible. Buena para joinability + reduced surface area. Aún personal data bajo GDPR.
- Anonymization: irreversible. Difícil de lograr genuinely debido a re-identification attacks.
- K-anonymity: cada record indistinguishable de k-1 otros. Basic privacy.
- L-diversity, T-closeness: incremental improvements addressing attribute disclosure.
- Differential Privacy: mathematical guarantee, gold standard, accuracy cost significativo.
- Defense en profundidad: combinar techniques + access controls + minimization.
Checkpoint: deberías poder elegir technique apropiada según tu data sensitivity y use case.
Puente a la siguiente cápsula: la cápsula 04 cubre consent en sistemas AI: informed consent, granularidad, revocación, y los retos específicos de obtener consent significativo cuando los users no entienden cómo AI procesa sus datos.
Recursos
- k-Anonymity (Sweeney, 2002) — paper foundational.
- Differential Privacy (Dwork et al., 2006) — paper foundational.
- ARX Anonymization Tool — open source implementation.
- DP-SGD (Abadi et al., 2016) — DP for ML training.
- Netflix Prize re-identification — case study.
Siguiente: 04-consent-en-ai.md — Consent significativo para sistemas AI.
Cápsula 03 de 08 — Módulo 3 — AI Ethics & Compliance Guide