feat: Phase 1 - Système d'évaluation de la qualité

- 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
This commit is contained in:
2026-03-02 10:07:41 +01:00
parent 0067738df6
commit 340348b820
86 changed files with 35587 additions and 40 deletions

185
FONCTIONNEMENT.md Normal file
View File

@@ -0,0 +1,185 @@
# Programme d'anonymisation de documents PDF
**Fichier principal** : `anonymizer_core_refactored_onnx.py`
Pipeline de pseudonymisation combinant extraction de texte multi-passes,
detection par expressions regulieres, reconnaissance d'entites nommees (NER)
et propagation globale des donnees personnelles.
Produit trois fichiers : texte anonymise, journal d'audit et PDF caviarde.
---
<div style="page-break-before: always;"></div>
## Pipeline de traitement
```
┌─────────────────┐
│ PDF d'entree │
└────────┬────────┘
┌──────────────────────────────────────┐
│ 1. EXTRACTION DE TEXTE │
│ │
│ pdfplumber ─► pdfminer ─► PyMuPDF │
│ ─► docTR OCR ─► tesseract │
│ │
│ (5 passes, meilleur resultat retenu) │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ 2. ANONYMISATION REGEX │
│ │
│ EMAIL · TEL · IBAN · NIR · IPP/ADM │
│ FINESS · RPPS · OGC · dates │
│ adresses · force-mask YAML │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ 3. NER (optionnel) │
│ │
│ EDS-Pseudo (AP-HP, F1=0.97) │
│ ou distilcamembert ONNX │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ 4. EXTRACTION TRACKARE │
│ │
│ Identite patient + soignants │
│ N° episode · pattern Prenom/NOM │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ 5. CONSOLIDATION GLOBALE │
│ │
│ Propagation des PII sur toutes les │
│ pages · noms compagnons · noms │
│ composes traites en bloc │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ 6. RESCAN SELECTIF + NETTOYAGE │
│ │
│ TEL fragmentes · CP orphelins │
│ tokens globaux sur texte final │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ FICHIERS DE SORTIE │
│ │
│ .pseudonymise.txt texte anonymise │
│ .audit.jsonl journal audit │
│ .redacted_raster.pdf PDF caviarde │
└──────────────────────────────────────┘
```
---
<div style="page-break-before: always;"></div>
## Detail des etapes
### 1. Extraction de texte
Fonction : `extract_text_with_fallback_ocr`
5 passes successives, chaque passe sert de fallback si la precedente
ne produit pas assez de contenu :
| Passe | Moteur | Role |
|-------|--------------|----------------------------------------------|
| 1 | pdfplumber | Extraction textuelle native |
| 2 | pdfminer | Extraction alternative (LAParams) |
| 3 | PyMuPDF | Fallback si artefacts `(cid:xx)` |
| 4 | docTR OCR | OCR deep learning pour PDF scannes |
| 5 | tesseract | OCR complementaire |
Pour les PDF scannes, docTR et tesseract sont executes en parallele ;
le meilleur resultat est retenu page par page.
### 2. Anonymisation regex
Fonction : `_mask_line_by_regex`
| Type | Placeholder | Exemple |
|---------------|----------------|----------------------|
| Email | `[EMAIL]` | nom@domaine.fr |
| Telephone | `[TEL]` | 01 23 45 67 89 |
| IBAN | `[IBAN]` | FR76 3000 ... |
| NIR (secu) | `[NIR]` | 1 85 05 78 ... |
| IPP / ADM | `[IPP]` | IPP : 123456 |
| FINESS | `[FINESS]` | FINESS : 750000001 |
| RPPS | `[RPPS]` | RPPS : 12345678901 |
| OGC | `[OGC]` | N OGC : ABC-123 |
| Dates | `[DATE]` | 12/03/2024 |
| Adresses | `[ADRESSE]` | 12 rue de la Paix |
Configuration supplementaire via `config/dictionnaires.yml` :
listes blanches, force-mask et regex personnalisees.
### 3. Reconnaissance d'entites nommees (NER)
S'applique sur le texte narratif (hors tableaux) apres les regles regex.
- **EDS-Pseudo** (`eds_pseudo_manager.py`) : modele AP-HP (F1=0.97) via edsnlp.
13 labels : NOM, PRENOM, MAIL, TEL, SECU, ADRESSE, ZIP, VILLE,
HOPITAL, DATE, DATE_NAISSANCE, IPP, NDA.
- **ONNX fallback** : `cmarkea/distilcamembert-base-ner` via onnxruntime.
### 4. Extraction Trackare
Fonction : `_extract_trackare_identity`
Pour les documents Trackare (logiciel medical), extraction des champs
d'identite structures : nom/prenom patient, adresse, date de naissance,
numeros d'episode (NDA), et noms des soignants.
Gere le pattern multi-lignes "Prenom\nNOM" courant dans ces documents.
### 5. Consolidation globale
Les PII detectes sont propages sur l'ensemble du document :
- **NOM_GLOBAL** : chaque token de nom masque dans toutes les pages.
Detection de "noms compagnons" (mot en majuscules adjacent a un nom connu).
- **TEL_GLOBAL, EMAIL_GLOBAL, ADRESSE_GLOBAL**, etc. : propagation globale
des valeurs uniques.
- Noms composes (ex: JEAN-PIERRE) traites comme un bloc.
### 6. Rescan selectif et nettoyage
Rescan des PII critiques (EMAIL, TEL, IBAN, NIR) ayant echappe
au premier passage. Nettoyage des codes postaux orphelins
et numeros de telephone fragmentes sur plusieurs lignes.
Application des tokens globaux sur le texte pseudonymise final.
---
## Generation du PDF caviarde
Pour les PDF textuels, les coordonnees des zones sensibles sont obtenues
via `page.search_for()` (PyMuPDF). Pour les PDF scannes (image only),
un fallback OCR est utilise :
- **docTR** : localisation mot par mot avec decoupe sur changement de casse
(tokens OCR fusionnes comme "GUILNGARAnne") + reconstruction de lignes
pour detecter les patterns TEL et IPP.
- **tesseract** : complement sur copie propre de l'image pour les numeros
de telephone (non detectes par docTR).
---
## Configuration et utilisation
| Element | Description |
|-------------------------------|------------------------------------------------|
| `config/dictionnaires.yml` | Listes blanches, force-mask, regex custom |
| `Pseudonymisation_Gui_V5.py` | Interface graphique (traitement par lots) |
| Ligne de commande | `python anonymizer_core_refactored_onnx.py fichier.pdf --hf --raster` |