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:

  1. Definiciones formales y diferencias técnicas.
  2. Cuándo cada una aplica.
  3. Re-identification attacks — por qué anonymization perfecta es difícil.
  4. K-anonymity, L-diversity, T-closeness — técnicas progresivamente robustas.
  5. Differential Privacy — el gold standard.
  6. 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:

  1. Necesitás joinability entre datasets pero no PII directo.
  2. Operations requieren reverse ocasional (auditing, customer support).
  3. 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:

  1. 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.

  2. 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.

  3. 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:

  1. Drop direct identifiers (name, email, SSN).
  2. Generalize quasi-identifiers (age → bracket, ZIP → first 3 digits).
  3. Suppress outliers que serían unique.
  4. 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 levelRecommendation
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:

  1. Mathematical guarantee es required: para regulated industries (medical research) o public data releases (census).

  2. Future-proof matters: querés protection contra attacks no descubiertos aún.

  3. Composability: vas a hacer múltiples queries y necesitás privacy budget tracking.

  4. 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:

  1. Drop direct identifiers: name, email, SSN, etc.

  2. Generalize quasi-identifiers: age bracket, ZIP first 3 digits, etc.

  3. Suppress outliers: records que serían unique se eliminan o generalizan más.

  4. K-anonymity (k≥5): each record matches at least 4 others.

  5. L-diversity (l≥3): equivalence classes tienen diverse sensitive values.

  6. Limit auxiliary data: minimize what context attackers have.

  7. Access controls: data anonymizada aún restricted access.

  8. Re-evaluate periodically: with new data sources, what was anonymous becomes identifiable.

  9. 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

  1. k-Anonymity (Sweeney, 2002) — paper foundational.
  2. Differential Privacy (Dwork et al., 2006) — paper foundational.
  3. ARX Anonymization Tool — open source implementation.
  4. DP-SGD (Abadi et al., 2016) — DP for ML training.
  5. 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