Ранняя остановка с LightGBM
Рассмотрим, как осуществить подбор оптимального количества деревьев для максимизации качества заданной метрики с градиентным бустингом LightGBM. Сначала сгенерируем рабочий датасет:
import pandas as pd from sklearn.datasets import make_classification import numpy as np np.random.seed(0) ar, y = make_classification(n_samples=1000, n_features=3, n_informative=2, n_redundant=0, class_sep = 0.5, shuffle=False, flip_y=0, n_clusters_per_class=2) df = pd.DataFrame(ar, columns = ['feat1', 'feat2', 'feat3']) df['feat4'] = pd.cut(df['feat2'], 5, labels=False) 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) X_tr, X_val, y_tr, y_val = train_test_split(X_cv.copy(), y_cv, test_size=0.25) y_tr.shape[0], y_ts.shape[0], y_val.shape[0]
Инициализируем объект класса LGBMClassifier максимальным количеством деревьев и количеством итераций, в течение которых если метрика не улучшается, происходит останов (подробнее писал здесь). В методе fit для раннего останова передадим валидационный датасет (параметр eval_set) и метрику (eval_metric, список здесь). При этом в последнем может задаваться список метрик, которые будут отслеживаться на валидационном датасете и использоваться для останова (выбор итерации будет происходит с учетом их всех либо первой, если при создании модели указать first_metric_only=True). Также для приглушения вывода значений метрики по умолчанию можно в конструктор класса указать metric='None':
from lightgbm import LGBMClassifier clf = LGBMClassifier(n_estimators=1000, early_stopping_rounds=80, first_metric_only=True, metric='None') clf.fit(X_tr, y_tr, eval_set=(X_val, y_val), eval_metric=['auc', 'cross_entropy'], categorical_feature=['feat4']) y_p = reg.predict(X_ts)
Как можно заметить, алгоритм выбирает 6 итерацию в качестве оптимальной. Однако, несмотря на то, что при выводе параметров классификатора количество количество деревьев в "обрезанном" лесу не указывается, в реальности используется лучшая итерация:
clf.get_params()
метрика roc_auc, соответствует лучшей:
В свойствах best_score_ и evals_result_ хранятся лучший результат обученной модели и история оценок на валидационном датасете:
clf.best_score_
clf.evals_result_
Также отмечу, что в параметр categorical_feature метода fit можно передать список категориальных признаков (по умолчанию 'auto' - для pandas датафрейма извлекаются признаки с категориальным типом). Чтобы признаки расценивались как категориальные, их надо преобразовать в этот тип (набрать что-то вроде df.astype({it:'category' for it in cat_cols}) )
Подробнее о параметрах можно узнать здесь.
Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях: