feat: externalisation des listes — stop-words et villes modifiables sans code
Toutes les listes de règles sont maintenant modifiables sans toucher au code Python : Fichiers de données (data/) : - stopwords_manuels.txt : 1307 termes médicaux/techniques - villes_blacklist.txt : 117 communes à ne pas matcher - medicaments_stopwords.txt : 7312 médicaments BDPM (existant) - Chargés automatiquement au démarrage Config YAML (dictionnaires.yml) : - additional_stopwords : mots supplémentaires par établissement - additional_villes_blacklist : villes supplémentaires - whitelist_phrases : phrases à ne jamais anonymiser - force_mask_terms : mots à toujours masquer Chaîne de chargement : code dur → fichiers data/ → YAML config Les 3 niveaux se cumulent (union). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -204,6 +204,14 @@ _VILLE_BLACKLIST = {
|
|||||||
# Parties du corps homonymes de communes (FP "prurit invalidant (COU, décolleté)")
|
# Parties du corps homonymes de communes (FP "prurit invalidant (COU, décolleté)")
|
||||||
"COU", "DOS", "SEIN", "BRAS",
|
"COU", "DOS", "SEIN", "BRAS",
|
||||||
}
|
}
|
||||||
|
# Enrichissement depuis fichier externe (modifiable sans toucher au code)
|
||||||
|
_villes_bl_file = Path(__file__).parent / "data" / "villes_blacklist.txt"
|
||||||
|
if _villes_bl_file.exists():
|
||||||
|
for _line in _villes_bl_file.read_text(encoding="utf-8").splitlines():
|
||||||
|
_w = _line.strip()
|
||||||
|
if _w and not _w.startswith("#"):
|
||||||
|
_VILLE_BLACKLIST.add(_w)
|
||||||
|
log.info("Villes blacklist chargées : %d entrées", len(_VILLE_BLACKLIST))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ahocorasick as _ahocorasick
|
import ahocorasick as _ahocorasick
|
||||||
@@ -772,6 +780,17 @@ _MEDICAL_STOP_WORDS_SET = {
|
|||||||
# Enrichissement automatique avec les ~4000 noms de médicaments d'edsnlp
|
# Enrichissement automatique avec les ~4000 noms de médicaments d'edsnlp
|
||||||
_MEDICAL_STOP_WORDS_SET.update(_load_edsnlp_drug_names())
|
_MEDICAL_STOP_WORDS_SET.update(_load_edsnlp_drug_names())
|
||||||
|
|
||||||
|
# Enrichissement depuis fichier externe (modifiable sans toucher au code)
|
||||||
|
_stopwords_file = Path(__file__).parent / "data" / "stopwords_manuels.txt"
|
||||||
|
if _stopwords_file.exists():
|
||||||
|
_sw_count = 0
|
||||||
|
for _line in _stopwords_file.read_text(encoding="utf-8").splitlines():
|
||||||
|
_w = _line.strip()
|
||||||
|
if _w and not _w.startswith("#"):
|
||||||
|
_MEDICAL_STOP_WORDS_SET.add(_w)
|
||||||
|
_sw_count += 1
|
||||||
|
log.info("Stop-words manuels chargés : %d mots depuis %s", _sw_count, _stopwords_file.name)
|
||||||
|
|
||||||
# Enrichissement BDPM : ~7300 noms commerciaux + DCI/substances actives
|
# Enrichissement BDPM : ~7300 noms commerciaux + DCI/substances actives
|
||||||
_bdpm_path = Path(__file__).parent / "data" / "bdpm" / "medicaments_stopwords.txt"
|
_bdpm_path = Path(__file__).parent / "data" / "bdpm" / "medicaments_stopwords.txt"
|
||||||
if _bdpm_path.exists():
|
if _bdpm_path.exists():
|
||||||
@@ -1053,6 +1072,22 @@ def load_dictionaries(config_path: Optional[Path]) -> Dict[str, Any]:
|
|||||||
cfg[k] = v
|
cfg[k] = v
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Charger les stop-words et villes supplémentaires depuis le YAML
|
||||||
|
extra_sw = cfg.get("additional_stopwords", [])
|
||||||
|
if extra_sw:
|
||||||
|
for w in extra_sw:
|
||||||
|
if w and str(w).strip():
|
||||||
|
_MEDICAL_STOP_WORDS_SET.add(str(w).strip().lower())
|
||||||
|
log.info("Stop-words YAML supplémentaires : %d", len(extra_sw))
|
||||||
|
|
||||||
|
extra_villes = cfg.get("additional_villes_blacklist", [])
|
||||||
|
if extra_villes:
|
||||||
|
for v in extra_villes:
|
||||||
|
if v and str(v).strip():
|
||||||
|
_VILLE_BLACKLIST.add(str(v).strip().upper())
|
||||||
|
log.info("Villes blacklist YAML supplémentaires : %d", len(extra_villes))
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
# ----------------- Extraction -----------------
|
# ----------------- Extraction -----------------
|
||||||
|
|||||||
@@ -60,6 +60,18 @@ whitelist_phrases:
|
|||||||
- "date de sortie"
|
- "date de sortie"
|
||||||
- "date d'admission"
|
- "date d'admission"
|
||||||
- "code postal"
|
- "code postal"
|
||||||
|
# Mots supplémentaires à ne jamais masquer comme noms de personnes
|
||||||
|
# (complète les 9000+ stop-words intégrés)
|
||||||
|
additional_stopwords: []
|
||||||
|
# Exemple :
|
||||||
|
# - "votre_mot"
|
||||||
|
|
||||||
|
# Villes supplémentaires à ne jamais matcher comme lieux
|
||||||
|
# (complète les 115+ villes blacklistées intégrées)
|
||||||
|
additional_villes_blacklist: []
|
||||||
|
# Exemple :
|
||||||
|
# - "VOTRE_VILLE"
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
case_insensitive: true
|
case_insensitive: true
|
||||||
unicode_word_boundaries: true
|
unicode_word_boundaries: true
|
||||||
|
|||||||
1311
data/stopwords_manuels.txt
Normal file
1311
data/stopwords_manuels.txt
Normal file
File diff suppressed because it is too large
Load Diff
121
data/villes_blacklist.txt
Normal file
121
data/villes_blacklist.txt
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Villes/communes à ne jamais matcher comme noms de lieux
|
||||||
|
# (homonymes de mots courants, parties du corps, etc.)
|
||||||
|
# Total : 117 entrées
|
||||||
|
|
||||||
|
AGEN
|
||||||
|
AIRE
|
||||||
|
ALBI
|
||||||
|
ANNE
|
||||||
|
AUCH
|
||||||
|
BARRES
|
||||||
|
BEAUNE
|
||||||
|
BILLE
|
||||||
|
BLOIS
|
||||||
|
BOIS
|
||||||
|
BOURG
|
||||||
|
BRAS
|
||||||
|
BREST
|
||||||
|
CENTRE
|
||||||
|
CERGY
|
||||||
|
CHAISE
|
||||||
|
CHARGE
|
||||||
|
COEUR
|
||||||
|
CONTRE
|
||||||
|
CORPS
|
||||||
|
COU
|
||||||
|
COURANT
|
||||||
|
COURS
|
||||||
|
CREIL
|
||||||
|
CROIX
|
||||||
|
DOLE
|
||||||
|
DOS
|
||||||
|
EST
|
||||||
|
EUROPE
|
||||||
|
EVIAN
|
||||||
|
FAUX
|
||||||
|
FOIX
|
||||||
|
FORT
|
||||||
|
FOSSES
|
||||||
|
FRANCE
|
||||||
|
GARDES
|
||||||
|
GIEN
|
||||||
|
GIVET
|
||||||
|
GRAND
|
||||||
|
GRAY
|
||||||
|
HYERES
|
||||||
|
ISLE
|
||||||
|
JEAN
|
||||||
|
JOUE
|
||||||
|
LACS
|
||||||
|
LAON
|
||||||
|
LENS
|
||||||
|
LIGNE
|
||||||
|
LIGNES
|
||||||
|
LONG
|
||||||
|
LUNEL
|
||||||
|
LURE
|
||||||
|
MAISON
|
||||||
|
MARCHE
|
||||||
|
MARIE
|
||||||
|
MARS
|
||||||
|
MARSA
|
||||||
|
MAURE
|
||||||
|
MEAUX
|
||||||
|
MENDE
|
||||||
|
MENTON
|
||||||
|
MERE
|
||||||
|
MONT
|
||||||
|
MORET
|
||||||
|
MOULIN
|
||||||
|
MURET
|
||||||
|
MURS
|
||||||
|
Médecin courant
|
||||||
|
NICE
|
||||||
|
NORD
|
||||||
|
NUITS
|
||||||
|
ONDRES
|
||||||
|
ORANGE
|
||||||
|
OUEST
|
||||||
|
OUST
|
||||||
|
PARIS
|
||||||
|
PAUL
|
||||||
|
PIERRE
|
||||||
|
PLACE
|
||||||
|
PLAN
|
||||||
|
PONT
|
||||||
|
PORT
|
||||||
|
PREY
|
||||||
|
PRISON
|
||||||
|
PUITS
|
||||||
|
QUATRE
|
||||||
|
RANS
|
||||||
|
RECY
|
||||||
|
REDON
|
||||||
|
REZE
|
||||||
|
RICHE
|
||||||
|
ROMANS
|
||||||
|
ROUGE
|
||||||
|
SAINT
|
||||||
|
SALLE
|
||||||
|
SALON
|
||||||
|
SARE
|
||||||
|
SEIN
|
||||||
|
SENS
|
||||||
|
SERVICE
|
||||||
|
SETE
|
||||||
|
SIGNES
|
||||||
|
SORE
|
||||||
|
SOURCE
|
||||||
|
SUD
|
||||||
|
TOURS
|
||||||
|
TRANS
|
||||||
|
VALLEE
|
||||||
|
VAUX
|
||||||
|
VEBRE
|
||||||
|
VERS
|
||||||
|
VERT
|
||||||
|
VIENNE
|
||||||
|
VILLE
|
||||||
|
VIRE
|
||||||
|
VITRE
|
||||||
|
prurit invalidant (COU, décolleté)
|
||||||
Reference in New Issue
Block a user