← Назад к вопросам

С какой функцией потерь можно обучить CatBoost

2.0 Middle🔥 91 комментариев
#Python#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Функции потерь в CatBoost

Введение

CatBoost поддерживает множество loss functions для разных типов задач. За 10+ лет использования этой библиотеки я узнал, какие работают лучше всего для разных случаев.

1. Регрессия (Regression)

MAE (Mean Absolute Error)

Уменьшает влияние выбросов.

from catboost import CatBoostRegressor

model = CatBoostRegressor(
    loss_function='MAE',  # L1 норма
    verbose=100
)
model.fit(X_train, y_train)

# Используй когда:
# - Много выбросов в данных
# - Важна медиана, не среднее
# - Деньги (рубли) - обычно нечувствительны к квадратичным ошибкам

RMSE (Root Mean Squared Error)

Стандартная квадратичная потеря.

model = CatBoostRegressor(
    loss_function='RMSE'  # L2 норма
)
model.fit(X_train, y_train)

# По умолчанию в CatBoost
# Используй когда:
# - Нормально распределённые ошибки
# - Нет экстремальных выбросов

MAPE (Mean Absolute Percentage Error)

Процентная ошибка.

model = CatBoostRegressor(
    loss_function='MAPE'
)
model.fit(X_train, y_train)

# Используй когда:
# - Цели имеют разные диапазоны значений
# - Важна относительная ошибка (5% vs 10%)
# - Время: прогнозирование спроса

Huber

Комбинация MAE и RMSE (robust regression).

model = CatBoostRegressor(
    loss_function='Huber',
    loss_function_params={'delta': 1.0}  # параметр сглаживания
)
model.fit(X_train, y_train)

# Используй когда:
# - Есть выбросы, но не нужна полная robustness MAE
# - Хочешь баланс между чувствительностью и robustness

Quantile

Предсказывает конкретный квантиль (не среднее).

model = CatBoostRegressor(
    loss_function='Quantile',
    loss_function_params={'alpha': 0.5}  # 0.5 = медиана
)
model.fit(X_train, y_train)

# Используй когда:
# - Нужны доверительные интервалы
# - alpha=0.1: нижний 10% квантиль
# - alpha=0.5: медиана
# - alpha=0.9: верхний 90% квантиль

# Практический пример: прогнозирование спроса
model_q10 = CatBoostRegressor(loss_function='Quantile', loss_function_params={'alpha': 0.1})
model_q50 = CatBoostRegressor(loss_function='Quantile', loss_function_params={'alpha': 0.5})
model_q90 = CatBoostRegressor(loss_function='Quantile', loss_function_params={'alpha': 0.9})

model_q10.fit(X_train, y_train)
model_q50.fit(X_train, y_train)
model_q90.fit(X_train, y_train)

pred_lower = model_q10.predict(X_test)
pred_median = model_q50.predict(X_test)
pred_upper = model_q90.predict(X_test)

print(f"Предсказание спроса: [{pred_lower}, {pred_median}, {pred_upper}]")

2. Классификация

Logloss (Binary Crossentropy)

Для бинарной классификации.

from catboost import CatBoostClassifier

model = CatBoostClassifier(
    loss_function='Logloss'
)
model.fit(X_train, y_train)

# Используй для:
# - Бинарная классификация (0 vs 1)
# - Выходное значение: вероятность P(y=1)

MultiClass

Для мультиклассовой классификации (более 2 классов).

model = CatBoostClassifier(
    loss_function='MultiClass'
)
model.fit(X_train, y_train)

# Автоматически выбирается если y имеет 3+ уникальных значения

MultiClassOneVsAll

Альтернатива MultiClass (One-vs-Rest стратегия).

model = CatBoostClassifier(
    loss_function='MultiClassOneVsAll'
)
model.fit(X_train, y_train)

CrossEntropy

Строгая кросс-энтропия (используй редко).

model = CatBoostClassifier(
    loss_function='CrossEntropy'
)
model.fit(X_train, y_train)

3. Ранжирование (Ranking)

PairLogit

Для задач ранжирования: какой документ релевантнее?

model = CatBoostRanker(
    loss_function='PairLogit',
    loss_function_params={'sigma': 1.0}  # параметр гладкости
)
model.fit(
    X_train, y_train,
    group_id=group_id_train  # ID группы (например, query_id)
)

# Используй когда:
# - Ранжирование поисковых результатов
# - Рекомендации
# - Относительные предпочтения (документ А лучше документа Б)

PairLogitPairwise

Улучшенная версия PairLogit.

model = CatBoostRanker(
    loss_function='PairLogitPairwise'
)
model.fit(X_train, y_train, group_id=group_id_train)

YetiRank

Сложная функция потерь для ранжирования (как LambdaMART).

model = CatBoostRanker(
    loss_function='YetiRank',
    loss_function_params={'decay': 0.15}  # как быстро уменьшается вес
)
model.fit(X_train, y_train, group_id=group_id_train)

# Используй когда:
# - Ранжирование с large relevance labels
# - Нужна высокая точность top-k результатов

YetiRankPairwise

Varisant YetiRank для парных сравнений.

model = CatBoostRanker(
    loss_function='YetiRankPairwise'
)
model.fit(X_train, y_train, group_id=group_id_train)

4. Специальные функции потерь

AUC (Area Under ROC Curve)

Для классификации с метрикой AUC.

model = CatBoostClassifier(
    loss_function='AUC'
)
model.fit(X_train, y_train)

# Неправильное название: AUC — это метрика, не loss function
# На практике используется внутренняя аппроксимация

Custom Loss (Кастомная функция потерь)

Для специфичных бизнес-требований.

def custom_loss(y_true, y_pred):
    """Асимметричная потеря для fraud detection"""
    error = y_true - y_pred
    
    # FP (false positive) = 500 руб (ложная тревога)
    # FN (false negative) = 50000 руб (пропущенный fraud)
    
    loss = np.where(
        y_true == 1,
        50000 * np.abs(error),  # Штраф за пропуск fraud
        500 * np.abs(error)      # Штраф за ложную тревогу
    )
    return loss.mean()

def custom_loss_gradient(y_true, y_pred):
    """Градиент для оптимизации"""
    error = y_pred - y_true
    
    grad = np.where(
        y_true == 1,
        -50000 * np.sign(error),
        500 * np.sign(error)
    )
    return grad

def custom_loss_hessian(y_true, y_pred):
    """Вторая производная (опционально)"""
    return np.ones_like(y_true) * 1000

from catboost import CatBoostClassifier

model = CatBoostClassifier(
    loss_function='Custom',
    loss_function_params={
        'loss_func': custom_loss,
        'gradient_func': custom_loss_gradient,
        'hessian_func': custom_loss_hessian
    }
)
model.fit(X_train, y_train)

Полная сравнительная таблица

Тип задачи | Loss Function | Когда использовать
──────────────────────────────────────────────────────────
Регрессия | RMSE | По умолчанию, нормальные данные
          | MAE | Много выбросов
          | MAPE | Разные диапазоны значений
          | Huber | Баланс между RMSE и MAE
          | Quantile | Доверительные интервалы
──────────────────────────────────────────────────────────
Класс. | Logloss | Бинарная классификация
       | MultiClass | 3+ класса
       | AUC | Когда важна ROC-AUC метрика
──────────────────────────────────────────────────────────
Ранжир | PairLogit | Парные сравнения
       | YetiRank | Large-scale ранжирование
       | LambdaMART* | NDCG метрика
──────────────────────────────────────────────────────────
Спец.  | Custom | Асимметричные потери

Практический пример: Выбор функции потерь

from catboost import CatBoostRegressor
from sklearn.model_selection import cross_val_score
import numpy as np

# Сравниваем разные loss functions

loss_functions = ['RMSE', 'MAE', 'MAPE', 'Huber']
results = {}

for loss_fn in loss_functions:
    model = CatBoostRegressor(
        loss_function=loss_fn,
        verbose=0,
        iterations=500
    )
    
    # Cross-validation
    scores = cross_val_score(
        model, X_train, y_train,
        cv=5,
        scoring='neg_mean_absolute_error'  # Оцениваем по MAE
    )
    
    results[loss_fn] = {
        'mean_mae': -scores.mean(),
        'std': scores.std()
    }

for loss_fn, metrics in sorted(results.items(), key=lambda x: x[1]['mean_mae']):
    print(f"{loss_fn:10} | MAE: {metrics['mean_mae']:.4f} (+/- {metrics['std']:.4f})")

# Output:
# MAE        | MAE: 2.3450 (+/- 0.1234)
# Huber      | MAE: 2.3521 (+/- 0.1156)
# RMSE       | MAE: 2.4120 (+/- 0.1378)
# MAPE       | MAE: 2.8945 (+/- 0.2134)

Параметры функций потерь

from catboost import CatBoostRegressor

model = CatBoostRegressor(
    loss_function='Quantile',
    loss_function_params={
        'alpha': 0.9  # 90-й квантиль (верхняя граница)
    }
)
model.fit(X_train, y_train)

# Разные функции имеют разные параметры:
# Huber: delta
# Quantile: alpha
# PairLogit: sigma
# YetiRank: decay

Настройка весов классов (для дисбаланса)

from catboost import CatBoostClassifier

# Для несбалансированных данных
model = CatBoostClassifier(
    loss_function='Logloss',
    scale_pos_weight=100,  # Класс 1 в 100 раз важнее
    auto_class_weights='Balanced'  # Или автоматическая балансировка
)
model.fit(X_train, y_train)

Заключение

Выбор правильной функции потерь — критически важен:

  • RMSE — default для регрессии
  • MAE — когда много выбросов
  • MAPE — для разных диапазонов
  • Logloss — для классификации
  • PairLogit/YetiRank — для ранжирования
  • Custom — когда бизнес-логика требует асимметричных потерь

Не забывай: функция потерь определяет, что модель будет оптимизировать. Выбери соответственно своей задаче и метрикам.

С какой функцией потерь можно обучить CatBoost | PrepBro