# Praktická implementace NER pro zpracování životopisů: od značkování dat po produkční službu
Named Entity Recognition (NER) je klíčovou součástí moderních NLP systémů, zejména v automatizaci HR. V tomto článku rozebereme technické aspekty nasazení NER řešení pro extrakci strukturovaných dat z životopisů s důrazem na ruskojazyčné texty a specifičnost nasazení do produkce.
Definice hranic úlohy
Před spuštěním vývoje je nutné jasně formalizovat požadavky. Pro HR systém jsou klíčovými entitami:
- Osobní údaje (jméno, příjmení, email, telefon)
- Profesionální dovednosti (technologie, nástroje)
- Finanční parametry (očekávaný plat s měnou)
Důležité je vzít v úvahu, že v životopisech se dovednosti často uvádějí bez oddělovačů (např. "Python SQL Docker"). To vyžaduje použití schématu značkování BIO místo jednoduchého IO, aby model správně odděloval sousední entity. Pro ruštinu je kritická zpracování pádových forem a zkratek ("JS" místo "JavaScript").
Definujte přesná pravidla pro každou entitu:
- SKILL: pouze profesionální termíny (vyloučit soft skills)
- SALARY: částka + měna ("150 tis. RUB", "$2500")
- PHONE: všechny formáty čísel s kódem země
Příprava dat: strategie a nástroje
Hledání hotových datasetů
První etapa – kontrola existujících zdrojů:
- Hugging Face Datasets
Filtrujeme podle: Task=Token Classification, Language=Russian. K okamžiku psaní článku nebyly nalezeny specializované datasety pro životopisy. Anglojazyčné analogy (např. Resume Entities Dataset) vyžadují adaptaci přes překlad a doškolení.
- Kaggle a Zenodo
Hledání podle klíčových slov "resume NER", "CV entities". Najdené sady dat často obsahují:
* Neúplné značkování (pouze dovednosti)
* Chybějící ruskojazyčné příklady
* Různé schémata tagování (BIOES vs BIO)
- Syntetická generace
Při nedostatku dat použijte knihovny jako nlpaug pro:
* Nahrazení reálných dat analogy ("Novák" → "Kovář")
* Zavedení překlepů do kontaktních údajů
* Generování variant zápisu dovedností ("PyTorch" → "pytorch")
Ruční značkování v Label Studio
Když hotových dat není dost, vytvoříme vlastní dataset. Klíčové kroky:
- Příprava PDF dokumentů
Použijeme pdfplumber pro extrakci textu s zachováním struktury:
```python
with pdfplumber.open('resume.pdf') as pdf:
text = '\n\n'.join([page.extract_text() for page in pdf.pages])
```
- Konverze do JSON pro Label Studio
Skript pro převod PDF do formátu přijímaného platformou:
```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)
```
- Nastavení rozhraní pro značkování
V Label Studio vytvoříme šablonu s tagy:
```xml
<View>
<Text name="text" value="$text"/>
<Labels name="ner" toName="text">
<Label value="SKILL" background="#ffcc00"/>
<Label value="SALARY" background="#66ccff"/>
</Labels>
</View>
```
Kriticky důležité je jednotné značkování: stanovte pravidla pro sporné případy (např. "C++" – jedna dovednost nebo dvě). Pro zlepšení kvality zapojte dva anotátory a počítejte metriku Cohen's Kappa.
Výběr a trénink modelu
Základní architektury
Pro ruskojazyčné texty doporučujeme následující přístupy:
- Fine-tuning předtrénovaných modelů
* RuBERT (DeepPavlov) – optimální pro ruštinu
* mBERT – pro potřebu multilingual podpory
* Klíčový parametr: max_seq_length=512 (životopisy často obsahují dlouhé popisy)
- Přizpůsobení tokenizace
Přidejte do slovníku specifické termíny:
```python
tokenizer.add_tokens(["CI/CD", "ETL", "MLflow"])
model.resize_token_embeddings(len(tokenizer))
```
- Zpracování nevyváženosti tříd
Použijte váženou funkci ztráty:
```python
class_weights = compute_class_weight('balanced',
classes=np.unique(labels),
y=labels)
criterion = nn.CrossEntropyLoss(weight=torch.tensor(class_weights))
```
Metriky hodnocení
Standardní accuracy není pro NER použitelná. Sledujte:
- Token-level F1 – hlavní metrika
- Entity-level precision/recall – přes knihovnu
seqeval - Rychlost zpracování – tokenů za sekundu na CPU
Zvláštní pozornost věnujte recall pro entitu SALARY – jeho pokles povede ke ztrátě kriticky důležitých dat.
Nasazení do produkce
Architektura služby
Doporučené schéma integrace:
- Předzpracování
* Konverze PDF/DOCX do textu (přes antiword a pdf2text)
* Normalizace textu (odstranění zbytečných mezer, kódování měn)
- Jádro 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)
# Zpracování logitů do entit
```
- Postprocessing
* Seskupení tokenů do entit podle BIO tagů
* Validace formátu (regulární výrazy pro email/telefon)
* Normalizace dovedností ("JS" → "JavaScript") přes mapování
Optimalizace výkonu
- Cacheování – pro opakující se požadavky
- Dávkové zpracování – sloučení několika životopisů do batch
- Quantization – konverze modelu do FP16 přes
torch.quantization
Pro systémy s vysokou zátěží implementujte frontu úloh přes RabbitMQ, aby se zabránilo timeoutům při zpracování velkých souborů.
Co je důležité
- Doménová adaptace je kritická: model trénovaný na novinách selže u zpracování životopisů
- Kvalita značkování určuje 80 % konečného výsledku – investujte do anotátorů
- Schéma BIO je povinné pro výčty dovedností bez oddělovačů
- Validace na hraničních případech – kontrolujte zpracování nestandardních formátů ("100k USD", "~2000 EUR")
- Monitorování driftu dat – pravidelně přepočítávejte metriky na nových životopisech
— Editorial Team
Zatím žádné komentáře.