Архив метки: xgboost

Hyperopt и xgboost: Пример поиска гиперпараметров с помощью Hyperopt для xgboost

Xgboost пожалуй самая популярная библиотека градиентного бустинга, поэтому именно на её примере покажу как можно улучшить качество простым техническим приёмом — автоматическим подбором параметров. Чтобы не усложнять поиск оптимальных гиперпараметров, возьмем лишь несколько основных: n_estimators, eta и max_depth. Основная идея библиотеки hyperopt — это построение математической гипотезы о том как выглядит функция результа на множества параметров и проверка этой гипотезы с каждой итерацией. Т.к. перебор и обучение может быть весьма продолжительны — то на вход задается количество итерации, после которого происходит остановка поиска. Но все равно предсказать, когда закончится поиск проблематично т.к. при разных гиперпараметрах обучение и предсказание занимает разное время. Поэтому я и советую начинать с небольшого количества итерации и небольшого количества параметров. К сожалению останова по истечению заранее заданного времени нет, поэтому мощный комьютер для data-sciece вам в руки и вперед!

import numpy as np
from sklearn import datasets
from sklearn.model_selection import cross_val_score
from xgboost import XGBClassifier

from hyperopt import hp, tpe
from hyperopt.fmin import fmin

# Для теста возьмем классический сет "ирисы Фишера"
# Разумеется вместо X и y Вам следует взять свои фичи и таргет
iris = datasets.load_iris()
X = iris.data
y = iris.target


def hyperopt_xgb_score(params):
    clf = XGBClassifier(**params)
    # усреднение по 3ем фолдам, для уменьшения влияния стахостичности
    # для ускорения можно использовать train_test_split один раз
    current_score = cross_val_score(clf, X, y, cv=3).mean()
    print(current_score, params)
    return -current_score


simple_space_xgb = {
            'n_estimators': hp.choice('n_estimators', range(100, 1000)),
            'eta': hp.quniform('eta', 0.025, 0.5, 0.025),
            'max_depth':  hp.choice('max_depth', np.arange(1, 14, dtype=int)),
}

best = fmin(fn=hyperopt_xgb_score, space=simple_space_xgb, algo=tpe.suggest, max_evals=10)
print('best:')
print(best)

Как видимо нет ничего сложного, главное определить:
1) пространство параметров, внутри которых hyperopt будет оптимизировать
2) функцию оценки.
Обратите внимание, что в функции оценки возвращается результат со знаком минус — это сделано специально, т.к. гиперопт минимизирует функционал, а нам надо максимизировать точность.
Для построения пространства в основном используется либо набор возможных значений (hp.choice) либо отрезок в пространстве R hp.quniform(label, low, high, q), где q округление.
Для тех, кто планирует более мощную настройку, оставлю space более мощный для XGB.

space_xgb2 = {
            'n_estimators': hp.choice('n_estimators', range(100, 1000)),
            'eta': hp.quniform('eta', 0.025, 0.5, 0.025),
            'max_depth':  hp.choice('max_depth', np.arange(1, 14, dtype=int)),
            'min_child_weight': hp.quniform('min_child_weight', 1, 6, 1),
            'subsample': hp.quniform('subsample', 0.5, 1, 0.05),
            'gamma': hp.quniform('gamma', 0.5, 1, 0.05),
            'colsample_bytree': hp.quniform('colsample_bytree', 0.5, 1, 0.05),
            'eval_metric': 'auc',
            'objective': 'binary:logistic',
            # Increase this number if you have more cores. Otherwise, remove it and it will default
            # to the maxium number.
            'nthread': 4,
            'booster': 'gbtree',
            'tree_method': 'exact',
            'silent': 1
        }

Теперь с помощью данного поста Вы можете построить оптимизацию гиперпараметров не ограничиваясь xgboost.