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

Алгоритм действий такой:

  1. Создайте словарь со значениями гиперпараметров для случайного поиска и поиска по сетке:
  • min_samples_split в диапазоне от 2 до 6 (не включительно);
  • min_samples_leaf в диапазоне от 1 до 6 (не включительно);
  • max_depth в диапазоне от 2 до 6 (не включительно).
  1. Инициализируйте классы для случайного поиска и поиска по сетке со значением кросс-валидации 5 и метрикой roc-auc.
  2. Задайте распределение гиперпараметров для байесовской оптимизации с такими же значениями гиперпараметров, как и для двух других способов.
  3. Инициализируйте класс для байесовской оптимизации на 20 итераций со значением кросс-валидации 5 и метрикой roc-auc.
# импортируем библиотеки и объявляем константы
import pandas as pd
from sklearn.model_selection import (
    train_test_split,
    GridSearchCV,
    RandomizedSearchCV
)
from sklearn.preprocessing import OneHotEncoder
from sklearn.tree import DecisionTreeClassifier
import time

from optuna import distributions
from optuna.integration import OptunaSearchCV

pd.set_option('display.max_columns', None)
pd.set_option('display.max_colwidth', None)

RANDOM_STATE = 42

# подготавливаем данные заранее созданной функцией
X_train, X_test, y_train, y_test = prepare_data('train_satisfaction.csv')

# инициализируем модель дерева решений
model = DecisionTreeClassifier(random_state=RANDOM_STATE)

# Создайте словарь с гиперпараметрами:
# - min_samples_split в диапазоне от 2 до 6 (не включительно)
# - min_samples_leaf в диапазоне от 1 до 6 (не включительно)
# - max_depth в диапазоне от 2 до 6 (не включительно)
gs_rs_parameters = {
    'min_samples_split': range(2, 6),
    'min_samples_leaf': range(1, 6),
    'max_depth': range(2, 6)
} 

# запускаем таймер
start = time.time()

# Инициализируйте класс для поиска по сетке:
# значение кросс-валидации 5, метрика roc-auc и n_jobs=-1.
gs = GridSearchCV(model,
                  gs_rs_parameters,
                  n_jobs=-1,
                  cv=5,
                  scoring='roc_auc')

# запускаем поиск гиперпараметров
gs.fit(X_train, y_train)

# считаем, сколько секунд прошло с начала запуска
gs_search_time = time.time() - start

# запускаем таймер
start = time.time()

# Инициализируйте класс для случайного поиска:
# значение кросс-валидации 5, метрика roc-auc и n_jobs=-1.
rs = RandomizedSearchCV(model,
                        gs_rs_parameters,
                        n_jobs=-1,
                        cv=5,
                        scoring='roc_auc',
                        random_state=RANDOM_STATE
                       )
# запускаем поиск гиперпараметров
rs.fit(X_train, y_train)

# считаем, сколько секунд прошло с начала запуска
rs_search_time = time.time() - start

# Создайте словарь с гиперпараметрами для байесовской оптимизации:
# - min_samples_split в диапазоне от 2 до 6 (не включительно)
# - min_samples_leaf в диапазоне от 1 до 6 (не включительно)
# - max_depth в диапазоне от 2 до 6 (не включительно)
oscv_parameters = {'min_samples_split': distributions.IntDistribution(2, 5),
              'min_samples_leaf': distributions.IntDistribution(1, 5),
              'max_depth': distributions.IntDistribution(2, 5)
             }

# запускаем таймер
start = time.time()

# Инициализируйте класс для байесовского поиска на 20 итераций:
# значение кросс-валидации 5, метрика roc-auc
oscv = OptunaSearchCV(model,
                      oscv_parameters,
                      scoring='roc_auc',
                      cv=5,
                      n_trials=20,
                      random_state=RANDOM_STATE
                     )

# запускаем поиск гиперпараметров
oscv.fit(X_train, y_train)

# считаем, сколько секунд прошло с начала запуска
oscv_search_time = time.time() - start

# объединяем результаты в одну таблицу
result = pd.DataFrame([
    [gs.best_score_, gs.best_params_, gs_search_time],
    [rs.best_score_, rs.best_params_, rs_search_time],
    [oscv.best_score_, oscv.best_params_, oscv_search_time]
])
result.index = ['GridSearchCV', 'RandomizedSearchCV', 'OptunaSearchCV']
result.columns = ['best_score_', 'best_params_', 'Search time']
print(result)

                    best_score_  
GridSearchCV           0.896743   
RandomizedSearchCV     0.893825   
OptunaSearchCV         0.896743   

                                                                       best_params_  
GridSearchCV        {'max_depth': 4, 'min_samples_leaf': 1, 'min_samples_split': 2}   
RandomizedSearchCV  {'min_samples_split': 4, 'min_samples_leaf': 3, 'max_depth': 5}   
OptunaSearchCV      {'min_samples_split': 4, 'min_samples_leaf': 1, 'max_depth': 4}   

                    Search time  
GridSearchCV           3.647023  
RandomizedSearchCV     0.422729  
OptunaSearchCV         1.136326