Volver al inicio

NER para currículos: Guía de implementación en sistemas de RRHH | IT Practice

El artículo describe los aspectos técnicos de la implementación de Reconocimiento de Entidades Nombradas para el procesamiento de currículos. Cubre las etapas de preparación de datos, selección de arquitectura de modelo e implementación en producción teniendo en cuenta las especificidades de los textos en idioma ruso. Se proporcionan ejemplos de código y recomendaciones de optimización.

Cómo implementar NER en sistemas de RRHH: guía técnica para desarrolladores
Advertisement 728x90

# 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.

Google AdInline article slot

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.

Google AdInline article slot
  • 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

Google AdInline article slot

* 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

Advertisement 728x90

Leer después