Files
anonymisation/evaluation
Domi31tls a827d860f1 fix: corrections retours collaborateurs — FP médicaments, N° venue, taille PDF
- Fix critique: whole-word search dans redact_pdf_raster et redact_pdf_vector
  pour éviter le substring matching (ex: "Luc" dans "FLUCONAZOLE",
  "TATIN" dans "ATORVASTATINE"). Appliqué à tous les kinds nom/NER.
- Ajout regex RE_VENUE_SEJOUR pour N° venue / N° séjour (BACTERIO, Trackare)
- DDN multiline élargi: tolère 0-3 lignes entre label DDN et date (tableaux BACTERIO)
- N° venue multiline: détection dans tableaux BACTERIO interleaved
- Réduction taille PDF raster: 150 DPI + JPEG quality 85 (était 300 DPI PNG)
  Ratio moyen: 19.5x (était 30-50x)
- Score qualité maintenu: 97.0/100 (grade A), 0 régression

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:38:27 +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.