#!/usr/bin/env python3 """ Démonstration du système d'évaluation de la qualité d'anonymisation. Ce script montre comment utiliser les 3 composants principaux : 1. QualityEvaluator - Évaluation de la qualité 2. LeakScanner - Détection de fuites 3. Benchmark - Mesure de performance """ import json from pathlib import Path from evaluation import QualityEvaluator, LeakScanner, Benchmark def demo_annotation_tool(): """Démo de l'outil d'annotation.""" print("\n" + "="*80) print("DÉMO 1 : OUTIL D'ANNOTATION") print("="*80) print("\nL'outil d'annotation permet d'annoter manuellement les documents PDF.") print("\nCommandes disponibles:") print(" python tools/annotation_tool.py --list") print(" → Liste les 27 documents disponibles") print("\n python tools/annotation_tool.py --resume") print(" → Reprend l'annotation au prochain document non annoté") print("\n python tools/annotation_tool.py tests/ground_truth/pdfs/001_simple_unknown_BACTERIO_23018396.pdf") print(" → Annote un document spécifique") # Afficher les documents disponibles pdfs_dir = Path("tests/ground_truth/pdfs") pdfs = sorted(pdfs_dir.glob("*.pdf")) print(f"\n📁 {len(pdfs)} documents disponibles dans {pdfs_dir}") print("\nExemples:") for pdf in pdfs[:5]: annotation_file = pdf.parent / f"{pdf.stem}.annotations.json" status = "✓ Annoté" if annotation_file.exists() else "○ À annoter" print(f" {status} {pdf.name}") print(f" ... et {len(pdfs) - 5} autres") def demo_quality_evaluator(): """Démo de l'évaluateur de qualité.""" print("\n" + "="*80) print("DÉMO 2 : ÉVALUATEUR DE QUALITÉ") print("="*80) print("\nL'évaluateur compare les annotations manuelles avec les détections automatiques.") print("Il calcule : Précision, Rappel, F1-Score") # Créer des données de test fictives print("\n📝 Création d'annotations de test...") test_pdf = Path("tests/ground_truth/pdfs/001_simple_unknown_BACTERIO_23018396.pdf") test_annotation = test_pdf.parent / f"{test_pdf.stem}.annotations.json" test_audit = test_pdf.parent / f"{test_pdf.stem}.audit.jsonl" # Créer une annotation fictive annotation_data = { "pdf_path": str(test_pdf), "metadata": { "annotator": "demo", "annotation_date": "2024-01-15T10:00:00", "document_type": "bacterio", "page_count": 1, "difficulty": "simple" }, "annotations": [ { "id": "ann_001", "page": 0, "type": "NOM", "text": "DUPONT", "bbox": None, "context": "Dr. DUPONT a examiné", "mandatory": True, "difficulty": "easy", "detection_method_expected": ["regex", "ner"] }, { "id": "ann_002", "page": 0, "type": "TEL", "text": "01 23 45 67 89", "bbox": None, "context": "Tel: 01 23 45 67 89", "mandatory": True, "difficulty": "easy", "detection_method_expected": ["regex"] }, { "id": "ann_003", "page": 0, "type": "EMAIL", "text": "jean.dupont@chu-bordeaux.fr", "bbox": None, "context": "Email: jean.dupont@chu-bordeaux.fr", "mandatory": True, "difficulty": "easy", "detection_method_expected": ["regex"] } ], "medical_terms_to_preserve": ["Médecin DIM", "Service de bactériologie"], "statistics": { "total_pii": 3, "by_type": {"NOM": 1, "TEL": 1, "EMAIL": 1} } } with open(test_annotation, 'w', encoding='utf-8') as f: json.dump(annotation_data, f, indent=2, ensure_ascii=False) print(f"✓ Annotation créée: {test_annotation.name}") print(f" - 3 PII annotés: 1 NOM, 1 TEL, 1 EMAIL") # Créer un audit fictif (détections) audit_data = [ {"page": 0, "kind": "NOM", "original": "DUPONT", "placeholder": "[NOM]"}, {"page": 0, "kind": "TEL", "original": "01 23 45 67 89", "placeholder": "[TEL]"}, {"page": 0, "kind": "EMAIL", "original": "jean.dupont@chu-bordeaux.fr", "placeholder": "[EMAIL]"}, {"page": 0, "kind": "NOM", "original": "MARTIN", "placeholder": "[NOM]"} # Faux positif ] with open(test_audit, 'w', encoding='utf-8') as f: for item in audit_data: f.write(json.dumps(item) + '\n') print(f"✓ Audit créé: {test_audit.name}") print(f" - 4 PII détectés: 2 NOM, 1 TEL, 1 EMAIL") # Évaluer print("\n🔍 Évaluation en cours...") evaluator = QualityEvaluator(Path("tests/ground_truth/pdfs")) result = evaluator.evaluate(test_pdf, test_audit) if result: print("\n📊 RÉSULTATS:") print(f" True Positives: {result.true_positives}") print(f" False Positives: {result.false_positives}") print(f" False Negatives: {result.false_negatives}") print(f"\n Précision: {result.precision:.4f} ({result.precision*100:.2f}%)") print(f" Rappel: {result.recall:.4f} ({result.recall*100:.2f}%)") print(f" F1-Score: {result.f1_score:.4f}") if result.false_positives > 0: print(f"\n ⚠ Faux positifs détectés:") for fp in result.false_detections: print(f" - {fp['type']}: {fp['text']}") # Générer un rapport report = evaluator.generate_report([result]) print("\n" + "─"*80) print(report) # Nettoyer test_annotation.unlink() test_audit.unlink() print("\n✓ Fichiers de test nettoyés") def demo_leak_scanner(): """Démo du scanner de fuite.""" print("\n" + "="*80) print("DÉMO 3 : SCANNER DE FUITE") print("="*80) print("\nLe scanner vérifie qu'aucun PII ne subsiste dans les documents anonymisés.") print("Il détecte:") print(" - PII originaux encore présents (CRITIQUE)") print(" - Nouveaux PII non masqués (HAUTE)") print(" - Métadonnées suspectes (MOYENNE)") # Créer des données de test print("\n📝 Création de données de test...") test_pdf = Path("tests/ground_truth/pdfs/001_simple_unknown_BACTERIO_23018396.pdf") test_audit = test_pdf.parent / f"{test_pdf.stem}.audit.jsonl" # Créer un audit fictif audit_data = [ {"page": 0, "kind": "NOM", "original": "DUPONT", "placeholder": "[NOM]"}, {"page": 0, "kind": "TEL", "original": "01 23 45 67 89", "placeholder": "[TEL]"} ] with open(test_audit, 'w', encoding='utf-8') as f: for item in audit_data: f.write(json.dumps(item) + '\n') print(f"✓ Audit créé: {test_audit.name}") # Scanner (simulation - le PDF n'est pas vraiment anonymisé) print("\n🔍 Scan en cours...") scanner = LeakScanner() # Simuler un scan avec du texte print("\n📄 Simulation de scan de texte:") # Cas 1 : Document sûr safe_text = "Le patient [NOM] a été examiné le [DATE]. Contact: [TEL]" original_pii = [ {"kind": "NOM", "original": "DUPONT"}, {"kind": "TEL", "original": "01 23 45 67 89"} ] leaks = scanner.scan_text(safe_text, original_pii) print(f"\n Texte: {safe_text}") print(f" Résultat: {'✓ Aucune fuite' if len(leaks) == 0 else f'✗ {len(leaks)} fuite(s)'}") # Cas 2 : Document avec fuite unsafe_text = "Le patient DUPONT a été examiné. Tel: 01 23 45 67 89" leaks = scanner.scan_text(unsafe_text, original_pii) print(f"\n Texte: {unsafe_text}") print(f" Résultat: {'✓ Aucune fuite' if len(leaks) == 0 else f'✗ {len(leaks)} fuite(s)'}") if leaks: for leak in leaks: print(f" - {leak['severity']}: {leak['message']}") # Cas 3 : Nouveau PII détecté new_pii_text = "Contact: marie.martin@example.com" leaks = scanner.scan_text(new_pii_text, original_pii) print(f"\n Texte: {new_pii_text}") print(f" Résultat: {'✓ Aucune fuite' if len(leaks) == 0 else f'✗ {len(leaks)} fuite(s)'}") if leaks: for leak in leaks: print(f" - {leak['severity']}: {leak['message']}") # Nettoyer test_audit.unlink() print("\n✓ Fichiers de test nettoyés") def demo_benchmark(): """Démo du benchmark.""" print("\n" + "="*80) print("DÉMO 4 : BENCHMARK DE PERFORMANCE") print("="*80) print("\nLe benchmark mesure les performances du système d'anonymisation:") print(" - Temps de traitement (total, par page)") print(" - Utilisation CPU (%)") print(" - Utilisation RAM (MB)") print(" - Nombre de PII détectés") # Afficher les informations système print("\n💻 Informations système:") benchmark = Benchmark(Path("tests/ground_truth/pdfs")) system_info = benchmark.get_system_info() for key, value in system_info.items(): print(f" {key}: {value}") print("\n📊 Exemple de résultats de benchmark:") print("\n Document: 001_simple_unknown_BACTERIO_23018396.pdf") print(" Temps: 3.45s") print(" Temps/page: 3.45s") print(" CPU: 45.2%") print(" RAM: 512.3 MB") print(" PII détectés: 12") print("\n Document: 023_complexe_compte_rendu_CRH_23102610.pdf") print(" Temps: 25.67s") print(" Temps/page: 2.85s (9 pages)") print(" CPU: 67.8%") print(" RAM: 1024.5 MB") print(" PII détectés: 45") print("\n📈 Résumé (27 documents):") print(" Temps moyen: 8.5s") print(" Temps min/max: 2.1s / 25.7s") print(" CPU moyen: 52.3%") print(" RAM moyenne: 768.2 MB") print(" PII détectés: 245 (moy: 9.1)") def main(): """Fonction principale.""" print("\n" + "="*80) print("DÉMONSTRATION DU SYSTÈME D'ÉVALUATION DE LA QUALITÉ D'ANONYMISATION") print("="*80) print("\nCe système permet de:") print(" 1. Annoter manuellement des documents PDF") print(" 2. Évaluer la qualité des détections (Précision, Rappel, F1)") print(" 3. Scanner les fuites de PII dans les documents anonymisés") print(" 4. Benchmarker les performances du système") # Lancer les démos demo_annotation_tool() demo_quality_evaluator() demo_leak_scanner() demo_benchmark() print("\n" + "="*80) print("FIN DE LA DÉMONSTRATION") print("="*80) print("\n📚 Pour en savoir plus:") print(" - Guide d'annotation: docs/annotation_guide.md") print(" - Documentation du module: evaluation/README.md") print(" - Tests unitaires: tests/unit/") print("\n🚀 Prochaines étapes:") print(" 1. Annoter les 27 documents: python tools/annotation_tool.py --resume") print(" 2. Anonymiser les documents avec le système actuel") print(" 3. Évaluer la qualité: python -c 'from evaluation import QualityEvaluator; ...'") print(" 4. Mesurer la baseline et identifier les améliorations") print("\n✨ Bon travail !") if __name__ == "__main__": main()