Implémentation pratique de la NER pour le traitement des CV : de l'annotation des données au service de production
La reconnaissance d'entités nommées (NER) est un composant critique des systèmes NLP modernes, en particulier dans l'automatisation RH. Dans cet article, nous décomposons les aspects techniques de l'implémentation d'une solution NER pour extraire des données structurées des CV, en mettant l'accent sur les textes en russe et les spécificités du déploiement en production.
Définition du périmètre de la tâche
Avant de commencer le développement, il est essentiel de formaliser clairement les exigences. Pour un système RH, les entités clés sont :
- Données personnelles (nom complet, email, téléphone)
- Compétences professionnelles (technologies, outils)
- Paramètres financiers (salaire attendu avec devise)
Il est important de noter que les compétences dans les CV sont souvent listées sans séparateurs (p. ex., "Python SQL Docker"). Cela nécessite d'utiliser le schéma d'étiquetage BIO au lieu de IO simple afin que le modèle puisse séparer correctement les entités adjacentes. Pour le russe, la gestion des formes de cas et des abréviations ("JS" au lieu de "JavaScript") est cruciale.
Définir des règles précises pour chaque entité :
- SKILL : seulement les termes professionnels (à l'exclusion des soft skills)
- SALARY : montant + devise ("150 000 RUB", "$2500")
- PHONE : tous les formats numériques avec indicatif pays
Préparation des données : Stratégies et outils
Recherche de jeux de données prêts à l'emploi
Première étape — vérifier les ressources existantes :
- Hugging Face Datasets
Filtrer par : Task=Token Classification, Language=Russian. À la date de cet article, aucun jeu de données spécialisé pour les CV n'a été trouvé. Les équivalents anglais (p. ex., Resume Entities Dataset) nécessitent une adaptation par traduction et fine-tuning.
- Kaggle and Zenodo
Recherche par mots-clés "resume NER", "CV entities". Les jeux de données trouvés contiennent souvent :
* Annotation incomplète (seulement compétences)
* Manque d'exemples en russe
* Schémas d'étiquetage différents (BIOES vs BIO)
- Synthetic Generation
Quand les données sont rares, utiliser des bibliothèques comme nlpaug pour :
* Remplacer les données réelles par des analogues ("Ivanov" → "Petrov")
* Introduire des fautes dans les données de contact
* Générer des variantes de noms de compétences ("PyTorch" → "pytorch")
Annotation manuelle dans Label Studio
Quand les données prêtes à l'emploi ne suffisent pas, créer un jeu de données personnalisé. Étapes clés :
- Préparation des documents PDF
Utiliser pdfplumber pour extraire le texte en préservant la structure :
```python
with pdfplumber.open('resume.pdf') as pdf:
text = '\n\n'.join([page.extract_text() for page in pdf.pages])
```
- Conversion en JSON pour Label Studio
Script pour convertir PDF au format de la plateforme :
```python
import json
import os
def convert_to_ls_format(pdf_dir):
tasks = [{"text": open(f, 'r').read()}
for f in os.listdir(pdf_dir) if f.endswith('.txt')]
with open('import.json', 'w') as f:
json.dump(tasks, f, ensure_ascii=False, indent=2)
```
- Configuration de l'interface d'annotation
Dans Label Studio, créer un modèle avec des étiquettes :
```xml
<View>
<Text name="text" value="$text"/>
<Labels name="ner" toName="text">
<Label value="SKILL" background="#ffcc00"/>
<Label value="SALARY" background="#66ccff"/>
</Labels>
</View>
```
Une annotation cohérente est cruciale : établir des règles pour les cas ambigus (p. ex., "C++" — une compétence ou deux). Pour améliorer la qualité, impliquer deux annotateurs et calculer la métrique de Cohen's Kappa.
Sélection et entraînement du modèle
Architectures de base
Pour les textes en russe, nous recommandons les approches suivantes :
- Fine-tuning Pretrained Models
* RuBERT (DeepPavlov) — optimal pour le russe
* mBERT — pour le support multilingue si nécessaire
* Paramètre clé : max_seq_length=512 (les CV ont souvent de longues descriptions)
- Customizing Tokenization
Ajouter des termes spécifiques au vocabulaire :
```python
tokenizer.add_tokens(["CI/CD", "ETL", "MLflow"])
model.resize_token_embeddings(len(tokenizer))
```
- Handling Class Imbalance
Utiliser une fonction de perte pondérée :
```python
class_weights = compute_class_weight('balanced',
classes=np.unique(labels),
y=labels)
criterion = nn.CrossEntropyLoss(weight=torch.tensor(class_weights))
```
Métriques d'évaluation
La précision standard n'est pas adaptée à la NER. Suivre :
- Token-level F1 — métrique principale
- Entity-level precision/recall — via la bibliothèque
seqeval - Processing speed — tokens par seconde sur CPU
Accorder une attention particulière au rappel pour l'entité SALARY — une baisse ici entraînera la perte de données critiques.
Déploiement en production
Architecture du service
Schéma d'intégration recommandé :
- Prétraitement
* Convertir PDF/DOCX en texte (via antiword et pdf2text)
* Normaliser le texte (supprimer les espaces excédentaires, encoder les devises)
- NER Core
```python
class NERServer:
def __init__(self):
self.model = AutoModelForTokenClassification.from_pretrained('ner_model')
def extract_entities(self, text):
inputs = tokenizer(text, return_tensors='pt', truncation=True)
outputs = self.model(**inputs)
# Process logits into entities
```
- Postprocessing
* Grouper les tokens en entités par étiquettes BIO
* Valider les formats (regex pour email/téléphone)
* Normaliser les compétences ("JS" → "JavaScript") via un mapping
Optimisation des performances
- Caching — pour les requêtes répétées
- Batch Processing — combiner plusieurs CV en un lot
- Quantization — convertir le modèle en FP16 via
torch.quantization
Pour les systèmes à forte charge, implémenter une file d'attente de tâches via RabbitMQ afin d'éviter les timeouts lors du traitement de gros fichiers.
Points clés
- Domain Adaptation est critique : un modèle entraîné sur des actualités échouera sur les CV
- Annotation Quality détermine 80 % du résultat final — investir dans les annotateurs
- BIO Scheme est obligatoire pour les listes de compétences sans séparateurs
- Validation on Edge Cases — tester la gestion des formats non standards ("100k $", "~2000 euros")
- Data Drift Monitoring — recalculer régulièrement les métriques sur de nouveaux CV
— Editorial Team
Aucun commentaire pour le moment.