- Sélection et copie de 27 documents représentatifs (10 simples, 12 moyens, 5 complexes) - Outil d'annotation CLI complet (tools/annotation_tool.py) - Guide d'annotation détaillé (docs/annotation_guide.md) - Évaluateur de qualité (evaluation/quality_evaluator.py) * Calcul Précision, Rappel, F1-Score * Identification faux positifs/négatifs * Métriques par type de PII * Export JSON et rapports texte - Scanner de fuite (evaluation/leak_scanner.py) * Détection PII résiduels (CRITIQUE) * Détection nouveaux PII (HAUTE) * Scan métadonnées PDF (MOYENNE) - Benchmark de performance (evaluation/benchmark.py) * Mesure temps de traitement * Mesure CPU/RAM * Export JSON/CSV - Tests unitaires complets pour tous les composants - Documentation complète du module d'évaluation Tâches complétées: - 1.1.1 Sélection de 27 documents (au lieu de 30) - 1.1.2 Outil d'annotation CLI - 1.2.1 Évaluateur de qualité - 1.2.2 Scanner de fuite - 1.2.3 Benchmark de performance Prochaines étapes: - 1.1.3 Annotation des 27 documents (manuel) - 1.1.4 Enrichissement stopwords médicaux - 1.3 Mesure de la baseline
263 lines
6.6 KiB
Markdown
263 lines
6.6 KiB
Markdown
# 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** :
|
||
```python
|
||
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** :
|
||
```python
|
||
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** :
|
||
```python
|
||
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 :
|
||
```bash
|
||
pip install pymupdf psutil
|
||
```
|
||
|
||
## Tests
|
||
|
||
Exécuter les tests unitaires :
|
||
```bash
|
||
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 :
|
||
```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é) :
|
||
```json
|
||
{"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.
|