feat(finess): whitelist de mono-mots distinctifs courts (EMBRUNS, etc.)
Le matcher Aho-Corasick FINESS rejetait tous les mono-mots < 10 chars pour éviter les faux positifs. Conséquence : EMBRUNS (7 chars), présent dans etablissements_distinctifs.txt, était ignoré et devait être forcé en YAML (LES EMBRUNS, REED LES EMBRUNS, EMBRUNS BIDART, regex [Ee]mbruns). Nouveau fichier data/finess/mono_mots_distinctifs.txt contenant la whitelist curée des mono-mots courts considérés comme distinctifs. Maintenance manuelle (un mot par ligne, commentaires autorisés). Le matcher accepte un mono-mot < 10 chars uniquement s'il est dans cette whitelist. Initialisation : embruns, embrun (documents CHCB "Les Embruns"). Validation : - _FINESS_AC matche maintenant "les embruns quelque part" et "embruns seul" - Pas de régression sur trackare-18007562 (122 hits) Après ce fix + futurs, on pourra retirer LES EMBRUNS / REED LES EMBRUNS / EMBRUNS BIDART et regex [Ee]mbruns de force_mask_terms du YAML. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3120,6 +3120,21 @@ def _build_finess_ac():
|
||||
"le bourg", "le val", "le clos", "le mas",
|
||||
"les pins", "les chenes", "les oliviers",
|
||||
}
|
||||
# Whitelist explicite de mono-mots < 10 chars considérés comme distinctifs
|
||||
# (sinon rejetés par le filtre général). Exemple : EMBRUNS (7 chars).
|
||||
# Alimentée depuis data/finess/mono_mots_distinctifs.txt — curation manuelle.
|
||||
mono_file = data_dir / "mono_mots_distinctifs.txt"
|
||||
mono_whitelist: set = set()
|
||||
if mono_file.exists():
|
||||
try:
|
||||
for _line in mono_file.read_text(encoding="utf-8").splitlines():
|
||||
_w = _line.strip()
|
||||
if _w and not _w.startswith("#"):
|
||||
mono_whitelist.add(_w.lower())
|
||||
log.info(f"FINESS mono-mots distinctifs whitelist: {len(mono_whitelist)} entrées")
|
||||
except Exception as _exc:
|
||||
log.warning(f"Erreur chargement mono_mots_distinctifs.txt : {_exc}")
|
||||
|
||||
try:
|
||||
ac = _ahocorasick.Automaton()
|
||||
count = 0
|
||||
@@ -3142,20 +3157,20 @@ def _build_finess_ac():
|
||||
_PRENOM_PREFIXES = {"jean", "marie", "louis", "pierre", "saint", "sainte"}
|
||||
if len(words) == 2 and words[0] in _PRENOM_PREFIXES and len(words[1]) < 10:
|
||||
continue
|
||||
# Filtrer : >= 8 chars et >= 2 mots, OU >= 10 chars pour 1 mot
|
||||
# Les noms courts sont gérés par RE_HOPITAL_VILLE
|
||||
# Filtrer : >= 8 chars et >= 2 mots, OU >= 10 chars pour 1 mot,
|
||||
# OU présent dans la whitelist explicite de mono-mots distinctifs.
|
||||
if len(words) >= 2 and len(name) >= 8:
|
||||
# Exclure les multi-mots dont TOUS les mots sont dans le stop words médical
|
||||
if all(w in _MEDICAL_STOP_WORDS_SET or len(w) <= 2 for w in words):
|
||||
continue
|
||||
ac.add_word(name, name)
|
||||
count += 1
|
||||
elif (len(words) == 1 and len(name) >= 10
|
||||
and name not in _ac_generic_blacklist
|
||||
and name not in _MEDICAL_STOP_WORDS_SET
|
||||
and _normalize_for_matching(name) not in _MEDICAL_STOP_WORDS_SET):
|
||||
ac.add_word(name, name)
|
||||
count += 1
|
||||
elif len(words) == 1 and (len(name) >= 10 or name in mono_whitelist):
|
||||
if (name not in _ac_generic_blacklist
|
||||
and name not in _MEDICAL_STOP_WORDS_SET
|
||||
and _normalize_for_matching(name) not in _MEDICAL_STOP_WORDS_SET):
|
||||
ac.add_word(name, name)
|
||||
count += 1
|
||||
ac.make_automaton()
|
||||
_FINESS_AC = ac
|
||||
log.info(f"Gazetteer FINESS Aho-Corasick: {count} patterns chargés")
|
||||
|
||||
Reference in New Issue
Block a user