feat(detect): paranames gazetteer Wikidata (1.4M noms + 502K prénoms)

Intégration de paranames (bltlab/paranames v2024.05.07.0, CC BY 4.0)
pour étendre la couverture du gazetteer aux noms étrangers en France
absents d'INSEE (basques, maghrébins, asiatiques, africains, etc.).

## Citation

Sälevä, J., & Lignos, C. (2024). ParaNames 1.0: Creating an Entity Name
Corpus for 400+ Languages using Wikidata. In Proceedings of LREC-COLING
2024. https://aclanthology.org/2024.lrec-main.1103/

## Fichiers

- scripts/build_paranames_gazetteer.py — script reproductible
- data/paranames/README.md — attribution + procédure
- data/paranames/EXTRACTION.md — workflow reproductible
- data/paranames/noms_famille_world.txt.gz — 1 379 609 noms (4.3 Mo gz, <30 Mo RAM)
- data/paranames/prenoms_world.txt.gz — 502 302 prénoms (1.4 Mo gz)

## Volume final

Réduction significative vs estimation initiale (~80 Mo) grâce à NFKD+A-Z
qui fusionne toutes les translittérations Wikidata (cyrilliques, arabes,
chinoises…) en latin de base. Résultat : 4.3 Mo gz total, ~30 Mo RAM.

## Spot-check

| Nom | Présent ? | Note |
|---|---|---|
| EJNAINI |  | Le cas de fuite résiduelle audit_30 — devrait être fixé |
| OYARZABAL |  | Variante basque |
| OYARCABAL |  | Orthographe franco-espagnole rare, absente Wikidata |
| NGUYEN, SCHMIDT, OBAMA, NAKAMURA, GARCIA, MARTIN, BERNARD |  | OK |

## Intersection INSEE

- ∩ INSEE FR : 130 340 noms (59.5 % de couverture INSEE)
- Gain net : 1 249 269 noms supplémentaires (focus diaspora / DOM-TOM)

## Risque FP identifié

Quelques mots français courants sont présents dans paranames (origine :
noms d'autres langues) : VOIR, ALLO. MIDI déjà filtré par stopwords.
Impact à mesurer sur retraitement audit_30. Si nécessaire, ajout d'un
filtre dictionnaire français à apporter ultérieurement.

## Source

- Dépôt : https://github.com/bltlab/paranames
- Mirror HF (utilisé) : https://huggingface.co/datasets/imvladikon/paranames
- License : CC BY 4.0
- Origine : Wikidata (entités publiques) — pas de PII fuitée

REJETÉ comme alternative : philipperemy/name-dataset (origine = leak
Facebook 2021, RGPD bloquant pour produit médical).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 16:02:54 +02:00
parent 3bd38c6cdb
commit 745ebd93fb
5 changed files with 407 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
# Procédure d'extraction — gazetteer paranames
## Vue d'ensemble
Le script `scripts/build_paranames_gazetteer.py` télécharge le dataset
paranames depuis HuggingFace, filtre les entités de type PER, normalise
les noms (NFKD UPPERCASE A-Z) et produit deux gazetteers compressés.
## Pré-requis
- Python ≥ 3.10
- Venv du projet activé : `source .venv/bin/activate`
- Paquets : `datasets`, `huggingface_hub`, `pyarrow`, `pandas`
(déjà présents dans `requirements.txt`).
- Connexion réseau pour le premier téléchargement (~1.33 GB).
- ~3 GB de cache HuggingFace disponibles.
- ~1 GB de RAM (le script lit le parquet par batches de 64 K lignes).
## Lancement
```bash
cd /home/dom/ai/anonymisation
source .venv/bin/activate
python scripts/build_paranames_gazetteer.py
```
Options :
- `--hf-cache /chemin` : forcer un cache custom (défaut : `~/.cache/huggingface`).
- `--limit N` : ne traiter que N lignes (debug uniquement).
## Étapes internes du script
1. **Téléchargement** via `huggingface_hub.hf_hub_download` du parquet
`data/train.parquet` du repo `imvladikon/paranames`. Le cache HF est
réutilisé (idempotent).
2. **Chargement** du BDPM stop-words (`data/bdpm/medicaments_stopwords.txt`,
7 312 tokens normalisés en UPPER A-Z) pour filtrer les noms qui sont en
fait des médicaments.
3. **Itération par batches** (`pyarrow.parquet.ParquetFile.iter_batches`)
sur les colonnes `name` et `type` uniquement. Filtre `type == "PER"`.
4. **Split** de chaque `name` sur espaces et séparateurs courants
(`SPLIT_CHARS`).
5. **Heuristique nom/prénom** :
- dernier token → **nom de famille candidat**
- tokens précédents → **prénoms candidats**
- cas mononyme (1 seul token) : considéré comme nom de famille.
6. **Normalisation** : NFKD → strip diacritiques → UPPER → conserver
uniquement A-Z (chars latins de base).
7. **Filtres anti-bruit** :
- longueur ≥ 3 caractères
- longueur ≤ 25 caractères
- non présent dans la BDPM stop-words.
8. **Écriture** triée alphabétique en `.txt.gz` compresslevel=9.
## Volumes attendus (ordre de grandeur)
- Lignes parquet totales : ~124 M
- Lignes PER après filtre : ~82 M
- Noms famille uniques (après dédup + normalisation) : quelques centaines
de milliers à quelques millions.
- Prénoms uniques : idem.
## Régénération (mise à jour)
Si une nouvelle version de paranames est publiée, supprimer le cache HF
correspondant :
```bash
rm -rf ~/.cache/huggingface/datasets--imvladikon--paranames/
python scripts/build_paranames_gazetteer.py
```
ou supprimer simplement les `.txt.gz` cibles et relancer (le download
réutilise le cache si la version est inchangée).
## Vérification rapide
```bash
zcat data/paranames/noms_famille_world.txt.gz | wc -l
zcat data/paranames/prenoms_world.txt.gz | wc -l
zcat data/paranames/noms_famille_world.txt.gz | grep -E "^(OYARCABAL|EJNAINI|NGUYEN|SCHMIDT|OBAMA)$"
```
## Licence
paranames est sous **CC BY 4.0**. Les fichiers dérivés (`*.txt.gz`)
héritent de cette licence et doivent être redistribués avec attribution
(voir README.md).

64
data/paranames/README.md Normal file
View File

@@ -0,0 +1,64 @@
# data/paranames — Gazetteers de noms mondiaux
Issu de [paranames](https://github.com/bltlab/paranames) v2024.05.07.0,
sous licence **CC BY 4.0**.
## Citation
> Sälevä, J., & Lignos, C. (2024). *ParaNames 1.0: Creating an Entity Name
> Corpus for 400+ Languages using Wikidata.* In Proceedings of LREC-COLING
> 2024.
Lien : <https://aclanthology.org/2024.lrec-main.1103/>
## Contenu
| Fichier | Description |
|----------------------------------|--------------------------------------------------------------------|
| `noms_famille_world.txt.gz` | Noms de famille mondiaux (UPPERCASE, NFKD sans diacritiques, A-Z). |
| `prenoms_world.txt.gz` | Prénoms mondiaux (UPPERCASE, NFKD sans diacritiques, A-Z). |
| `EXTRACTION.md` | Procédure reproductible d'extraction. |
Les deux fichiers sont triés alphabétiquement, encodés UTF-8, compressés gzip
niveau 9. Une entrée par ligne.
## Régénération
```bash
python scripts/build_paranames_gazetteer.py
```
Le script est **idempotent** : relance = même résultat. Le cache HuggingFace
(~/.cache/huggingface/) évite tout re-téléchargement.
Voir [EXTRACTION.md](EXTRACTION.md) pour le détail de la procédure.
## Source amont
- **Repo** : <https://github.com/bltlab/paranames>
- **Mirror HuggingFace** : <https://huggingface.co/datasets/imvladikon/paranames>
- **Données** : `data/train.parquet` (~1.33 GB, 124 M lignes — noms parallèles
de plus de 12 M d'entités nommées dans 400+ langues, extraits de Wikidata).
- **Filtrage appliqué** : seuls les `type == "PER"` (personnes) sont retenus.
## Utilisation dans l'anonymiseur
Ces gazetteers complètent les listes INSEE (françaises) pour couvrir les noms
**internationaux** (basques, vietnamiens, arabes, asiatiques, africains…)
fréquents dans les documents médicaux français des CHU et hôpitaux de
territoires multi-ethniques (La Réunion, Antilles, métropole).
Charger en lecture :
```python
import gzip
with gzip.open("data/paranames/noms_famille_world.txt.gz", "rt", encoding="utf-8") as f:
NOMS_WORLD = {line.strip() for line in f if line.strip()}
```
## Attribution dans l'application
L'écran « À propos » de l'application Pseudonymisation mentionne :
> Gazetteers de noms mondiaux issus de paranames (Sälevä & Lignos, 2024)
> sous licence CC BY 4.0.

Binary file not shown.

Binary file not shown.