CatBoost — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Пример использования)
Строка 9: Строка 9:
  
 
----
 
----
 +
== Общий принцип работы ==
  
== Дерево решений ==
+
=== Дерево решений ===
  
  
 
Алгоритм работы следующий: для каждого документа имеется набор значений признаков, имеется дерево, в вершинах которого условия при выполнении которых осуществляется переход в правого ребенка вершины, иначе в левого. Очень просто для конкретно ребенка пройти до листа по дереву в соответствии со значениям признаков для документа. На выходе каждому документу соответствует значение листа. Это и есть ответ.
 
Алгоритм работы следующий: для каждого документа имеется набор значений признаков, имеется дерево, в вершинах которого условия при выполнении которых осуществляется переход в правого ребенка вершины, иначе в левого. Очень просто для конкретно ребенка пройти до листа по дереву в соответствии со значениям признаков для документа. На выходе каждому документу соответствует значение листа. Это и есть ответ.
  
== Бустинг ==
+
=== Бустинг ===
  
 
Одно дерево - хорошо, больше - лучше. Идея состоит в том, чтобы каждое следующее дерево училось на предыдущем, уменьшая ошибку. Итого при достаточно большом количестве деревьев мы сможем сильно уменьшить ошибку, однако не стоит забывать, что чем больше деревьев, тем дольше обучается модель и в какой-то момент прирост качества становится незначительным.
 
Одно дерево - хорошо, больше - лучше. Идея состоит в том, чтобы каждое следующее дерево училось на предыдущем, уменьшая ошибку. Итого при достаточно большом количестве деревьев мы сможем сильно уменьшить ошибку, однако не стоит забывать, что чем больше деревьев, тем дольше обучается модель и в какой-то момент прирост качества становится незначительным.
  
== Градиентный бустинг ==
+
=== Градиентный бустинг ===
  
 
* В основе CatBoost лежит градиентный бустинг.
 
* В основе CatBoost лежит градиентный бустинг.
Строка 26: Строка 27:
  
 
Будем минимизировать ошибку опираясь на градиент.
 
Будем минимизировать ошибку опираясь на градиент.
== Режимы работы ==
+
 
 +
== Особенности CatBoost ==
 +
 
 +
=== Режимы работы ===
  
 
* Регрессия   
 
* Регрессия   
Строка 37: Строка 41:
 
Объекты с попарной классификацией
 
Объекты с попарной классификацией
  
== Оптимизируемые функции ==
+
=== Оптимизируемые функции ===
  
 
  Поддерживает много оптимизируетмых функций. Для конкретной модели выбирается одна оптимизируемая функция.
 
  Поддерживает много оптимизируетмых функций. Для конкретной модели выбирается одна оптимизируемая функция.
  
== Метрики ==
+
=== Метрики ===
  
 
Поддерживает множество метрик, таких как:
 
Поддерживает множество метрик, таких как:
Строка 49: Строка 53:
 
* Ранжирование: ''NDCG, PrecisionAt, RecallAt, PFound, PairLogit'' etc.
 
* Ранжирование: ''NDCG, PrecisionAt, RecallAt, PFound, PairLogit'' etc.
  
== Шаги обучения ==
+
== Обучение ==
 +
=== Шаги обучения ===
  
 
* Строим дерево
 
* Строим дерево
 
* Считаем значение в листьях
 
* Считаем значение в листьях
  
== Построение дерева ==
+
=== Построение дерева ===
  
 
Процесс построения происходит жадно.  
 
Процесс построения происходит жадно.  
Строка 64: Строка 69:
 
Дерево строится по слоям. Гарантировано на каждом слое один и тот же сплит (условие, по которому мы делим)
 
Дерево строится по слоям. Гарантировано на каждом слое один и тот же сплит (условие, по которому мы делим)
  
== Вычисление значений в листьях ==  
+
=== Вычисление значений в листьях ===  
 
Во время вычисления значений в листьях можем позволить себе сделать больше операций, так как у нас уже зафиксирована структура дерева и значения в листьях будут вычислены единожды. Поэтому можем себе позволить даже сделать несколько шагов по градиенту.
 
Во время вычисления значений в листьях можем позволить себе сделать больше операций, так как у нас уже зафиксирована структура дерева и значения в листьях будут вычислены единожды. Поэтому можем себе позволить даже сделать несколько шагов по градиенту.
  
Строка 70: Строка 75:
 
* Несколько шагов внутри одного дерева
 
* Несколько шагов внутри одного дерева
  
== Как выбрать лучшее дерево? ==
+
=== Как выбрать лучшее дерево? ===
  
 
Смотрим на сколько меняется функция ошибки, выбираем такое дерево, чтобы оно как можно лучше приближало вектор градиентов.
 
Смотрим на сколько меняется функция ошибки, выбираем такое дерево, чтобы оно как можно лучше приближало вектор градиентов.
  
== Как работает градиентный бустинг? ==
+
=== Как работает градиентный бустинг? ===
  
 
Отметим, что существует идеальный шаг по градиенту, однако листьев в дереве меньше, чем документов в датасете.
 
Отметим, что существует идеальный шаг по градиенту, однако листьев в дереве меньше, чем документов в датасете.
 
Поэтому мы можем пытаться приближать тот самый идеальный шаг.
 
Поэтому мы можем пытаться приближать тот самый идеальный шаг.
 
Чтобы найти лучший сплит, проверяем похожесть после одного шага алгоритма по градиенту.
 
Чтобы найти лучший сплит, проверяем похожесть после одного шага алгоритма по градиенту.
 +
 +
=== Рандомизация ===
 +
 +
Есть рандомизация метрики, по которой выбирается лучшее дерево.
 +
''Score += random_strength *  Rand (0, lenofgrad * q)''
 +
 +
''q'' - множитель, уменьшающийся при увеличении итерации.
 +
Таким образом, рандом уменьшается ближе к концу.
  
 
----
 
----
Строка 84: Строка 97:
 
== Работа с датасетом ==
 
== Работа с датасетом ==
  
 +
=== Режимов выборки данных ===
  
 
CatBoost поддерживает несколько режимов выборки данных
 
CatBoost поддерживает несколько режимов выборки данных
Строка 92: Строка 106:
 
  Отметим, что бутстрап используется только для выбора структуры дерева, для подсчета значения в листьях используем всю выборку. Это сделано так как выбор структуры дерева происходит долго, нужно несколько раз пересчитывать значения, поэтому использовать всю выборку - слишком дорого. Однако значения в листьях с уже готовой структурой дерева считаются один раз, и для большей точности можно позволить использовать весь датасет.
 
  Отметим, что бутстрап используется только для выбора структуры дерева, для подсчета значения в листьях используем всю выборку. Это сделано так как выбор структуры дерева происходит долго, нужно несколько раз пересчитывать значения, поэтому использовать всю выборку - слишком дорого. Однако значения в листьях с уже готовой структурой дерева считаются один раз, и для большей точности можно позволить использовать весь датасет.
  
== Рандомизация ==
+
=== Бинаризация фичей ===
 
 
Есть рандомизация метрики, по которой выбирается лучшее дерево.
 
''Score += random_strength *  Rand (0, lenofgrad * q)''
 
 
 
''q'' - множитель, уменьшающийся при увеличении итерации.
 
Таким образом, рандом уменьшается ближе к концу.
 
 
 
== Бинаризация фичей ==
 
  
 
  Пробовать все - долго. Поэтому выбираем сетку заранее и ходим по ней.
 
  Пробовать все - долго. Поэтому выбираем сетку заранее и ходим по ней.
Строка 112: Строка 118:
 
* GreedyLogSum - аналог MaxSumLog, однако в основе лежит жадность, поэтому работает не точно, однако быстрее чем MaxSumLog
 
* GreedyLogSum - аналог MaxSumLog, однако в основе лежит жадность, поэтому работает не точно, однако быстрее чем MaxSumLog
  
== Работа с категориальными фичами ==
+
=== Работа с категориальными фичами ===
  
 
* LabelEncoding - на реальных примерах точность работы низкая, так как появляется отношения порядка между объектами.
 
* LabelEncoding - на реальных примерах точность работы низкая, так как появляется отношения порядка между объектами.

Версия 22:49, 25 ноября 2018

Статья посвящена работе с библиотекой CatBoost — методу машинного обучения, основанному на градиентном бустинге.


Практически любой современный метод на основе градиентного бустинга работает с числами. Это приводит к искажению их сути и потенциальному снижению точности работы модели. Именно поэтому было важно научить машину работать не только с числами, но и с категориями напрямую, закономерности между которыми она будет выявлять самостоятельно, без ручной «помощи». CatBoost разработан так, чтобы одинаково хорошо работать «из коробки» как с числовыми признаками, так и с категориальными.

Документацию можно найти здесь: [1].


Общий принцип работы

Дерево решений

Алгоритм работы следующий: для каждого документа имеется набор значений признаков, имеется дерево, в вершинах которого условия при выполнении которых осуществляется переход в правого ребенка вершины, иначе в левого. Очень просто для конкретно ребенка пройти до листа по дереву в соответствии со значениям признаков для документа. На выходе каждому документу соответствует значение листа. Это и есть ответ.

Бустинг

Одно дерево - хорошо, больше - лучше. Идея состоит в том, чтобы каждое следующее дерево училось на предыдущем, уменьшая ошибку. Итого при достаточно большом количестве деревьев мы сможем сильно уменьшить ошибку, однако не стоит забывать, что чем больше деревьев, тем дольше обучается модель и в какой-то момент прирост качества становится незначительным.

Градиентный бустинг

  • В основе CatBoost лежит градиентный бустинг.
  • Градиент функции ошибки - все производные по всем значениям функции

Будем минимизировать ошибку опираясь на градиент.

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

Режимы работы

  • Регрессия
  • Классификация

Функция потерь - максимизируем вероятность того что все объекты в обучающей выборке классифицированы правильно, вероятность - это сигмоида над значением формулы Функция ```predict_proba``` - на вхоже получаем готовый вероятности. Нужно отметить, что складывать их уже нельзя. Функция ```predict``` - выдает необработанный результат. Такой результат можно складывать, например, с результатами других моделей.

  • Мультиклассификация
  • Ранжирование

Объекты с попарной классификацией

Оптимизируемые функции

Поддерживает много оптимизируетмых функций. Для конкретной модели выбирается одна оптимизируемая функция.

Метрики

Поддерживает множество метрик, таких как:

  • Регрессия: MAE, MAPE, RMSE, SMAPE etc.
  • Классификация: Logloss , Precision, Recall, F1, CrossEntropy, BalancedAccuracy etc.
  • Мультиклассификация: MultiClass, MultiClassOneVsAll, HammingLoss, F1 etc.
  • Ранжирование: NDCG, PrecisionAt, RecallAt, PFound, PairLogit etc.

Обучение

Шаги обучения

  • Строим дерево
  • Считаем значение в листьях

Построение дерева

Процесс построения происходит жадно.

  • Выбираем первую вершину
  • Выбираем лучшее дерево с одной вершиной.
  • Считаем метрику и по ней выбираем лучшее дерево.

Дерево строится по слоям. Гарантировано на каждом слое один и тот же сплит (условие, по которому мы делим)

Вычисление значений в листьях

Во время вычисления значений в листьях можем позволить себе сделать больше операций, так как у нас уже зафиксирована структура дерева и значения в листьях будут вычислены единожды. Поэтому можем себе позволить даже сделать несколько шагов по градиенту.

  • Метод Ньютона или шаг по градиенту
  • Несколько шагов внутри одного дерева

Как выбрать лучшее дерево?

Смотрим на сколько меняется функция ошибки, выбираем такое дерево, чтобы оно как можно лучше приближало вектор градиентов.

Как работает градиентный бустинг?

Отметим, что существует идеальный шаг по градиенту, однако листьев в дереве меньше, чем документов в датасете. Поэтому мы можем пытаться приближать тот самый идеальный шаг. Чтобы найти лучший сплит, проверяем похожесть после одного шага алгоритма по градиенту.

Рандомизация

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

Score += random_strength *  Rand (0, lenofgrad * q) 

q - множитель, уменьшающийся при увеличении итерации. Таким образом, рандом уменьшается ближе к концу.


Работа с датасетом

Режимов выборки данных

CatBoost поддерживает несколько режимов выборки данных

  • Бутстрап Бернулли - выбираем документ с вероятностью p. Регулируется параметром sample_rate
  • Байесовский бутстрап - байесовское распределение. Регулируется параметром bagging_temp
Отметим, что бутстрап используется только для выбора структуры дерева, для подсчета значения в листьях используем всю выборку. Это сделано так как выбор структуры дерева происходит долго, нужно несколько раз пересчитывать значения, поэтому использовать всю выборку - слишком дорого. Однако значения в листьях с уже готовой структурой дерева считаются один раз, и для большей точности можно позволить использовать весь датасет.

Бинаризация фичей

Пробовать все - долго. Поэтому выбираем сетку заранее и ходим по ней.

Есть несколько способов выбора:

  • Uniform. Равномерно разбиваем отрезок от минимума значения для данной фичи до максимума.
  • Медианная сетка. Задаем количество разбиений над множеством значений, далее идем по объектам в порядке сортировки и разбиваем на группы по k объектов, где k - количество объектов в одном слоте разбиения.
  • UniformAndQuantiles. Комбинация 1 и 2 пунктов.
  • MaxSumLog - в основе лежит точно правильная динамика, работает долго.
  • GreedyLogSum - аналог MaxSumLog, однако в основе лежит жадность, поэтому работает не точно, однако быстрее чем MaxSumLog

Работа с категориальными фичами

  • LabelEncoding - на реальных примерах точность работы низкая, так как появляется отношения порядка между объектами.
  • One-hot encoding - дает неплохую точность, если различных значений признаков не много. Иначе один признак размножится на множество признаков и будет влиять на модель заведомо сильнее остальных фичей.
Лучше не делать препроцессинг самим, из-за проблем, описанных выше. В CatBoost можно задать параметр cat_features, передав туда индексы категориальных фичей. Также можно отрегулировать параметр one_hot_max_size - максимальное количество различных значений у категориального признака, чтобы он мог в последствии быть подвержен one-hot encoding.

Подбор параметров

Ниже описаны гиперпараметры, на которые стоит обратить внимание при использовании библиотеки.

  • cat_features
  • Overfitting detector
  • Число итераций и learning rate
  • L2_reg
  • Random_srength
  • Bagging_temp
  • Глубина дерева (стоит попробовать 10 и 6)

Полезная функциональность

  • Snapshots
  • Overfitting detector
  • CV
  • eval_metrics

Бенчмрки

Сравнение библиотеки CatBoost с открытыми аналогами XGBoost, LightGBM и H20 на наборе публичных датасетов. Результаты - [2]

Пример использования

  • Делим данные на тренировочное и тестовое множество
X_train, X_validation, y_train, y_validation = train_test_split(X, y, train_size=0.5, random_state=1234)
print(X_train.shape, X_validation.shape)
  • Создаем классификатор
from catboost import CatBoostClassifier
best_model = CatBoostClassifier(
   bagging_temperature=1,
   random_strength=1,
   thread_count=3,
   iterations=500,
   l2_leaf_reg = 4.0, 
   learning_rate = 0.07521709965938336,
   save_snapshot=True,
   snapshot_file='snapshot_best.bkp',
   random_seed=63,
   od_type='Iter',
   od_wait=20,
   custom_loss=['AUC', 'Accuracy'],
   use_best_model=True
)
  • Обучаемся
best_model.fit(
   X_train, y_train,
   cat_features=cat_features,
   eval_set=(X_validation, y_validation),
   logging_level='Silent',
   plot=True
)

  • Вывод числа деревьев в модели
print('Resulting tree count:', best_model.tree_count_)
> Resulting tree count: 217
  • Используем кросс валидацию
from catboost import cv
params = best_model.get_params()
params['iterations'] = 10
params['custom_loss'] = 'AUC'
del params['use_best_model']
pool1 = Pool(X, label=y, cat_features=cat_features)
cv_data = cv(
   params = params,
   pool = pool1,
   fold_count=2,
   inverted=False,
   shuffle=True,
   stratified=False,
   partition_random_seed=0
)
  • Выводим результат
best_value = np.max(cv_data['AUC_test_avg'])
best_iter = np.argmax(cv_data['AUC_test_avg'])
print('Best validation AUC score: {:.2f}±{:.2f} on step {}'.format(
   best_value,
   cv_data['AUC_test_stddev'][best_iter],
   best_iter
))
> Best validation AUC score: 0.91±0.00 on step 9


Больше примеров можно найти на сайте библиотеки[3]