- Test sur 003_simple_compte_rendu_CRO_23155084.pdf - 25 PII détectés (4 sur page principale + propagation globale) - Types: NOM, ADRESSE, CODE_POSTAL, DATE_NAISSANCE - Validation: AUCUNE FUITE détectée ✓ - Scripts d'analyse: analyze_anonymization_result.py, demo_complete_anonymization.py - Résultats dans tests/ground_truth/pdfs/anonymized_test/
143 lines
5.1 KiB
Python
143 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Démonstration complète : Anonymisation + Analyse
|
|
"""
|
|
import json
|
|
from pathlib import Path
|
|
from collections import Counter
|
|
from evaluation import LeakScanner
|
|
|
|
def show_comparison():
|
|
"""Affiche une comparaison avant/après."""
|
|
|
|
print("\n" + "="*80)
|
|
print("DÉMONSTRATION COMPLÈTE : ANONYMISATION D'UN DOCUMENT RÉEL")
|
|
print("="*80)
|
|
|
|
# Fichiers
|
|
original_pdf = Path("tests/ground_truth/pdfs/003_simple_compte_rendu_CRO_23155084.pdf")
|
|
output_dir = Path("tests/ground_truth/pdfs/anonymized_test")
|
|
base_name = "003_simple_compte_rendu_CRO_23155084"
|
|
|
|
audit_path = output_dir / f"{base_name}.audit.jsonl"
|
|
redacted_pdf = output_dir / f"{base_name}.redacted_raster.pdf"
|
|
|
|
print(f"\n📄 DOCUMENT TRAITÉ")
|
|
print(f" Original: {original_pdf.name}")
|
|
print(f" Type: Compte-rendu opératoire (CRO)")
|
|
print(f" Complexité: Simple (1 page)")
|
|
|
|
# Extraire le texte original
|
|
try:
|
|
import fitz
|
|
doc = fitz.open(original_pdf)
|
|
original_text = doc[0].get_text()
|
|
doc.close()
|
|
|
|
print(f"\n📝 TEXTE ORIGINAL (extrait):")
|
|
print(" " + "-"*76)
|
|
lines = original_text.split('\n')[:8]
|
|
for line in lines:
|
|
if line.strip():
|
|
print(f" {line[:76]}")
|
|
print(" " + "-"*76)
|
|
except Exception as e:
|
|
print(f" ⚠ Impossible d'extraire le texte: {e}")
|
|
|
|
# Analyser les PII détectés
|
|
if audit_path.exists():
|
|
print(f"\n🔍 PII DÉTECTÉS PAR LE SYSTÈME")
|
|
|
|
pii_list = []
|
|
with open(audit_path, 'r', encoding='utf-8') as f:
|
|
for line in f:
|
|
if line.strip():
|
|
pii_list.append(json.loads(line))
|
|
|
|
# PII de la page principale
|
|
page0_pii = [p for p in pii_list if p.get('page') == 0]
|
|
|
|
print(f"\n Sur la page principale ({len(page0_pii)} PII):")
|
|
for pii in page0_pii:
|
|
kind = pii['kind']
|
|
original = pii.get('original', '')
|
|
print(f" ✓ {kind:20s} : {original}")
|
|
|
|
# Noms propagés
|
|
extracted = [p for p in pii_list if 'EXTRACTED' in p.get('kind', '') or 'GLOBAL' in p.get('kind', '')]
|
|
if extracted:
|
|
unique_names = set(p['original'] for p in extracted if 'NOM' in p.get('kind', ''))
|
|
print(f"\n Noms propagés sur tout le document ({len(unique_names)} uniques):")
|
|
for name in sorted(unique_names):
|
|
print(f" → {name}")
|
|
|
|
# Statistiques
|
|
type_counts = Counter(pii['kind'] for pii in pii_list)
|
|
print(f"\n 📊 STATISTIQUES:")
|
|
print(f" Total PII: {len(pii_list)}")
|
|
print(f" Types différents: {len(type_counts)}")
|
|
|
|
# Top 3
|
|
print(f"\n Top 3 des types:")
|
|
for pii_type, count in type_counts.most_common(3):
|
|
print(f" {pii_type:20s} : {count}")
|
|
|
|
# Texte anonymisé
|
|
text_path = output_dir / f"{base_name}.pseudonymise.txt"
|
|
if text_path.exists():
|
|
with open(text_path, 'r', encoding='utf-8') as f:
|
|
anon_text = f.read()
|
|
|
|
print(f"\n📝 TEXTE ANONYMISÉ (extrait):")
|
|
print(" " + "-"*76)
|
|
lines = anon_text.split('\n')[:8]
|
|
for line in lines:
|
|
if line.strip():
|
|
print(f" {line[:76]}")
|
|
print(" " + "-"*76)
|
|
|
|
# Scan de fuite
|
|
if redacted_pdf.exists() and audit_path.exists():
|
|
print(f"\n🔒 VALIDATION DE SÉCURITÉ")
|
|
|
|
scanner = LeakScanner()
|
|
leak_report = scanner.scan(redacted_pdf, audit_path)
|
|
|
|
if leak_report.is_safe:
|
|
print(f" ✅ DOCUMENT SÛR")
|
|
print(f" Aucune fuite de PII détectée")
|
|
print(f" Le document peut être diffusé en toute sécurité")
|
|
else:
|
|
print(f" ⚠️ ATTENTION - {leak_report.leak_count} fuite(s)")
|
|
for severity, count in leak_report.severity_counts.items():
|
|
print(f" {severity}: {count}")
|
|
|
|
# Résumé
|
|
print(f"\n" + "="*80)
|
|
print("✨ RÉSUMÉ")
|
|
print("="*80)
|
|
|
|
print(f"\n✓ Document anonymisé avec succès")
|
|
print(f"✓ {len(page0_pii)} PII détectés et masqués")
|
|
print(f"✓ Propagation globale des noms sur tout le document")
|
|
print(f"✓ Validation de sécurité : AUCUNE FUITE")
|
|
|
|
print(f"\n📂 Fichiers générés:")
|
|
print(f" • PDF anonymisé (raster): {redacted_pdf.name}")
|
|
print(f" • PDF anonymisé (vector): {base_name}.redacted_vector.pdf")
|
|
print(f" • Texte anonymisé: {base_name}.pseudonymise.txt")
|
|
print(f" • Audit détaillé: {base_name}.audit.jsonl")
|
|
|
|
print(f"\n💡 Répertoire: {output_dir}")
|
|
|
|
print(f"\n🎯 PROCHAINES ÉTAPES:")
|
|
print(f" 1. Annoter manuellement ce document")
|
|
print(f" 2. Comparer avec l'évaluateur de qualité")
|
|
print(f" 3. Calculer Précision, Rappel, F1-Score")
|
|
print(f" 4. Identifier les améliorations possibles")
|
|
|
|
print(f"\n" + "="*80)
|
|
|
|
if __name__ == "__main__":
|
|
show_comparison()
|