Производительность библиотеки XGBoost в Python

Библиотека XGBoost (eXtreme Gradient Boosting) стала одним из самых популярных инструментов в машинном обучении, поскольку это один из методов-победителей в соревнованиях Kaggle и лучший метод для решения крупномасштабных задач.

Если вы новичок в этой библиотеке, вы, возможно, уже поняли, что можете использовать общий синтаксис sklearn или вы можете использовать основной API xgboost с dmatrices. Но подождите, что такое DMatrix?

DMatrix — это просто внутренняя структура данных, которую XGBoost использует для оптимизации эффективности использования памяти и скорости обучения.

Это одна из ключевых особенностей библиотеки, так как она делает ее намного быстрее.

В этой статье я хочу показать вам, насколько он эффективен по сравнению с обычным синтаксисом sklearn и почему стоит изменить свой код на основной API, а не оставить его как более известный.

XGBoost — замечательная библиотека для крупномасштабных наборов данных. Однако здесь, в примере, и только для его анализа, мы собираемся использовать небольшой набор данных, предоставленный sklearn `load_breast_cancer` всего с 569 экземплярами.

data = load_breast_cancer(as_frame=True)
df_features = pd.DataFrame(data.data, columns=data.feature_names)
df_target = pd.DataFrame(data.target, columns=[‘target’])

Начиная с версии 0.23 в sklearn вы можете использовать as_frame=True.

Метод XGBoost XGBClassifier

def test_sklearn_api(X_train, X_test, y_train, y_test):
    xgb_cls = xgb.XGBClassifier(objective ='binary:logistic', n_jobs=-1)
    xgb_cls.fit(X_train,y_train)
    y_pred = xgb_cls.predict(X_test)
start_time = time()
test_sklearn_api(X_train, X_test, y_train, y_test)
print(f"The time of training and predict is {time() - start_time}")

› Время обучения и прогнозирования составляет 0,06125473976135254 секунды.

start_time = time()
def test_core_api(X_train, X_test, y_train, y_test):
    d_train = xgb.DMatrix(X_train, label=y_train)
    d_test = xgb.DMatrix(X_test, label=y_test)
    xgb_core_api = xgb.train(params={'objective':'binary:logistic'},
                             dtrain=d_train,
                             verbose_eval=False)
    y_pred = xgb_core_api.predict(d_test)
start_time = time()
test_core_api(X_train, X_test, y_train, y_test)
print(f"The time of training and predict is {time() - start_time}")

› Время обучения и прогнозирования составляет 0,02025914192199707 секунд.

Только с этим небольшим набором данных, состоящим всего из 569 экземпляров, мы можем увидеть разницу на 4 секунды больше при использовании XGBClassifier и метода fit как sklearn, чем при использовании DMatrix и метод train. Представьте разницу в большем масштабе!

Но давайте замерим время, чтобы посмотреть, как это будет вести себя с несколькими циклами одной и той же функции:

%timeit test_sklearn_api(X_train, X_test, y_train, y_test)

› 52,2 мс ± 1,07 мс на цикл (среднее значение ± стандартное отклонение для 7 запусков, по 10 циклов в каждом)

%timeit test_core_api(X_train, X_test, y_train, y_test)

›13,1 мс ± 79,1 мкс на цикл (среднее значение ± стандартное отклонение для 7 запусков по 100 циклов в каждом)

Как мы снова видим, основной API xgboost намного эффективнее, чем sklearn!

Я действительно советую вам подумать об этом, чтобы оптимизировать свой производственный код!

Но другой вопрос: одинаковая ли у них эффективность с показателями оценки?

Мы будем отображать отчет о классификации для каждого случая:

# Using XGBClassifier and .fit
classification_report(y_test, y_pred)

# Using DMatrix and .train
classification_report(y_test, y_pred>0.5)

Показатели немного хуже, чем при использовании XGBClassifier, как по точности, так и по точности.

Резюме

Итак, какой же тогда лучше? Это, очевидно, будет зависеть от вашей цели. Вам нужна более высокая скорость производства и вам нужно немного пожертвовать производительностью? или вам нужна высочайшая точность?

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