машинное обучение
October 12, 2022

Ключевые плюшки от подбора гиперпараметров в Sklearn

Изобилие плохо, когда его нет у тебя и оно есть у соседа.

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

import pandas as pd
import numpy as np
np.random.seed(0)

df = pd.read_csv("https://s3.amazonaws.com/h2o-public-test-data/smalldata/gbm_test/titanic.csv")

df[['age', 'body', 'fare']] = df[['age', 'body', 'fare']].\
                             fillna(df[['age', 'body', 'fare']].agg('median').to_dict())
df = df.fillna('unknown')

df = df.sample(frac=1).reset_index(drop=True)
df.head()

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

id_cols = ['name', 'ticket']
target_col = 'survived'

cat_cols = df.drop([target_col]+id_cols, axis=1).select_dtypes(exclude=np.number)\
                                                    .columns.tolist()
num_cols = df.drop([target_col]+id_cols, axis=1).select_dtypes(include=np.number)\
                                                    .columns.tolist()

display(cat_cols)
display(num_cols)
tr_idx, ts_idx = np.split(np.arange(df.shape[0]), [round(0.8*df.shape[0])])

Ниже проведем подбор гиперпараметров с GridSearchCV:

from sklearn.model_selection import GridSearchCV
from lightgbm import LGBMClassifier

model_lgb = LGBMClassifier()

params = {'max_depth':[1,3,5]}

gr_s = GridSearchCV(model_lgb, params, scoring='roc_auc', cv=5)
gr_s.fit(df.drop(columns=id_cols+[target_col])\
         .astype({it:'category' for it in cat_cols}).iloc[tr_idx], df[target_col].iloc[tr_idx])

Алгоритм с лучшими параметрами на валидационном наборе можно извлечь из свойства best_estimator_:

gr_s.best_estimator_ 

В best_score_ и best_params_ содержатся значение валидационной метрики и параметров найденной оптимальной модели:

gr_s.best_score_
gr_s.best_params_

Не менее полезна сводная статистика для каждого набора параметров, хранящаяся в свойстве cv_results_:

grid_res = pd.DataFrame(gr_s.cv_results_).sort_values(by='rank_test_score')
grid_res

Как можно заметить, по полю rank_test_score можно упорядочить результаты и вывести статистику для выбранной модели, например, время обучения и предсказания:

grid_res.iloc[0]['mean_fit_time'], grid_res.iloc[0]['mean_score_time']

Это же можно сделать по-другому, обратившись к строке с номером best_index_:

pd.DataFrame(gr_s.cv_results_).iloc[gr_s.best_index_]