машинное обучение
May 29, 2022

Подбор гиперпараметров модели с помощью Hyperopt

Рассмотрим библиотеку подбора гиперпараметров модели Hyperopt. В отличие от GridSearchCV и RandomizedSearchCV в ней используются методы интеллектуального перемещения по пространству параметров с целью нахождения более подходящих значений. В демонстрационных целях создадим набор данных:

import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
import numpy as np
np.random.seed(0)

ar, y = make_classification(n_samples=10000, n_features=3, n_informative=2, 
                           n_redundant=0, class_sep = 0.2, shuffle=False, 
                           flip_y=0, n_clusters_per_class=2)

df = pd.DataFrame(ar, columns = ['feat1', 'feat2', 'feat3'])
df['y'] = y
# мешаем
df = df.sample(frac=1).reset_index(drop=True)
df

Разделим датасет на выборки:

from sklearn.model_selection import train_test_split
X_cv, X_ts, y_cv, y_ts = train_test_split(df.drop(columns='y').copy(), 
                                          df['y'], test_size=0.2)

Для оптимизации с помощью hyperopt задайте:

1) целевую функцию, в которой возвращается словарь с обязательными loss значением (чем оно меньше тем лучше, поэтому для увеличения метрики умножьте ее на "-1") и статусом (другие ключи опциональны);

2) пространство поиска, функции выборки параметров можно найти здесь;

3) специальный объект Trials, хранящий историю результатов;

4) затем запустите функцию fmin с заданными аргументами;

from hyperopt import fmin, tpe, hp, STATUS_OK, Trials
from sklearn.model_selection import cross_val_score

def obj_f(params):
  clf = DecisionTreeClassifier(**params, random_state = 0)
  return {'loss': -cross_val_score(clf, X_cv, y_cv, scoring='f1').mean(), 
          'params': params, 'status': STATUS_OK}


search_space = {
    'max_depth': hp.choice('max_depth', range(5,20)),
    'min_samples_split': hp.choice('min_samples_split', range(2,5))
}

trials = Trials()
fmin(   
    fn=obj_f, 
    space=search_space,
    algo=tpe.suggest, 
    max_evals=10,
    trials=trials
)

trials.best_trial['result']


Аргументы fmin:

fn содержит ссылку на целевую функцию;

space - пространство параметров;

algo - алгоритм подбора (подробнее здесь);

max_evals - количество попыток;

trials - хранилище результатов.

После отработки fmin словарь trials.best_trial['result'] будет содержать лучшие параметры и значение loss. Проверим это в цикле по всем trial-ам:

min=0
for i in range(10):
  if trials.trials[i]['result']['loss']<min:
    params = trials.trials[i]['result']['params']
    min = trials.trials[i]['result']['loss']
print(min)

print(params)

В последующем можно создать экземпляр модели с лучшими параметрами:

clf = DecisionTreeClassifier(random_state=0, **trials.best_trial['result']['params'])
cross_val_score(clf, X_cv, y_cv, scoring='f1').mean()

Полезные ссылки:

1. Теория алгоритмов оптимизации

2. Статья с кейсами перебора гиперпараметров для различных моделей

3. Статья с описание библиотеки Hyperopt c конференции Scipy

4. Подбор гиперпараметров модели с GridSearchCV и RandomizedSearchCV

5. Подбор гиперпараметров с помощью Optuna.

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram