Search
Write a publication
Pull to refresh

Настройка RMSLE для CatBoost Regressor

Intro

Вот уже третий год подряд компания SIBUR организовывает собственные соревнования в областях Data Science, AI, и ML, предлагая для решения реальные кейсы основанные на реальных данных компании. В 2021 году соревнование Sibur Challenge 2021 собрало 161 участника. Задачей поставленной перед участниками являлось создание предикативной модели для помесячного прогнозирования объемов закупок определенного типа товаров.

https://habr.com/ru/company/sibur_official/news/t/593027
https://habr.com/ru/company/sibur_official/news/t/593027

Решение задач прогнозирования

Для решения задачи прогнозирования (задача регрессии) была выбрана библиотека CatBoost разработанная компанией "Яндекс", использующая градиентный бустинг на деревьях решений. В связи с наличием большого количества категориальных признаков в предоставленных исходных данных модель CatBoostRegressor показалась наиболее удобной в работе.

https://yandex.com/company/blog/yandex-catboost/

RMSLE и работа с CatBoostRegressor

Если Вы работаете в Google Collab для работы с библиотекой CatBoost необходимо установить данный пакет при помощи команды

!pip install catboost

Подключаем CatBoost

from catboost import CatBoostRegressor

Для объявления модели CatBoostRegressor необходимо вызвать ее конструктор.

 model = CatBoostRegressor(iterations=3000,
                          early_stopping_rounds=100,
                          grow_policy = 'Depthwise',
                          depth=8,
                          loss_function=RMSLE(),
                          cat_features= CAT_COLS,
                          random_state=RS,
                          l2_leaf_reg = 1,
                          learning_rate=0.03,
                          verbose=10,
                          eval_metric=RMSLE_val())

loss_function - параметр отвечающий за метрику ошибки при обучении модели.

eval_metric - параметр отвечающий за метрику обнаружения переобучения.

Библиотека CatBoost имеет также встроенные функции потерь. О их наличии можно ознакомиться в официальной документации :
https://catboost.ai/en/docs/concepts/loss-functions-regression

https://catboost.ai/en/docs/concepts/python-reference_catboostregressor_eval-metrics

Как можно было заметить функция RMSLE - не является встроенной в библиотеку CatBoost. Выходом из данной ситуации служат кастомные метрики, которые пользователь сам может создать для дальнейшего использования при обучении и валидации моделей. Но сначала разберемся что же такое RMSLE:

RMSLE (Root Mean Squared Log Error) - среднеквадратичная логарифмическая ошибка. Вычисляется по следующей формуле:

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

Для создания собственной "кастомной метрики", необходимо представить функцию вычисляющую метрику в виде объекта. Ниже представлен код на языке Python вычисляющий loss_function и evaluation_metric для CatBoostRegressor. Заметим, что вычисление производной было заменено на более упрощенное выражение.

import math
class RMSLE(object):
    def calc_ders_range(self, approxes, targets, weights):
        assert len(approxes) == len(targets)
        if weights is not None:
            assert len(weights) == len(approxes)

        result = []
        for index in range(len(targets)):
            val = max(approxes[index], 0)
            der1 = math.log1p(targets[index]) - math.log1p(max(0, approxes[index]))
            der2 = -1 / (max(0, approxes[index]) + 1)

            if weights is not None:
                der1 *= weights[index]
                der2 *= weights[index]

            result.append((der1, der2))
        return result
class RMSLE_val(object):
    def get_final_error(self, error, weight):
        return np.sqrt(error / (weight + 1e-38))

    def is_max_optimal(self):
        return False

    def evaluate(self, approxes, target, weight):
        assert len(approxes) == 1
        assert len(target) == len(approxes[0])

        approx = approxes[0]

        error_sum = 0.0
        weight_sum = 0.0

        for i in range(len(approx)):
            w = 1.0 if weight is None else weight[i]
            weight_sum += w
            error_sum += w * ((math.log1p(max(0, approx[i])) - math.log1p(max(0, target[i])))**2)

        return error_sum, weight_sum

Теперь при работе с CatBoostRegressor model можно указывать как loss_function и eval_metric наш объект RMSLE() и RMSLE_VAL() соответственно:

 model = CatBoostRegressor(iterations=3000,
                          early_stopping_rounds=100,
                          grow_policy = 'Depthwise',
                          depth=8,
                          loss_function=RMSLE(),
                          cat_features= CAT_COLS,
                          random_state=RS,
                          l2_leaf_reg = 1,
                          learning_rate=0.03,
                          verbose=10,
                          eval_metric=RMSLE_val())
params = {'l2_leaf_reg':[1,4,8],
          'learning_rate': [0.03,0.5,0.1]
          'depth':[6,8,10]
         }
grid_search_res = model.grid_search(params, full_features['items'][FTS_COLS], full_features['items'].target, train_size=0.8)
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.