Реалізація класифікації тексту
Класифікація тексту—завдання присвоєння мітки(и) тексту. Тематика листа, рубрика статті, тип звернення, мова документа—за зовнішньою простотою скривається множество технічних рішень, які принципово впливають на якість.
Постановка завдання та вибір підходу
Перш ніж вибирати архітектуру, потрібно визначити параметри завдання:
- Кількість класів: 2–5 (бінарна/проста багатокласова) або 20–100+ (ієрархічна)
- Обсяг розмітки: є 500+ прикладів на клас?
- Мова: англійська, російська, багатомовна
- Вимоги latency: реальний час (<100ms) або batch
- Інтерпретативність: потрібно пояснювати рішення?
Ці параметри визначають стек. Помилка—автоматично йти до BERT, коли логістична регресія розв'язує завдання за 50ms.
Ієрархія підходів
Рівень 1—класичний ML (TF-IDF / BOW + Logistic Regression / SVM / LightGBM):
- Коли достатньо: чіткі теми, багато розмітки, потрібна інтерпретативність, latency < 10ms
- scikit-learn Pipeline: TfidfVectorizer → LogisticRegression
- Точність на типових завданнях: 85–92%
Рівень 2—FastText:
- Коли: потрібне швидке навчання на великому обсязі, багатомовне завдання
- Навчання 100K прикладів: < 30 секунд
- Inference: ~1ms на текст
- Якість близька до BERT для чистих тематичних класифікаторів
Рівень 3—Transformer Fine-tuning:
- BERT / RoBERTa / DeBERTa для англійської
- ruBERT / ruRoBERTa для російської
- Коли: складні класи, мало розмітки (few-shot), потрібна висока точність
- Навчання: 2–10 епох на GPU, 15–60 хвилин для типового датасету
Рівень 4—LLM із промптингом:
- Zero-shot / few-shot через GPT-4o-mini або Claude
- Коли: немає розмітки, потрібен швидкий старт або класи описові
- Недоліки: latency 500ms–2s, вартість на обсязі
BERT Fine-tuning на PyTorch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import TrainingArguments, Trainer
import numpy as np
model_name = "DeepPavlov/rubert-base-cased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
model_name, num_labels=len(label2id)
)
def tokenize(examples):
return tokenizer(
examples["text"],
truncation=True,
max_length=512,
padding="max_length"
)
training_args = TrainingArguments(
output_dir="./classifier",
num_train_epochs=5,
per_device_train_batch_size=16,
learning_rate=2e-5,
weight_decay=0.01,
evaluation_strategy="epoch",
load_best_model_at_end=True,
)
Робота з незбалансованими класами
Реальні дані майже завжди незбалансовані. Стратегії:
-
Class weights:
compute_class_weight('balanced', ...)—передається в loss function - Oversampling: SMOTE для embedding або аугментація тексту (paraphrase)
- Undersampling: лише якщо мажоритарний клас справді надмірний
- Focal Loss: для екстремального дисбалансу (1:100+)
Моніторьте per-class F1, не лише accuracy—95% accuracy при 5% рідкісного класу нічого не значить.
Багатокласова проти багатомітчевої класифікації
Для multilabel (текст може мати кілька міток одночасно):
- Замініть
softmaxнаsigmoidу фінальному шарі - Використовуйте
BCEWithLogitsLossзамістьCrossEntropyLoss - Поріг класифікації настроюється окремо для кожного класу (maximize F1)
Деплой класифікатора
Оптимізація для inference:
- ONNX export: прискорення CPU inference в 2–4x
- Quantization (INT8): зменшення пам'яті в 4x, деградація accuracy < 1%
- TorchScript: для production PyTorch serving
Serving:
# ONNX Runtime
pip install onnxruntime
# Експорт
from optimum.onnxruntime import ORTModelForSequenceClassification
model = ORTModelForSequenceClassification.from_pretrained("./classifier", export=True)
Latency ONNX+INT8 на CPU: 20–50ms для 512-токенного тексту.
Метрики та моніторинг
- F1 Macro—основна метрика для незбалансованих завдань
- Confusion matrix—обов'язкова при первинній оцінці
- Calibration curve—якщо потрібні достовірні ймовірності
У production: моніторинг distribution shift через KL-дивергенцію розподілу передбачених класів. Сигнал: метрика виходить за межі історичного коридору→переобучення моделі.
Часова шкала реалізації
- Baseline (TF-IDF + ML): 3–5 днів (включаючи розмітку)
- BERT fine-tuning: 1–2 тижні
- Production з моніторингом: 3–5 тижнів







