feat: anonymisation qualité++ — 15 patterns, subparts tirets, fix entity registry

Bloc A: fix sous-parties dans _mappings, filtre NER anti-tag,
intégration patterns manquants (DESTINATAIRE, PRESCRIPTION_AUTHOR),
whitelist médicaments élargie (+60), villes retirées de whitelist.

Bloc B: CRH dedup chars 200-1000, CP_VILLE vrais codes postaux FR,
DR_NAME capital par mot, BACTERIO header tolère ligne vide.

Bloc C: DR_NAME negative lookahead multi-docteurs même ligne,
entity_registry split tirets (RITZ-QUILLACQ), fix early return
subparts dans _find_matching_entity, PRESCRIPTION_AUTHOR élargi
(Révisé/Traité, variable.), NOTE_AUTHOR élargi (Diététicienne,
Kiné, Ergo), + 8 nouveaux patterns (CONTACT_RELATION, MOD_PAR,
AIDE_NAME, SIGNATURE_LINE, VALIDE_PAR, INTERNE_SIGNATURE,
FOIS_NAME, MALADIE_NAME), adresses inline +ALLEE/IMP,
text_cleaner préserve abréviations médicales.

Validé sur 6 cas (21, 11, 104, 160, 50, 200). 70 tests OK.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dom
2026-03-03 11:11:47 +01:00
parent f4a23a5f43
commit 99069f150a
7 changed files with 492 additions and 60 deletions

View File

@@ -86,10 +86,25 @@ def _split_text(text: str, max_chars: int = 500) -> list[str]:
def _deduplicate(entities: list[dict]) -> list[dict]:
"""Déduplique les entités par mot (garde le score le plus élevé)."""
seen: dict[str, dict] = {}
"""Déduplique les entités par position (supprime les chevauchements).
Garde toutes les occurrences d'un même mot à des positions différentes,
mais supprime les entités qui se chevauchent à la même position
(garde celle avec le meilleur score).
"""
if not entities:
return []
# Trier par position de début
entities.sort(key=lambda e: e["start"])
result: list[dict] = []
for ent in entities:
key = ent["word"].lower()
if key not in seen or ent["score"] > seen[key]["score"]:
seen[key] = ent
return list(seen.values())
if result and ent["start"] < result[-1]["end"]:
# Chevauchement : garder celle avec le meilleur score
if ent["score"] > result[-1]["score"]:
result[-1] = ent
else:
result.append(ent)
return result