Commit Graph

21 Commits

Author SHA1 Message Date
f188116bc1 fix: Propagation globale sélective pour corriger fuites dates CRO
Problème:
- 36 CRO avec fuites dates de naissance (Né(e) le DD/MM/YYYY)
- Dates détectées page 0 mais pas propagées pages suivantes
- Désactivation propagation globale avait éliminé 951 FP mais créé fuites

Solution:
- Propagation SÉLECTIVE: uniquement PII critiques (DATE_NAISSANCE, NIR, IPP, EMAIL, force_term)
- PII non-critiques (TEL, ADRESSE, etc.) NON propagés (évite 951 FP)
- Remplacement amélioré: gère variations format dates (/, ., -, espaces)
- Gère contexte 'Né(e) le' avec case-insensitive

Impact attendu:
- Rappel: 100% (plus de fuites)
- Précision: 85-87% (légère baisse vs 88.27%, mais acceptable)
- FP réintroduits: ~10-20 (vs 951 avant)

Fichiers:
- anonymizer_core_refactored_onnx.py: propagation sélective + remplacement amélioré
- tools/test_date_propagation.py: script test sur CRO
- LEAK_FIX.md: documentation complète de la correction
2026-03-02 11:59:32 +01:00
6806aee587 feat: Filtre hospitalier pour éliminer les faux positifs
- Ajout config/hospital_stopwords.yml avec adresses/téléphones hôpitaux
- Ajout detectors/hospital_filter.py pour filtrer les FP
- Intégration dans anonymizer_core_refactored_onnx.py
- Test sur document: 40 -> 32 détections (-8 FP)
- Élimine: adresses hôpitaux, codes postaux CEDEX, épisodes dans noms de fichiers
2026-03-02 11:21:48 +01:00
70ff0b9e12 feat: Désactivation NOM_EXTRACTED et *_GLOBAL - Précision 18.97% → 88.27% (+69.3pts) 2026-03-02 11:15:43 +01:00
cb84698c2d Stop words +170 : détection automatique FP via dictionnaire français (audit_fp_detector.py)
- Nouvel outil audit_fp_detector.py : croise NOM_GLOBAL avec dictionnaire FR (346K mots),
  patterns morphologiques médicaux, mots structurels DPI, fréquence inter-documents
- +170 stop words en 2 lots : termes médicaux (abdomen, bilirubine, gastrique...),
  soins infirmiers (bijoux, ongles, maquillage, habillage...), mots courants (angle, bureau...)
- Ville basque ajoutée : anglet
- Résultat : 192/199 FP détectés couverts, 7 restants = artefacts OCR de vrais noms
- Total stop words : 5076 tokens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 10:04:33 +01:00
84be2a5176 Stop words : +15 FP supplémentaires (apyréxie, mode, retraitée, villes, ass, cat)
Audit OGC 17/74 : ajout variante accentuée apyréxie, termes courants
(mode, retraitée, régression, tel) et noms de villes françaises pour
éviter leur masquage comme NOM_GLOBAL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:46:04 +01:00
7991436caa Fix faux positifs NOM : +50 stop words médicaux, blacklist companion, limite RE_EXTRACT_STAFF_ROLE
Audit OGC 21 : termes médicaux (ALIMENTATION, BCY, CAT, VOIES, BILIAIRES,
CLAVULANIQUE, TAZOBACTAM...) incorrectement masqués comme [NOM].
- Ajout ~50 termes médicaux/courants aux stop words
- Ajout ~30 termes à _COMPANION_BLACKLIST
- RE_EXTRACT_STAFF_ROLE limité à 2 tokens ALL-CAPS max ({0,2} vs *)
Batch 59 OGC : 0 résidu, 0 FP médical connu dans NOM_GLOBAL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:28:29 +01:00
96d55584c7 Fix 62 fuites résiduelles : DATE_NAISSANCE global, CHCB, Centre Hospitalier de la Côte Basque
- RE_HOPITAL_VILLE : ajout articles (la/le/l'/les) après prépositions
- DATE_NAISSANCE + force_term + force_regex : propagation globale cross-pages
- Config : org_gpe_keep=false, CHCB + variantes Centre Hospitalier en force_mask
- Audit 130 fichiers : 0 résidu (était 36 DATE_NAISS + 26 ETAB)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 12:07:58 +01:00
0684b77d68 Qualité anonymisation : 10 améliorations (audit 59 OGC, +98% établissements, 0 FP médical)
- RE_ETABLISSEMENT élargi (CH/CHU/CHRU/CHS/HIA/CLCC/GHT/GCS), CH/CHS exigent un nom après
- RE_HOPITAL_VILLE enrichi (Centre de Soins, Maison de Santé/Retraite, Résidence, Foyer)
- Nouveau RE_SERVICE (service/unité/pôle/département + nom propre)
- org_gpe_keep=False : NER masque désormais ORG/LOC
- +40 stop words (oncologie, confrères, préparations, spécialités médicales...)
- RE_IBAN accepte espaces (groupes de 4, format standard)
- RE_TEL tiret échappé + nouveau RE_TEL_COMPACT (numéros collés 0612345678)
- RE_ADRESSE +10 types de voies (lotissement, hameau, esplanade, côte...)
- RE_AGE élargi (patiente 72 ans, , 88 ans, (85A))
- Blacklist companion tokens (27 mots génériques/spécialités médicales)
- Propagation globale VLM_SERVICE et VLM_ETAB

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 10:43:30 +01:00
86274b3b2a Sécurité VLM : format JSON forcé, modèle local uniquement, fix logging critique
- vlm_manager: ajout format:json dans payload Ollama (élimine hallucinations JSON)
- vlm_manager: retour modèle local qwen2.5vl:7b (sécurité données médicales)
- anonymizer_core: ajout import logging (fix NameError silencieux qui tuait le VLM)
- anonymizer_core: masquage direct pages manuscrites (suppression rotation inutile)
- GUI: intégration checkbox VLM + auto-load EDS-Pseudo prioritaire

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 02:38:30 +01:00
125ac82f4f VLM v2 : prompt élargi (19 catégories PII), modèle 235b cloud, masquage total pages manuscrites
- vlm_manager.py : nouvelles catégories (NUMERO_LOT, NUMERO_PATIENT, NUMERO_ORDONNANCE,
  SERVICE, ETABLISSEMENT, DATE, AGE, NDA), prompt détaillé pour identifiants médicaux
  (EFS, lots PSL, services hospitaliers), modèle par défaut qwen3-vl:235b-instruct-cloud,
  parser JSON robuste (réparation troncature), num_predict 8192
- anonymizer_core_refactored_onnx.py : FULL_PAGE_MASK pour pages manuscrites
  (OCR < 100 mots + VLM PII ou VLM en échec), matching flou pour numéros manuscrits
  (_search_ocr_words_fuzzy_digits), auto-rotation VLM (4 orientations),
  fix label OGC doublé, support nouveaux kinds VLM dans redact_pdf_raster

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 02:08:02 +01:00
f206d160f4 Intégration VLM (Ollama) pour anonymisation des PDFs scannés
- Ajout paramètre vlm_manager à process_pdf()
- Nouvelle fonction _apply_vlm_on_scanned_pdf() : envoie chaque page
  au VLM (qwen2.5vl) pour détecter visuellement les PII
- Les entités VLM sont ajoutées à l'audit et au texte pseudonymisé
- Dégradation gracieuse : si Ollama indisponible, le pipeline continue
- Actif uniquement sur les PDFs scannés (ocr_used=True)
- Testé sur 2 scans : LACAZE/PAUL/CAPDUPUY détectés et masqués (0 PII résiduel)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 01:10:16 +01:00
4583283bd4 Fix 2 fuites PII : prénom REGINA + nom composé NOCENT-EJNAINI cross-line
- Retirer "regina" de _MEDICAL_STOP_WORDS_SET (bloquait la détection du prénom)
- Ajouter regex "Prénom de naissance" / "Prénom utilisé" dans _extract_document_names
- Substitution tolérante aux sauts de ligne pour noms composés (tiret + \s*)
- Conserver les parties longues (>=5 chars) des noms composés dans _global_name_tokens
  au lieu de les supprimer (le texte PDF peut les scinder sur des lignes séparées)

Vérifié : REGINA 33→0, NOCENT 90→0, EJNAINI 90→0 occurrences en clair

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:41:40 +01:00
28da29f521 Perf x56 : parallélisation raster + dédup tokens vector (30min → 32s sur 4 PDFs)
- Rasterisation parallèle (ProcessPoolExecutor) : _rasterize_page worker par page
- Déduplication tokens dans redact_pdf_vector : 401 hits → 28 tokens uniques par page
- Séparation phase search / phase annotate pour éviter dégradation PyMuPDF
- Déduplication tokens dans redact_pdf_raster (Phase 1)
- Index by_page dict au lieu de filtrage linéaire par page
- Ajout process_pdfs_batch() pour batch multi-PDF sans NER
- Support OCR word map dans vector et raster (fallback PDFs scannés)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:13:20 +01:00
ac62a722bb Fix FP résiduels (Glyc, VIDER, FORTE) + rétrécissement rectangles masquage
- Ajout glyc, glycosurie, vider, forte aux stop words médicaux
- Shrink horizontal de 1.5px sur les rectangles raster pour éviter
  le débordement sur le texte adjacent (issue rectangles trop larges)
- Batch 10 OGC : 21 OK, 0 PII résiduel, 0 FP

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:25:13 +01:00
0eb27343cc Réduction sur-masquage : stop words trackare/CRH + filtre NOM_GLOBAL court
- Ajout ~30 stop words : abréviations soins trackare (SOINS, LIT, JEUN, LEVER,
  SURV, GGT, VVP, VERIF, NFS...) et mots narratifs CRH capturés par fusion
  sidebar 2-colonnes (Evolution, Explorations, Cholécystectomie, Paracétamol...)
- Filtre NOM_GLOBAL renforcé : mots ALL-CAPS ≤4 chars confirmés par une seule
  source regex sont rejetés (probables abréviations médicales, pas des noms)
- Résultat batch 10 OGC : CRH 23042753 passe de 326 à 284 hits

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:09:41 +01:00
50b6f6b70f Fix FP : ajout HGT (hémoglucose test) aux stop words médicaux
Évite que le sigle HGT/Hgt soit masqué comme [NOM] dans les trackare (23 occurrences sur OGC 316).
Validé sur batch 20 OGC (42 OK, 0 PII résiduel, 0 FP).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 19:26:11 +01:00
6c82def02c Amélioration qualité anonymisation : dico médicaments auto, noms soignants, garde trackare, validation EDS, QC audit
- Track A : chargement automatique de ~4200 noms de médicaments depuis edsnlp/drugs.json dans _MEDICAL_STOP_WORDS_SET (réduit les faux positifs médicaments)
- Track B : règles de validation EDS par type (NOM rejeté si contexte dosage, HOPITAL rejeté si < 5 chars ou mot structurel)
- Track C : nouveau script qc_audit.py pour contrôle qualité post-anonymisation (scan FN résiduels, densité placeholders, FP/FN candidats, mode batch CSV)
- Track D : garde structurelle trackare — NOM_GLOBAL <= 3 chars ignoré dans les documents trackare pour éviter de masquer des codes diagnostics
- Track E : détection enrichie des noms soignants (Pr/Professeur, Prescripteur, Prescrit par, Exécuté par, Réalisé par)

Testé sur 3 OGC (407, 316, 589) — 4 PDFs, 0 erreur, 0 PII résiduel, 0 faux positif détecté.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:58:18 +01:00
a138b26738 Fix faux positifs PDF (EDS_TEL, EDS_VILLE) + détection noms Notes IDE
- Skip EDS_TEL dans PDF (valeurs Pouls détectées comme N° de téléphone)
- Ajout EDS_VILLE au whole-word matching (évite "GEL" dans "GELULE")
- Filtre stop words étendu à EDS_HOPITAL et EDS_VILLE dans la détection NER
- Détection noms soignants dans "Note IDE\nPrenom NOM" (BARGAIN, LACOTE, etc.)
- Stop words : semaine, jour, matin, soir, nuit, midi

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:22:38 +01:00
2236fdcd01 Correction majeure des faux positifs et fuites d'anonymisation PDF
- Fix fuites critiques trackare : extraction multi-occurrences (re.finditer),
  noms soignants multi-lignes, N° épisode, tokens GLOBAL sur final_text
- Fix faux positifs PDF : whole-word matching pour tokens courts (<5 chars)
  au lieu de les ignorer (corrige Emma/Lili non masqués + évite substring)
- Skip EDS_SECU dans PDF (valeurs vitales PA/Pouls détectées comme N° sécu)
- Skip EDS_DATE dans PDF (dates rendaient les tableaux illisibles)
- Filtre dosages détectés comme noms (10MG, 300UI, 1 000)
- Filtre EDS_NOM multi-mots contenant des stop words (SI DIARRHEES)
- Regex CODE_POSTAL : exclure unités médicales (13000 UI ≠ code postal)
- Stop words massivement enrichis (~100+ termes médicaux, médicaments,
  abréviations, en-têtes de colonnes trackare)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:01:32 +01:00
5ed2312d93 Amélioration majeure de l'anonymisation regex : trackare, noms composés, faux positifs
- Parseur trackare spécifique (détection par contenu, extraction structurée des PII)
- Support format "Dr X. NOM" et "Mme X. NOM" (initiales + noms composés avec tiret)
- Détection noms personnel médical (Aide, Cadre Infirmier, etc.)
- Masquage RPPS, établissements (EHPAD/SSR/USLD standalone), lieux de naissance
- Stop words médicaux enrichis (~270 entrées : DCI, spécialités, termes contextuels)
- Détection compagnon (noms adjacents à des noms connus dans le texte brut)
- Protection noms composés (JEAN-PIERRE traité comme un tout, pas JEAN + PIERRE)
- Nettoyage codes postaux orphelins, téléphones fragmentés/partiels
- Désactivation masquage dates génériques, AGE avec contexte obligatoire
- GUI : extraction OGC depuis le nom du répertoire parent, incrustation sur les pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:25:18 +01:00
8339069c83 Initial commit — Pseudonymisation de PDF v5
- GUI v5 : vue unique épurée (tkinter), 2 étapes visuelles
- Core ONNX : anonymisation regex + NER optionnel
- Extraction globale des noms depuis champs structurés
  (Patient, Rédigé par, MME/Madame, DR)
- Génération simultanée PDF Image + PDF Anonymisé (structure préservée)
- Build Windows via Nuitka (script batch + GitHub Actions CI)
- install.sh pour setup/run Linux

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 15:03:37 +01:00