Собесов

Сценарий ML: TabNet и DL для табличных данных

ML / Data ScienceДеревья vs нейросетиСложнаяSenior

Условие

Опишите TabNet и FT-Transformer. Почему ими интересуются, когда стоит пробовать?

Решение

Подход

TabNet (Arik & Pfister, 2019, Google):

Архитектура: на каждом decision step attention выбирает подмножество фичей (sparse), затем feature transformer применяет non-linearity. Стек таких steps. Финал — sum representations.

Особенности:

  • Sparse feature selection (interpretability).
  • Self-supervised pretraining via masked feature reconstruction.
  • Не нужен feature engineering для категорий (учит embeddings).

FT-Transformer (Gorishniy et al., 2021, Yandex):

  • Tokenize все фичи (категории = embedding, числа = linear+bias).
  • Стек transformer encoder layers с self-attention.
  • [CLS] токен в финале → classifier head.

Особенности:

  • Универсальная transformer arch для табличных.
  • Часто match или beat GBDT на крупных датасетах.

Реализация TabNet

from pytorch_tabnet.tab_model import TabNetClassifier
 
model = TabNetClassifier(
    n_d=64, n_a=64,             # размер attention/decision
    n_steps=5,                  # шагов
    gamma=1.5,                  # sparsity regularization
    n_independent=2, n_shared=2,
    momentum=0.3,
    mask_type='sparsemax',
    seed=42
)
model.fit(X_tr, y_tr, eval_set=[(X_val, y_val)], max_epochs=200,
          patience=20, batch_size=4096, virtual_batch_size=256)

FT-Transformer (упрощённо)

import torch.nn as nn
 
class FTTransformer(nn.Module):
    def __init__(self, n_num, cat_cardinalities, dim=192, depth=3, heads=8):
        super().__init__()
        self.num_emb = nn.Linear(1, dim)
        self.cat_emb = nn.ModuleList([nn.Embedding(c, dim) for c in cat_cardinalities])
        self.cls = nn.Parameter(torch.randn(1, 1, dim))
        layer = nn.TransformerEncoderLayer(dim, heads, batch_first=True)
        self.trans = nn.TransformerEncoder(layer, depth)
        self.head = nn.Linear(dim, 1)
 
    def forward(self, x_num, x_cat):
        toks = [self.num_emb(x_num[:,i:i+1].unsqueeze(-1)) for i in range(x_num.shape[1])]
        toks += [emb(x_cat[:,i]).unsqueeze(1) for i,emb in enumerate(self.cat_emb)]
        cls = self.cls.expand(x_num.shape[0], -1, -1)
        x = torch.cat([cls] + toks, dim=1)
        x = self.trans(x)
        return self.head(x[:,0])

Когда пробовать

  • Большой dataset (>500k rows).
  • Multimodal: можно concat tabular embeddings с text/image.
  • Self-supervised pretraining нужен (TabNet).
  • Команда уже работает с PyTorch.

Когда не пробовать

  • Малая выборка (<10k): GBDT выиграет.
  • Low-latency production: inference ~ms vs μs у GBDT.
  • Простые tabular (числа без структуры).

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

  1. Hyperparameter sensitivity: TabNet требует серьёзного tuning. Лень → underperform vs CatBoost.
  2. Compute cost: TabNet/FT-Transformer на GPU несколько часов. CatBoost минуты.
  3. Self-supervised pretraining (для TabNet) даёт +1-3% на финальной метрике, но 2x train time.
  4. На rare categories embedding learning struggles → smoothing / <UNK> нужен.
  5. Бенчмарки в paper часто cherry-picked. Воспроизведите на своих данных перед production.

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

TabNet: sequential attention для sparse feature selection, support self-supervised pretraining. FT-Transformer: tokenize фичи → transformer encoder + CLS classifier. Обычно паритет с GBDT, выигрывают на больших датасетах или multimodal. Требуют много compute и tuning; для baseline всё ещё CatBoost / LightGBM.

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

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

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