Files
anonymisation/evaluation
Domi31tls eb14cd219d feat(phase3): CamemBERT v3 + détection villes + initiales + texte espacé + docs réglementaires
Intégration du modèle CamemBERT-bio-deid v3 (F1=0.96, Recall=0.97, 1112 docs)
et corrections qualité issues de l'audit approfondi sur 29 fichiers.

Détection des villes en texte libre :
- Automate Aho-Corasick sur 33K communes INSEE + 11.6K villes FINESS
- Stratégie contextuelle : exige un contexte géographique (à, de, vers,
  habite, urgences de, etc.) sauf pour les villes composées (Saint-Palais)
- Blacklist de ~80 communes homonymes de mots courants (charge, signes, plan...)
- Normalisation SAINT↔ST pour les variantes orthographiques
- De 18 fuites de villes à 2 cas résiduels atypiques

Masquage des initiales de prénom :
- Post-traitement regex : "Dr T. [NOM]" → "Dr [NOM] [NOM]"
- Références initiales : "Ref : JF/VA" → "Ref : [NOM]/[NOM]"

Détection texte espacé d'en-tête :
- "C E N T R E  H O S P I T A L I E R" → [ETABLISSEMENT]

Autres corrections :
- Fix regex RE_EXTRACT_MME_MR (Mr?.? → Mr.?, \s+ → [ \t]+, * → {0,4})
- Stop words médicaux : lever, coucher, services hospitaliers (viscérale, etc.)
- CamemBERT NER manager : version tracking, propriété version, log F1/Recall
- Script finetune : export ONNX automatique + mise à jour VERSION.json
- Évaluateur qualité : exclusion stop words médicaux des alertes INSEE

Documentation :
- Spécifications techniques CamemBERT-bio-deid v3
- Conformité RGPD + AI Act (caviardage PDF raster)
- AIPD (Analyse d'Impact Protection des Données)

Score qualité : 97.0/100 (Grade A), Leak score 100/100

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:16:13 +01:00
..

Module d'Évaluation de la Qualité d'Anonymisation

Ce module fournit des outils pour évaluer et valider la qualité de l'anonymisation des documents PDF médicaux.

Composants

1. QualityEvaluator

Évalue la qualité d'anonymisation en comparant les annotations manuelles (ground truth) avec les détections automatiques.

Métriques calculées :

  • Précision (Precision) : TP / (TP + FP)
  • Rappel (Recall) : TP / (TP + FN)
  • F1-Score : 2 × (Precision × Recall) / (Precision + Recall)

Usage :

from evaluation import QualityEvaluator
from pathlib import Path

evaluator = QualityEvaluator(Path("tests/ground_truth/pdfs"))

# Évaluer un document
result = evaluator.evaluate(
    pdf_path=Path("tests/ground_truth/pdfs/001_simple_unknown_BACTERIO_23018396.pdf"),
    audit_path=Path("tests/ground_truth/pdfs/001_simple_unknown_BACTERIO_23018396.audit.jsonl")
)

print(f"Précision: {result.precision:.4f}")
print(f"Rappel: {result.recall:.4f}")
print(f"F1-Score: {result.f1_score:.4f}")

# Générer un rapport
report = evaluator.generate_report([result])
print(report)

# Exporter en JSON
evaluator.export_json([result], Path("evaluation_results.json"))

2. LeakScanner

Scanne les documents anonymisés pour détecter les fuites de PII (données personnelles résiduelles).

Vérifications :

  • PII originaux encore présents (CRITIQUE)
  • Nouveaux PII détectés (HAUTE)
  • Métadonnées PDF suspectes (MOYENNE)

Usage :

from evaluation import LeakScanner
from pathlib import Path

scanner = LeakScanner()

# Scanner un document anonymisé
report = scanner.scan(
    anonymized_pdf=Path("output/document.redacted.pdf"),
    original_audit=Path("output/document.audit.jsonl")
)

if report.is_safe:
    print("✓ Document sûr - Aucune fuite détectée")
else:
    print(f"✗ {report.leak_count} fuite(s) détectée(s)")
    for leak in report.leaks:
        print(f"  - {leak['severity']}: {leak['message']}")

# Générer un rapport
report_text = scanner.generate_report(report, Path("document.pdf"))
print(report_text)

# Exporter en JSON
scanner.export_json(report, Path("leak_report.json"))

3. Benchmark

Mesure les performances du système d'anonymisation (temps, CPU, RAM).

Métriques collectées :

  • Temps de traitement (total, par page)
  • Utilisation CPU (%)
  • Utilisation RAM (MB)
  • Nombre de PII détectés

Usage :

from evaluation import Benchmark
from pathlib import Path

benchmark = Benchmark(Path("tests/ground_truth/pdfs"))

# Définir la fonction d'anonymisation à benchmarker
def anonymize_func(pdf_path):
    # Votre code d'anonymisation ici
    # Retourner le chemin vers le fichier .audit.jsonl
    return pdf_path.parent / f"{pdf_path.stem}.audit.jsonl"

# Benchmarker des documents
pdf_list = list(Path("tests/ground_truth/pdfs").glob("*.pdf"))
results = benchmark.run(pdf_list, anonymize_func)

# Générer un rapport
report = benchmark.generate_report(results)
print(report)

# Exporter en JSON
benchmark.export_json(results, Path("benchmark_results.json"))

# Exporter en CSV
benchmark.export_csv(results, Path("benchmark_results.csv"))

Installation

Dépendances requises :

pip install pymupdf psutil

Tests

Exécuter les tests unitaires :

pytest tests/unit/test_quality_evaluator.py -v
pytest tests/unit/test_leak_scanner.py -v
pytest tests/unit/test_benchmark.py -v

Format des Données

Annotations (ground truth)

Format JSON :

{
  "pdf_path": "document.pdf",
  "metadata": {
    "annotator": "annotator_1",
    "annotation_date": "2024-01-15T10:30:00",
    "document_type": "compte_rendu",
    "page_count": 3,
    "difficulty": "medium"
  },
  "annotations": [
    {
      "id": "ann_001",
      "page": 0,
      "type": "NOM",
      "text": "DUPONT",
      "bbox": null,
      "context": "Dr. DUPONT a examiné le patient",
      "mandatory": true,
      "difficulty": "easy",
      "detection_method_expected": ["regex", "ner", "contextual"]
    }
  ],
  "medical_terms_to_preserve": [
    "Médecin DIM",
    "Service de cardiologie"
  ],
  "statistics": {
    "total_pii": 1,
    "by_type": {
      "NOM": 1
    }
  }
}

Audit (détections)

Format JSONL (une ligne par PII détecté) :

{"page": 0, "kind": "NOM", "original": "DUPONT", "placeholder": "[NOM]"}
{"page": 0, "kind": "TEL", "original": "01 23 45 67 89", "placeholder": "[TEL]"}

Métriques Cibles

Pour garantir la conformité RGPD et la qualité d'anonymisation :

  • Rappel (Recall) : ≥ 99.5% (maximum 0.5% de PII manqués)
  • Précision (Precision) : ≥ 97% (maximum 3% de faux positifs)
  • F1-Score : ≥ 0.98
  • Taux de documents sûrs : ≥ 98% (documents avec 0 faux négatif)

Workflow Complet

  1. Annoter les documents : Utiliser tools/annotation_tool.py
  2. Anonymiser les documents : Utiliser le système d'anonymisation
  3. Évaluer la qualité : Utiliser QualityEvaluator
  4. Scanner les fuites : Utiliser LeakScanner
  5. Benchmarker les performances : Utiliser Benchmark
  6. Analyser les résultats : Identifier les améliorations nécessaires

Exemples de Rapports

Rapport d'Évaluation

================================================================================
RAPPORT D'ÉVALUATION DE LA QUALITÉ D'ANONYMISATION
================================================================================

Documents évalués: 27

MÉTRIQUES GLOBALES:
  True Positives:  245
  False Positives: 8
  False Negatives: 2

  Précision moyenne: 0.9684 (96.84%)
  Rappel moyen:      0.9919 (99.19%)
  F1-Score moyen:    0.9800

RÉSULTATS PAR DOCUMENT:
  001_simple_unknown_BACTERIO_23018396.pdf
    Précision: 1.0000  Rappel: 1.0000  F1: 1.0000
    TP: 10  FP: 0  FN: 0

Rapport de Fuite

================================================================================
RAPPORT DE FUITE - document.redacted.pdf
================================================================================

✓ DOCUMENT SÛR - Aucune fuite détectée

================================================================================

Rapport de Benchmark

================================================================================
RAPPORT DE BENCHMARK - PERFORMANCE D'ANONYMISATION
================================================================================

SYSTÈME:
  OS: Linux 6.8.0
  CPU: AMD Ryzen 9 9950X
  Cœurs: 16 physiques / 32 logiques
  RAM: 128.0 GB
  Python: 3.12.0

RÉSUMÉ:
  Documents: 27
  Temps moyen: 8.5s
  Temps min/max: 2.1s / 25.3s
  CPU moyen: 45.2%
  RAM moyenne: 1024.5 MB
  PII détectés: 245 (moy: 9.1)

Licence

Ce module fait partie du système d'anonymisation de documents PDF médicaux.