# Implementación Práctica de NER para el Procesamiento de Currículos: Desde la Anotación de Datos hasta el Servicio en Producción
El Reconocimiento de Entidades Nombradas (NER) es un componente crítico de los sistemas modernos de NLP, especialmente en la automatización de RR. HH. En este artículo, desglosaremos los aspectos técnicos de la implementación de una solución NER para extraer datos estructurados de currículos, con enfoque en textos en ruso y las particularidades del despliegue en producción.
Definición de los Límites de la Tarea
Antes de comenzar el desarrollo, es esencial formalizar claramente los requisitos. Para un sistema de RR. HH., las entidades clave son:
- Datos personales (nombre completo, correo electrónico, teléfono)
- Habilidades profesionales (tecnologías, herramientas)
- Parámetros financieros (salario esperado con moneda)
Es importante tener en cuenta que las habilidades en los currículos suelen listarse sin separadores (p. ej., "Python SQL Docker"). Esto requiere usar el esquema de etiquetado BIO en lugar de IO simple para que el modelo pueda separar correctamente entidades adyacentes. Para el ruso, manejar formas de caso y abreviaturas ("JS" en lugar de "JavaScript") es crítico.
Define reglas precisas para cada entidad:
- SKILL: solo términos profesionales (excluyendo habilidades blandas)
- SALARY: cantidad + moneda ("150 thousand. rubles.", "$2500")
- PHONE: todos los formatos de números con código de país
Preparación de Datos: Estrategias y Herramientas
Búsqueda de Conjuntos de Datos Listos
Primera etapa: revisar recursos existentes:
- Hugging Face Datasets
Filtrar por: Task=Token Classification, Language=Russian. Hasta la fecha de este artículo, no se encontraron conjuntos de datos especializados para currículos. Los análogos en inglés (p. ej., Resume Entities Dataset) requieren adaptación mediante traducción y ajuste fino.
- Kaggle y Zenodo
Buscar por palabras clave "resume NER", "CV entities". Los conjuntos encontrados suelen contener:
* Anotación incompleta (solo habilidades)
* Falta de ejemplos en ruso
* Esquemas de etiquetado diferentes (BIOES vs BIO)
- Generación Sintética
Cuando los datos escasean, usa bibliotecas como nlpaug para:
* Reemplazar datos reales con análogos ("Ivanov" → "Petrov")
* Introducir errores tipográficos en datos de contacto
* Generar variantes de nombres de habilidades ("PyTorch" → "pytorch")
Anotación Manual en Label Studio
Cuando los datos listos no bastan, crea un conjunto personalizado. Pasos clave:
- Preparación de Documentos PDF
Usa pdfplumber para extraer texto preservando la estructura:
```python
with pdfplumber.open('resume.pdf') as pdf:
text = '\n\n'.join([page.extract_text() for page in pdf.pages])
```
- Conversión a JSON para Label Studio
Script para convertir PDF al formato de la plataforma:
```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)
```
- Configuración de la Interfaz de Anotación
En Label Studio, crea una plantilla con etiquetas:
```xml
<View>
<Text name="text" value="$text"/>
<Labels name="ner" toName="text">
<Label value="SKILL" background="#ffcc00"/>
<Label value="SALARY" background="#66ccff"/>
</Labels>
</View>
```
La anotación consistente es críticamente importante: establece reglas para casos ambiguos (p. ej., "C++" — ¿una habilidad o dos?). Para mejorar la calidad, involucra a dos anotadores y calcula la métrica de Cohen's Kappa.
Selección y Entrenamiento del Modelo
Arquitecturas Base
Para textos en ruso, recomendamos los siguientes enfoques:
- Ajuste Fino de Modelos Preentrenados
* RuBERT (DeepPavlov) — óptimo para ruso
* mBERT — para soporte multilingüe si es necesario
* Parámetro clave: max_seq_length=512 (los currículos suelen tener descripciones largas)
- Personalización de la Tokenización
Agrega términos específicos al vocabulario:
```python
tokenizer.add_tokens(["CI/CD", "ETL", "MLflow"])
model.resize_token_embeddings(len(tokenizer))
```
- Manejo del Desbalance de Clases
Usa una función de pérdida ponderada:
```python
class_weights = compute_class_weight('balanced',
classes=np.unique(labels),
y=labels)
criterion = nn.CrossEntropyLoss(weight=torch.tensor(class_weights))
```
Métricas de Evaluación
La precisión estándar no es adecuada para NER. Rastrea:
- F1 a nivel de token — métrica principal
- Precisión/recuperación a nivel de entidad — vía la biblioteca
seqeval - Velocidad de procesamiento — tokens por segundo en CPU
Presta especial atención a la recuperación para la entidad SALARY: una caída aquí provocará la pérdida de datos críticos.
Despliegue en Producción
Arquitectura del Servicio
Esquema de integración recomendado:
- Preprocesamiento
* Convertir PDF/DOCX a texto (vía antiword y pdf2text)
* Normalizar texto (eliminar espacios extra, codificar monedas)
- Núcleo NER
```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
```
- Postprocesamiento
* Agrupar tokens en entidades por etiquetas BIO
* Validar formatos (regex para correo/teléfono)
* Normalizar habilidades ("JS" → "JavaScript") vía mapeo
Optimización de Rendimiento
- Caché — para solicitudes repetidas
- Procesamiento en Lotes — combinar múltiples currículos en un lote
- Cuantización — convertir modelo a FP16 vía
torch.quantization
Para sistemas de alta carga, implementa una cola de tareas vía RabbitMQ para evitar tiempos de espera al procesar archivos grandes.
Lecciones Clave
- Adaptación al Dominio es crítica: un modelo entrenado en noticias fallará en currículos
- Calidad de la Anotación determina el 80% del resultado final: invierte en anotadores
- Esquema BIO es obligatorio para listas de habilidades sin separadores
- Validación en Casos Límite — prueba manejo de formatos no estándar ("100k $", "~2000 evro")
- Monitoreo de Deriva de Datos — recalcula métricas regularmente en nuevos currículos
— Editorial Team
Aún no hay comentarios.