Powrót do strony głównej

NER dla CV: Przewodnik po wdrożeniu w systemy HR | IT-praktyka

Artykuł opisuje aspekty techniczne wdrożenia Named Entity Recognition do przetwarzania CV. Omówiono etapy przygotowania danych, wyboru architektury modelu i wdrożenia produkcyjnego z uwzględnieniem specyfiki tekstów rosyjskojęzycznych. Podano przykłady kodu i rekomendacje optymalizacji.

Jak wdrożyć NER w systemy HR: techniczne przewodnictwo dla programistów
Advertisement 728x90

# Praktyczna implementacja NER do przetwarzania CV: od anotacji danych po serwis produkcyjny

Named Entity Recognition (NER) — kluczowy komponent nowoczesnych systemów NLP, szczególnie w automatyzacji HR. W tym artykule omówimy aspekty techniczne wdrożenia rozwiązania NER do wyodrębniania strukturyzowanych danych z CV, z naciskiem na teksty rosyjskojęzyczne i specyfikę wdrożenia produkcyjnego.

Określenie granic zadania

Przed rozpoczęciem development należy dokładnie sformalizować wymagania. Dla systemu HR kluczowymi encjami są:

  • Dane osobowe (imię i nazwisko, email, telefon)
  • Umiejętności zawodowe (technologie, narzędzia)
  • Parametry finansowe (oczekiwane wynagrodzenie z walutą)

Ważne jest uwzględnienie, że w CV umiejętności często są wymieniane bez separatorów (np. "Python SQL Docker"). To wymaga użycia schematu anotacji BIO zamiast prostego IO, aby model poprawnie rozdzielał sąsiadujące encje. Dla języka rosyjskiego kluczowa jest obsługa form deklinacyjnych i skrótów ("JS" zamiast "JavaScript").

Google AdInline article slot

Określ precyzyjne reguły dla każdej encji:

  • SKILL: tylko terminy zawodowe (wykluczając soft skills)
  • SALARY: kwota + waluta ("150 tys. rubles.", "$2500")
  • PHONE: wszystkie formaty numerów z kodem kraju

Przygotowanie danych: strategie i narzędzia

Wyszukiwanie gotowych zbiorów danych

Pierwszy etap — sprawdzenie istniejących zasobów:

  • Hugging Face Datasets

Filtrowanie po: Task=Token Classification, Language=Russian. Na moment pisania artykułu nie znaleziono specjalistycznych zbiorów danych dla CV. Angielskojęzyczne odpowiedniki (np. Resume Entities Dataset) wymagają adaptacji poprzez tłumaczenie i dofine-tuning.

Google AdInline article slot
  • Kaggle i Zenodo

Wyszukiwanie po słowach kluczowych "resume NER", "CV entities". Znalezione zbiory danych często zawierają:

* Niekompletną anotację (tylko umiejętności)

* Brak przykładów rosyjskojęzycznych

Google AdInline article slot

* Różne schematy tagowania (BIOES vs BIO)

  • Syntetyczna generacja

Przy braku danych użyj bibliotek typu nlpaug do:

* Zamiany rzeczywistych danych na odpowiedniki ("Ivanov" → "Petrov")

* Wprowadzania literówek w dane kontaktowe

* Generowania wariantów zapisu umiejętności ("PyTorch" → "pytorch")

Ręczna anotacja w Label Studio

Gdy gotowych danych jest za mało, tworzymy niestandardowy zbiór danych. Kluczowe kroki:

  • Przygotowanie dokumentów PDF

Używamy pdfplumber do wyodrębniania tekstu z zachowaniem struktury:

```python

with pdfplumber.open('resume.pdf') as pdf:

text = '\n\n'.join([page.extract_text() for page in pdf.pages])

```

  • Konwersja do formatu JSON dla Label Studio

Skrypt konwertujący PDF do formatu akceptowanego przez platformę:

```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)

```

  • Konfiguracja interfejsu anotacji

W Label Studio tworzymy szablon z tagami:

```xml

<View>

<Text name="text" value="$text"/>

<Labels name="ner" toName="text">

<Label value="SKILL" background="#ffcc00"/>

<Label value="SALARY" background="#66ccff"/>

</Labels>

</View>

```

Kluczowa jest jednolita anotacja: ustal reguły dla przypadków spornych (np. "C++" — jedna umiejętność czy dwie). Aby poprawić jakość, zaangażuj dwóch anotatorów i oblicz metrykę Cohen's Kappa.

Wybór i trenowanie modelu

Podstawowe architektury

Dla tekstów rosyjskojęzycznych polecamy następujące podejścia:

  • Fine-tuning modeli pretrenowanych

* RuBERT (DeepPavlov) — optymalny dla języka rosyjskiego

* mBERT — w razie potrzeby wsparcia multilingualnego

* Kluczowy parametr: max_seq_length=512 (CV często zawierają długie opisy)

  • Dostosowanie tokenizacji

Dodaj do słownika specyficzne terminy:

```python

tokenizer.add_tokens(["CI/CD", "ETL", "MLflow"])

model.resize_token_embeddings(len(tokenizer))

```

  • Obsługa niezrównoważonych klas

Użyj ważonej funkcji straty:

```python

class_weights = compute_class_weight('balanced',

classes=np.unique(labels),

y=labels)

criterion = nn.CrossEntropyLoss(weight=torch.tensor(class_weights))

```

Metryki ewaluacji

Standardowa accuracy nie nadaje się do NER. Śledź:

  • Token-level F1 — główna metryka
  • Entity-level precision/recall — za pomocą biblioteki seqeval
  • Prędkość przetwarzania — tokenów/sekundę na CPU

Zwróć szczególną uwagę na recall dla encji SALARY — jego spadek doprowadzi do utraty krytycznie ważnych danych.

Wdrożenie produkcyjne

Architektura serwisu

Zalecany schemat integracji:

  • Przedprzetwarzanie

* Konwersja PDF/DOCX na tekst (przez antiword i pdf2text)

* Normalizacja tekstu (usuwanie zbędnych spacji, kodowanie walut)

  • Rdzeń 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)

# Przetwarzanie logitów na encje

```

  • Postprzetwarzanie

* Grupowanie tokenów w encje według tagów BIO

* Walidacja formatu (wyrażenia regularne dla email/telefonu)

* Normalizacja umiejętności ("JS" → "JavaScript") przez mapowanie

Optymalizacja wydajności

  • Cache'owanie — dla powtarzających się zapytań
  • Przetwarzanie wsadowe — łączenie kilku CV w batch
  • Kwantyzacja — konwersja modelu do FP16 przez torch.quantization

Dla systemów o wysokiej obciążeniu zaimplementuj kolejkę zadań przez RabbitMQ, aby uniknąć timeoutów przy przetwarzaniu dużych plików.

Co jest ważne

  • Adaptacja domenowa jest kluczowa: model trenowany na wiadomościach zawiedzie przy przetwarzaniu CV
  • Jakość anotacji decyduje o 80% ostatecznego wyniku — zainwestuj w anotatorów
  • Schemat BIO jest obowiązkowy dla list umiejętności bez separatorów
  • Walidacja edge cases — sprawdzaj obsługę niestandardowych formatów ("100k $", "~2000 euro")
  • Monitorowanie dryfu danych — regularnie przeliczaj metryki na nowych CV

— Editorial Team

Advertisement 728x90

Czytaj dalej