Собесов

Сценарий ML: TF-IDF vs BERT embeddings

ML / Data ScienceFeature engineeringСредняяMiddle

Условие

Классифицируем тексты отзывов (negative/positive). Когда TF-IDF, когда BERT?

Решение

Подход

TF-IDF BERT
Семантика Bag-of-words, нет контекста Контекстуальная
Скорость train Очень быстро Медленно (GPU)
Inference Быстро Медленно (~50-100ms на CPU)
Малая выборка Лучше Overfit
Длинные тексты OK 512 токенов лимит (default)
Out-of-vocab Нет (только seen) BPE справляется
Интерпретация Веса слов SHAP / attention

TF-IDF pipeline

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
 
pipe = Pipeline([
    ('tfidf', TfidfVectorizer(
        ngram_range=(1,2),
        max_features=50_000,
        min_df=5, max_df=0.95,
        sublinear_tf=True,
        strip_accents='unicode',
        lowercase=True,
    )),
    ('clf', LogisticRegression(C=1.0, max_iter=1000))
])
pipe.fit(X_train, y_train)

С N=10k текстов TF-IDF + LR обычно даёт baseline 80-85% accuracy.

BERT embeddings

from transformers import AutoTokenizer, AutoModel
import torch
 
tokenizer = AutoTokenizer.from_pretrained("DeepPavlov/rubert-base-cased")
model = AutoModel.from_pretrained("DeepPavlov/rubert-base-cased").eval()
 
def bert_embed(texts, max_len=128):
    enc = tokenizer(texts, padding=True, truncation=True,
                    max_length=max_len, return_tensors='pt')
    with torch.no_grad():
        out = model(**enc)
    # Стратегии: CLS токен, mean pooling, max pooling
    mask = enc.attention_mask.unsqueeze(-1).float()
    pooled = (out.last_hidden_state * mask).sum(1) / mask.sum(1)
    return pooled.numpy()

Затем над эмбеддингами — любой classifier (LR, XGB).

Fine-tuning BERT vs frozen embeddings

  • Frozen + classifier head: быстро, baseline.
  • Full fine-tuning: лучший accuracy, но требует данных (5k+ примеров) и GPU.
  • LoRA / adapters: компромисс — обучаем малый адаптер.

Когда что

  • TF-IDF: классификация тем, поиск ключевых слов, малая выборка, low-latency требования.
  • BERT frozen + LR: средний размер данных, нужна семантика, latency не критична.
  • BERT fine-tune: достаточно данных, важно качество, есть GPU.
  • Sentence-BERT: для сравнения текстов через cosine similarity.

Подводные камни

  1. TF-IDF без min_df → шум из редких опечаток. min_df=5 минимум.
  2. BERT 512 токенов default — длинные тексты обрезаются. Альтернативы: Longformer, Sliding window, chunking.
  3. Domain mismatch: BERT-base обучен на Wikipedia/news; на медицинских / юридических текстах хуже. Используйте domain-specific (BioBERT, LegalBERT).
  4. CLS токен из non-fine-tuned BERT — слабый sentence embedding. Лучше mean pooling или fine-tuned SBERT.
  5. На малой выборке (n<500) BERT fine-tune overfit. Stick to TF-IDF.

Эталонный ответ

TF-IDF: быстрый baseline, bag-of-words, отличный при малой выборке и low-latency. BERT: контекстуальная семантика, фron мер для средних/больших данных и важного качества. Fine-tune BERT при n>5k и GPU; frozen BERT + LR для baseline; SBERT для сравнения текстов.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти