Premier pipeline¶
Vous allez construire un pipeline qui détecte des noms et des lieux arbitraires, pas seulement des valeurs connues d'avance, et le voir tourner à chaque étape. Deux détecteurs conviennent pour ça, un modèle NER (GLiNER2) ou un catalogue de motifs regex. Vous partez d'un détecteur, ajoutez les trois composants restants un par un, puis lancez le pipeline sur une phrase.
Prérequis
piighost installé, voir Installation. Le chemin regex n'utilise que le socle, sans extra. Le chemin GLiNER2 demande l'extra gliner2 et télécharge un modèle au premier chargement.
1. Choisir un détecteur¶
Le détecteur lit le texte et renvoie des détections, une par PII trouvée. Le reste du pipeline est identique quel que soit le détecteur, alors choisissez celui qui correspond à votre texte.
Un RegexDetector reconnaît des motifs, c'est-à-dire des chaînes de caractères qui suivent une structure fixe. Pour des noms et des lieux arbitraires, on lui passe un dictionnaire qui associe un label à un motif. Ici deux motifs, un pour les prénoms, un pour la ville.
from piighost.components.detector import RegexDetector
patterns = {
"PERSON": r"\b(?:Patrick|Marie)\b",
"LOCATION": r"\bParis\b",
}
detector = RegexDetector(patterns)
piighost fournit aussi des catalogues prêts à l'emploi pour les formats non spécifiques à une langue, comme l'email et l'URL.
Un NER est un modèle d'IA qui, sur un texte, classe les mots selon une classification décidée à l'avance (nom, prénom, lieu, organisation). Contrairement à la regex, il n'a pas besoin de connaître les valeurs à l'avance, il détecte un prénom qu'il n'a jamais vu.
from piighost.components.detector.ner import Gliner2Detector
detector = Gliner2Detector(
model="fastino/gliner2-multi-v1",
labels=["PERSON", "LOCATION"],
threshold=0.5,
)
Le premier argument est un nom de modèle chargé par GLiNER2, ou une instance déjà chargée. labels fixe les catégories interrogées. threshold est la confiance minimale au-dessus de laquelle une détection est gardée.
2. Regrouper les détections en entités¶
Un même prénom peut apparaître plusieurs fois. Le linker regroupe les détections d'une même valeur et d'un même label en une seule entité, pour que chaque occurrence reçoive plus tard le même jeton.
3. Assigner un jeton à chaque entité¶
L'anonymiseur remplace chaque entité par un placeholder, c'est-à-dire le jeton qui prend sa place dans le texte. Le jeton dépend de la factory choisie. LabelCounterPlaceholderFactory numérote par label, donc <<PERSON:1>>, <<PERSON:2>>, <<LOCATION:1>>.
from piighost.components.anonymizer import Anonymizer
from piighost.components.placeholder import LabelCounterPlaceholderFactory
factory = LabelCounterPlaceholderFactory()
anonymizer = Anonymizer(factory)
4. Assembler et lancer¶
AnonymizationPipeline enchaîne les trois composants dans l'ordre, détecter, regrouper, remplacer. Son appel anonymize est asynchrone et renvoie un résultat dont text porte la phrase dé-identifiée.
import asyncio
from piighost.pipeline import AnonymizationPipeline
pipeline = AnonymizationPipeline(detector, linker, anonymizer)
async def main() -> None:
text = "Patrick habite à Paris. Patrick aime Paris. Marie aussi."
result = await pipeline.anonymize(text)
print(result.text)
asyncio.run(main())
La sortie doit être :
Chaque occurrence de Patrick reçoit le même <<PERSON:1>>, Paris garde <<LOCATION:1>> à ses deux apparitions, et Marie reçoit le numéro suivant <<PERSON:2>>. C'est le linker de l'étape 2 qui rend cette cohérence possible.
Comment ça marche¶
AnonymizationPipeline exécute trois étapes obligatoires. Le détecteur trouve les PII, le linker regroupe les occurrences d'une même valeur en une entité, l'anonymiseur remplace chaque entité par le jeton de sa factory. Des étapes optionnelles existent (expansion des occurrences manquées, fusion d'entités), désactivées par défaut, tandis que la résolution de chevauchement s'exécute par défaut. Seul le détecteur est strictement requis pour construire, ce qui suffit pour un premier pipeline.
Et ensuite¶
- Pour décrire ce pipeline dans un fichier plutôt qu'en Python, voir la Référence TOML. Un détecteur regex y prend ses catalogues avec
catalogs = ["generic"]. - Pour dé-identifier au fil d'une conversation avec des jetons stables entre les messages, voir le Pipeline conversationnel.