Как настроить гиперпараметры XGBoost и повысить производительность вашей модели?

Почему XGBoost так популярен?

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

Многие считают его одним из лучших алгоритмов и из-за его высокой производительности при решении задач регрессии и классификации рекомендуют его в качестве первого выбора во многих ситуациях. XGBoost прославился тем, что выиграл множество соревнований Kaggle, теперь используется во многих отраслевых приложениях и даже реализован в платформах машинного обучения, таких как BigQuery ML.

Если вы читаете эту статью об оптимизации гиперпараметров XGBoost, вы, вероятно, знакомы с алгоритмом. Но чтобы лучше понять, что мы хотим настроить, давайте подведем итоги!

ЧАСТЬ 1: Понимание XBGoost

XGBoost (eXtreme Gradient Boosting) - это не только алгоритм. Это целая библиотека с открытым исходным кодом, разработанная как оптимизированная реализация фреймворка Gradient Boosting. Основное внимание уделяется скорости, гибкости и характеристикам модели. Его сила заключается не только в алгоритме, но и во всей базовой оптимизации системы (распараллеливание, кэширование, оптимизация оборудования и т. Д.).

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

В этот момент у вас, вероятно, возникнет еще больше вопросов. Что такое дерево решений? Что такое повышение? В чем разница с Gradient Boosting?
Не волнуйтесь, мы подведем итоги!

Что такое деревья решений и корзины?

Дерево решений - один из простейших алгоритмов машинного обучения.

Это способ реализации алгоритма, который содержит только условные операторы.

XGBoost использует тип дерева решений, называемый CART: Classification and Decision Tree.

  • Деревья классификации: целевая переменная является категориальной, и дерево используется для определения «класса», в который, вероятно, попадает целевая переменная.
  • Деревья регрессии: целевая переменная является непрерывной, и дерево используется для прогнозирования ее значения.

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

Что такое повышение?

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

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

Случайные леса и Бэггинг - два известных метода ансамблевого обучения.

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

Что такое повышение градиента?

Наконец, Gradient Boosting - это метод повышения, при котором ошибки минимизируются с помощью алгоритма градиентного спуска. Проще говоря, градиентный спуск - это итеративный алгоритм оптимизации, используемый для минимизации функции потерь.

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

При построении нашей модели цель состоит в том, чтобы минимизировать функцию потерь по всем точкам данных. Например, среднеквадратичная ошибка (MSE) является наиболее часто используемой функцией потерь для регрессии.

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

Как мы уже говорили во вступлении, XGBoost - это оптимизированная реализация этого метода градиентного усиления!

Итак, как использовать XGBoost?

Есть 2 распространенных способа использования XGBoost:

  • Learning API: это базовый низкоуровневый способ использования XGBoost. Простой и мощный, он включает встроенный метод перекрестной проверки.
import xgboost as xgb
 
X, y = #Import your data
dmatrix = xgb.DMatrix(data=x, label=y) #Learning API uses a dmatrix
params = {'objective':'reg:squarederror'}
cv_results = xgb.cv(dtrain=dmatrix, 
                    params=params, 
                    nfold=10, 
                    metrics={'rmse'})
print('RMSE: %.2f' % cv_results['test-rmse-mean'].min())
  • Scikit-Learn API: это интерфейс-оболочка Scikit-Learn для XGBoost. Он позволяет использовать XGBoost совместимым с scikit-learn способом, точно так же, как вы использовали бы любую нативную модель scikit-learn.
import xgboost as xgb
X, y = # Import your data
xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.2)
xgbr = xgb.XGBRegressor(objective='reg:squarederror')
xgbr.fit(xtrain, ytrain)
 
ypred = xgbr.predict(xtest)
mse = mean_squared_error(ytest, ypred)
print("RMSE: %.2f" % (mse**(1/2.0)))

Обратите внимание, что при использовании Learning API вы можете вводить и получать доступ к метрике оценки, тогда как при использовании Scikit-learn API вы должны ее вычислить.

Целевая функция

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

Чаще всего используются:

  • reg: squarederror: для линейной регрессии.
  • reg: logistic: для логистической регрессии.
  • двоичный: логистический: для логистической регрессии - с выводом вероятностей.

ЧАСТЬ 2: Настройка гиперпараметров

Зачем настраивать свою модель?

Как будет работать ненастроенная модель по сравнению с настроенной моделью? Стоит ли прилагать усилия? Прежде чем углубляться в настройку модели XGBoost, давайте выделим причины, по которым вам необходимо настроить свою модель.

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

Вот как бы выполнить нашу модель без настройки гиперпараметров:

import xgboost as xgb
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
 
boston = load_boston()
X, y = boston.data, boston.target
dmatrix = xgb.DMatrix(data=x, label=y)
params={'objective':'reg:squarederror'}
cv_results = xgb.cv(dtrain=dmatrix, params=params, nfold=10, metrics={'rmse'}, as_pandas=True, seed=20)
print('RMSE: %.2f' % cv_results['test-rmse-mean'].min())

## Result : RMSE: 3.38

Без какой-либо настройки мы получили RMSE 3,38. Что неплохо, но давайте посмотрим, как это будет работать с несколькими настроенными гиперпараметрами:

import xgboost as xgb
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
 
boston = load_boston()
X, y = boston.data, boston.target
dmatrix = xgb.DMatrix(data=x, label=y)
params={ 'objective':'reg:squarederror',
         'max_depth': 6, 
         'colsample_bylevel':0.5,
         'learning_rate':0.01,
         'random_state':20}
cv_results = xgb.cv(dtrain=dmatrix, params=params, nfold=10, metrics={'rmse'}, as_pandas=True, seed=20, num_boost_round=1000)
print('RMSE: %.2f' % cv_results['test-rmse-mean'].min())

## Result : RMSE: 2.69

После небольшой настройки мы получили RMSE 2,69. Это улучшение на 20%! И, вероятно, мы могли бы стать еще лучше. Посмотрим как!

Глубокое погружение в гиперпараметры XGBoost

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

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

Перед этим обратите внимание, что есть несколько параметров, которые вы можете настроить при работе с XGBoost. Вы можете найти полный список здесь или псевдонимы, используемые в Scikit-Learn API.

Для учащихся Tree base наиболее распространенными параметрами являются:

  • max_depth: максимальная глубина для дерева. Более глубокое дерево может повысить производительность, но также сложность и вероятность переобучения.
    Значение должно быть целым числом больше 0. По умолчанию - 6.
  • Learning_rate: скорость обучения определяет размер шага на каждой итерации, пока ваша модель оптимизируется для достижения своей цели. Низкая скорость обучения замедляет вычисления и требует большего количества раундов для достижения такого же снижения остаточной ошибки, что и модель с высокой скоростью обучения. Но это оптимизирует шансы на достижение наилучшего оптимума.
    Значение должно быть от 0 до 1. По умолчанию - 0,3.
  • n_estimators: количество деревьев в нашем ансамбле. Эквивалентно количеству раундов повышения.
    Значение должно быть целым числом больше нуля.
    Примечание: в стандартной библиотеке это называется num_boost_round.
  • colsample_bytree: представляет долю столбцов, выбираемых случайным образом для каждого дерева. Это может улучшить переоснащение.
    Значение должно быть от 0 до 1. По умолчанию - 1.
  • подвыборка: представляет долю наблюдений, которые нужно выбрать для каждого дерева. Более низкие значения предотвращают переобучение, но могут привести к недообучению.
    Значение должно быть от 0 до 1. По умолчанию - 1.

Параметры регуляризации:

  • альфа (reg_alpha): регуляризация L1 весов (регрессия лассо). При работе с большим количеством функций это может улучшить быстродействие. Это может быть любое целое число. По умолчанию 0.
  • лямбда (reg_lambda): L2 регуляризация весов (регрессия гребня). Это может помочь уменьшить переобучение. Это может быть любое целое число. По умолчанию 1.
  • гамма: гамма - это параметр псевдорегуляризации (множитель Лагранжа), который зависит от других параметров. Чем выше гамма, тем выше регуляризация. Это может быть любое целое число. По умолчанию 0.

Подход 1: интуиция и разумные ценности

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

Начнем с разумных ценностей. Обычно это:

max_depth: 3–10
n_estimators: от 100 (много наблюдений) до 1000 (несколько наблюдений)
Learning_rate: 0,01–0,3
colsample_bytree: 0,5–1
подвыборка
: 0,6–1

Затем вы можете сосредоточиться на оптимизации max_depth и n_estimators.

Затем вы можете поиграть с скоростью обучения и увеличить ее, чтобы ускорить модель без снижения производительности. Если он станет быстрее без потери производительности, вы можете увеличить количество оценщиков, чтобы попытаться повысить производительность.

Наконец, вы можете работать со своими параметрами регуляризации, обычно начиная с альфа и лямбда. Для гаммы 0 означает отсутствие регуляризации, обычно используются значения 1–5, тогда как 10+ считается очень высоким.

Подход 2: алгоритмы оптимизации

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

Двумя наиболее распространенными являются поиск по сетке и случайный поиск.

Поиск по сетке

Поиск по сетке - это исчерпывающий поиск по каждой комбинации указанных значений параметров. Если вы укажете 2 возможных значения для max_depth и 3 для n_estimators, поиск по сетке будет перебирать 6 возможных комбинаций:

max_depth: [3,6],
n_estimators: [100, 200, 300]

Результатом будут следующие возможности:
max_depth: 3, n_estimators: 100
max_depth: 3, n_estimators: 200
max_depth: 3, n_estimators: 300
max_depth: 6, n_estimators: 100
max_depth: 6, n_estimators: 200
max_depth: 6, n_estimators: 300

Давайте воспользуемся GridSearchCV () из Scikit-learn, чтобы настроить нашу модель XGBoost!

В следующих примерах мы будем использовать обработанную версию набора данных о продолжительности жизни, доступного на Kaggle.

import pandas as pd
import xgboost as xgb
from sklearn.model_selection import GridSearchCV
data = pd.read_csv("life_expectancy_clean.csv")
X, y = data[data.columns.tolist()[:-1]],
       data[data.columns.tolist()[-1]]
params = { 'max_depth': [3,6,10],
           'learning_rate': [0.01, 0.05, 0.1],
           'n_estimators': [100, 500, 1000],
           'colsample_bytree': [0.3, 0.7]}
xgbr = xgb.XGBRegressor(seed = 20)
clf = GridSearchCV(estimator=xgbr, 
                   param_grid=params,
                   scoring='neg_mean_squared_error', 
                   verbose=1)
clf.fit(X, y)
print("Best parameters:", clf.best_params_)
print("Lowest RMSE: ", (-clf.best_score_)**(1/2.0))
  • Estimator: GridSearchCV является частью sklearn.model_selection и работает с любым scikit-learn совместимым оценщиком. Мы используем xgb.XGBRegressor () из Scikit-learn API XGBoost.
  • param_grid: GridSearchCV принимает список параметров для проверки при вводе. Как мы уже говорили, поиск по сетке проверяет каждую комбинацию.
  • скоринг: это показатели, которые будут использоваться для оценки эффективности модели с перекрестной проверкой. В этом случае neg_mean_squared_error используется вместо mean_squared_error. GridSearchCV просто использует отрицательную версию MSE по техническим причинам - таким образом, это делает функцию обобщаемой для других показателей, где мы стремимся к более высокому баллу, а не к более низкому.
  • verbose: контролирует многословность. Чем выше, тем больше сообщений.

Дополнительные параметры по мере возможности, вы можете узнать в документации.

Наконец, самый низкий RMSE на основе отрицательного значения clf.best_score_
И лучшие параметры с clf.best_params_

Best parameters: {'colsample_bytree': 0.7, 'learning_rate': 0.05, 'max_depth': 6, 'n_estimators': 500}

Случайный поиск

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

Если вы вводите 10 возможных значений для max_depth, 200 возможных значений для n_estimators и выбираете выполнение 10 итераций:

max_depth: np.arrange (1,10,1),
n_estimators: np.arrange (100,400,2)

Пример случайных возможностей с 10 итерациями:
1: max_depth: 1, n_estimators: 110
2: max_depth: 3, n_estimators: 222
3: max_depth: 3, n_estimators: 306
4: max_depth: 4, n_estimators: 102
5: max_depth: 1, n_estimators: 398
6: max_depth: 6, n_estimators: 290
7: max_depth: 9, n_estimators: 102 < br /> 8: max_depth: 6, n_estimators: 310
9: max_depth: 3, n_estimators: 344
10: max_depth: 6, n_estimators: 202

Теперь давайте воспользуемся RandomSearchCV () из Scikit - научимся настраивать нашу модель!

import pandas as pd
import numpy as np
import xgboost as xgb
from sklearn.model_selection import RandomizedSearchCV
data = pd.read_csv("life_expectancy_clean.csv")
X, y = data[data.columns.tolist()[:-1]],
       data[data.columns.tolist()[-1]]
params = { 'max_depth': [3, 5, 6, 10, 15, 20],
           'learning_rate': [0.01, 0.1, 0.2, 0.3],
           'subsample': np.arange(0.5, 1.0, 0.1),
           'colsample_bytree': np.arange(0.4, 1.0, 0.1),
           'colsample_bylevel': np.arange(0.4, 1.0, 0.1),
           'n_estimators': [100, 500, 1000]}
xgbr = xgb.XGBRegressor(seed = 20)
clf = RandomizedSearchCV(estimator=xgbr,
                         param_distributions=params,
                         scoring='neg_mean_squared_error',
                         n_iter=25,
                         verbose=1)
clf.fit(X, y)
print("Best parameters:", clf.best_params_)
print("Lowest RMSE: ", (-clf.best_score_)**(1/2.0))
  • Большинство параметров RandomizedSearchCV аналогичны параметрам GridSearchCV.
  • n_iter: это количество выбираемых комбинаций параметров.
    Чем больше, тем больше комбинаций вы будете тестировать. Он жертвует временем работы и качеством решения.

Что касается GridSearchCV, мы печатаем лучшие параметры с помощью clf.best_params_
И самый низкий RMSE на основе отрицательного значения clf.best_score _

Заключение

В этой статье мы объяснили, как работает XGBoost, чтобы лучше понять, как настроить его гиперпараметры. Как мы видели, настройка обычно приводит к значительному улучшению характеристик модели.

Иногда бывает достаточно использовать нашу интуицию для настройки нашей модели. Также стоит попробовать алгоритмы оптимизации, такие как GridSearch и RandomSearch.
Но в большинстве случаев вы получите еще лучший результат, используя сочетание алгоритмов и корректировок благодаря тестированию и интуиции!