feat(detect): paranames loader + fallback étendu cross-validation
Préparation à l'intégration du gazetteer paranames (Wikidata CC BY 4.0,
Sälevä & Lignos LREC-COLING 2024) qui couvrira les noms étrangers en
France absents du gazetteer INSEE (basques, maghrébins, asiatiques,
africains, etc.).
## Loader
- `_PARANAMES_NOMS_SET` + `_PARANAMES_LOADED` (cache global)
- `_load_paranames_noms()` : lazy load au 1er besoin
- Fichier cible : `data/paranames/noms_famille_world.txt.gz`
- Si fichier absent : retourne set vide, log INFO, comportement actuel
(INSEE seul) — fallback transparent
- Si erreur de lecture : log WARNING, fallback INSEE
## Intégration cross-validation
Dans `_cross_validate_name_candidates`, `is_in_insee` étendu :
is_in_insee = (tok_upper in insee_noms or tok_upper in insee_prenoms
or tok_upper in _load_paranames_noms())
Effets :
- En contexte "low" + non NER : un token comme OYARCABAL (basque) ou
EJNAINI (maghrébin) sera désormais accepté si présent dans paranames.
- Aucun changement pour noms FR (déjà dans INSEE).
- Aucune régression : si le fichier paranames n'est pas généré, le
comportement est strictement identique.
## Génération du gazetteer
Le script de génération `scripts/build_paranames_gazetteer.py` et le
fichier `data/paranames/noms_famille_world.txt.gz` sont produits par un
agent dédié en cours d'exécution. Commit séparé à venir avec :
- Script de génération
- README + attribution CC BY 4.0
- Fichier gazetteer
## Tests
74 passed sur 75 (1 test happy path Q-1) + 10 xfailed. 5 tests
synthetic_review cassés (non liés à ce commit — issue séparée du
CHCB cleanup à fixer dans un commit dédié).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -187,6 +187,47 @@ _INSEE_PRENOMS_SET: set = set() # uppercase sans accents
|
||||
_INSEE_COMMUNES: set = set() # uppercase
|
||||
_INSEE_NOMS_FAMILLE: set = set() # uppercase sans accents
|
||||
|
||||
# Gazetteer mondial paranames (Wikidata CC BY 4.0 — Sälevä & Lignos 2024)
|
||||
# Fallback étendu après INSEE pour couvrir les noms étrangers présents en
|
||||
# France (basques, maghrébins, asiatiques, africains, etc.) absents du
|
||||
# gazetteer INSEE France. Chargé en lazy (au 1er besoin) pour ne pas
|
||||
# pénaliser le splash de démarrage.
|
||||
_PARANAMES_NOMS_SET: set = set()
|
||||
_PARANAMES_LOADED: bool = False
|
||||
|
||||
|
||||
def _load_paranames_noms() -> set:
|
||||
"""Charge le gazetteer paranames (Wikidata) en lazy.
|
||||
|
||||
Fichier attendu : data/paranames/noms_famille_world.txt.gz
|
||||
Si absent, retourne set vide (fallback transparent — comportement actuel).
|
||||
|
||||
Cible : couvrir les noms étrangers présents en France absents d'INSEE
|
||||
(basques, maghrébins, asiatiques, africains, etc.).
|
||||
"""
|
||||
global _PARANAMES_NOMS_SET, _PARANAMES_LOADED
|
||||
if _PARANAMES_LOADED:
|
||||
return _PARANAMES_NOMS_SET
|
||||
_PARANAMES_LOADED = True
|
||||
# Chercher le fichier relatif au module (compat dev + EXE PyInstaller)
|
||||
try:
|
||||
base = Path(__file__).parent
|
||||
except NameError:
|
||||
base = Path.cwd()
|
||||
path = base / "data" / "paranames" / "noms_famille_world.txt.gz"
|
||||
if not path.exists():
|
||||
log.info("paranames gazetteer absent (%s) — fallback INSEE seul", path)
|
||||
return _PARANAMES_NOMS_SET
|
||||
try:
|
||||
import gzip
|
||||
with gzip.open(path, "rt", encoding="utf-8") as f:
|
||||
_PARANAMES_NOMS_SET = {line.strip() for line in f if line.strip()}
|
||||
log.info("paranames loaded: %d noms (CC BY 4.0 — Sälevä & Lignos 2024)",
|
||||
len(_PARANAMES_NOMS_SET))
|
||||
except Exception as e:
|
||||
log.warning("paranames load failed: %s — fallback INSEE seul", e)
|
||||
return _PARANAMES_NOMS_SET
|
||||
|
||||
|
||||
def _normalize_nfkd_upper(s: str) -> str:
|
||||
"""Supprime les accents et met en majuscules (pour matching INSEE)."""
|
||||
@@ -2355,7 +2396,12 @@ def _cross_validate_name_candidates(
|
||||
tok_lower = tok.lower()
|
||||
|
||||
is_ner_confirmed = tok_upper in ner_confirmed_tokens
|
||||
is_in_insee = tok_upper in insee_noms or tok_upper in insee_prenoms
|
||||
# is_in_insee → étendu à paranames (gazetteer mondial Wikidata) en
|
||||
# fallback : couvre les noms étrangers en France (basques, maghrébins,
|
||||
# asiatiques, africains, etc.) absents du gazetteer INSEE France.
|
||||
# paranames est chargé en lazy au 1er appel (cache global).
|
||||
is_in_insee = (tok_upper in insee_noms or tok_upper in insee_prenoms
|
||||
or tok_upper in _load_paranames_noms())
|
||||
is_stopword = tok_lower in medical_stopwords
|
||||
|
||||
strength = cand.context_strength
|
||||
|
||||
Reference in New Issue
Block a user