питон
Познакомьтесь с HistGradientBoostingClassifier
Более гибкий и масштабируемый GradientBoostingClassifier
GradientBoostingClassifier от Scikit-learn (далее GBM) — один из самых популярных ансамблевых алгоритмов, который хорошо работает со многими наборами данных. HistGradientBoostingClassifier (далее HGBM), основанная на гистограмме альтернативная реализация GBM, была представлена в v0.21.0 в качестве экспериментальной оценки. Начиная с v1.0.0, этот оценщик стал стабильным оценщиком. В этом посте мы рассмотрим два основных преимущества использования HGBM по сравнению с GBM.
Существует также эквивалент регрессии: HistGradientBoostingRegressor. Однако мы не будем освещать его, чтобы избежать повторения, поскольку применяется та же логика.
📦 1. Обрабатывает отсутствующие данные
Этот оценщик может работать с отсутствующими данными, поскольку он имеет встроенную поддержку отсутствующих значений. Давайте посмотрим на это в действии. Мы начнем с импорта библиотек и создания примера данных с отсутствующими значениями:
import numpy as np import pandas as pd from time import perf_counter pd.options.display.max_columns = 6 from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.ensemble import (GradientBoostingClassifier, HistGradientBoostingClassifier) from sklearn.metrics import accuracy_score, roc_auc_score, f1_score import matplotlib.pyplot as plt import seaborn as sns sns.set(style='darkgrid', context='talk', palette='rainbow') n = 10**4 X, y = make_classification(n, random_state=42) X = pd.DataFrame(X, columns=[f'feature{i}' for i in range(X.shape[1])]) # Randomly add missing data for all columns for i, col in enumerate(X.columns): np.random.seed(i) X.loc[np.random.choice(range(n), 1000, replace=False), col] = np.nan print(f"Target shape: {y.shape}") print(f"Features shape: {X.shape}") X.head()
Теперь мы разделим данные и попробуем подобрать GBM:
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) print("========== Training data ========== ") print(f"Features: {X_train.shape} | Target:{y_train.shape}") print("========== Test data ========== ") print(f"Features: {X_test.shape} | Target:{y_test.shape}") gbm = GradientBoostingClassifier(random_state=42) gbm.fit(X_train, y_train) gbm.score(X_test, y_test)
Как и в большинстве средств оценки Scikit-learn, попытка подогнать модель под данные с отсутствующими значениями вызовет ValueError: Input contains NaN, infinity or a value too large for dtype('float32')
.
Теперь давайте посмотрим, что произойдет, если мы используем HGBM:
hgbm = HistGradientBoostingClassifier(random_state=42) hgbm.fit(X_train, y_train) hgbm.score(X_test, y_test)
Удивительно, это работает отлично, так как оценщик может изначально обрабатывать недостающие данные. Это одно из преимуществ, которое HGBM предлагает по сравнению с GBM.
📊 2. Хорошо масштабируется с большими данными
HGBM является более быстрой реализацией GBM и хорошо масштабируется с большими наборами данных. Давайте посмотрим, как обе оценки сравниваются на выборочных данных с разными размерами:
n_samples = 10**np.arange(2,7) tuples = [*zip(np.repeat(n_samples,2), np.tile(['gbm', 'hgbm'], 2))] summary = pd.DataFrame( index=pd.MultiIndex.from_tuples(tuples, names=["n_records", "model"]) ) models = [('gbm', GradientBoostingClassifier(random_state=42)), ('hgbm', HistGradientBoostingClassifier(random_state=42))] for n in n_samples: X, y = make_classification(n, random_state=42) X_train, X_test, y_train, y_test = train_test_split( X, y, random_state=42 ) for name, model in models: start = perf_counter() model.fit(X_train, y_train) end = perf_counter() summary.loc[(n, name), 'fit_time'] = end-start start = perf_counter() y_proba = model.predict_proba(X_test)[:,1] end = perf_counter() summary.loc[(n, name), 'score_time'] = end-start summary.loc[(n, name), 'roc_auc'] = roc_auc_score(y_test, y_proba) y_pred = np.round(y_proba) summary.loc[(n, name), 'accuracy'] = accuracy_score(y_test, y_pred) summary.loc[(n, name), 'f1'] = f1_score(y_test, y_pred) summary
Здесь 75% всех записей используются для обучения, а оставшиеся 25% записей используются для тестирования. Мы видим, что время обучения намного быстрее с HGBM по мере роста данных обучения. Чем больше данных, тем более впечатляющая скорость HGBM. HGBM достигает своей удивительной скорости за счет огрубления данных в бинарные функции. Давайте посмотрим на резюме немного внимательнее:
fig, ax = plt.subplots(2, 1, figsize=(9,6), sharex=True) sns.lineplot(data=summary['fit_time'].reset_index(), x='n_records', y='fit_time', hue='model', ax=ax[0]) ax[0].legend(loc='upper right', bbox_to_anchor=(1.3, 1)) sns.lineplot(data=summary['score_time'].reset_index(), x='n_records', y='score_time', hue='model', legend=False, ax=ax[1]) ax[1].set_xscale('log') fig.tight_layout();
Время обучения значительно увеличивается с GBM по мере увеличения количества обучающих примеров, тогда как с HGBM оно по-прежнему относительно быстрое на больших наборах данных. Время подсчета очков довольно близко между ними.
fig, ax = plt.subplots(3, 1, figsize=(9,9), sharex=True) sns.lineplot(data=summary['roc_auc'].reset_index(), x='n_records', y='roc_auc', hue='model', ax=ax[0]) ax[0].legend(loc='upper right', bbox_to_anchor=(1.3, 1)) sns.lineplot(data=summary['accuracy'].reset_index(), x='n_records', y='accuracy', hue='model', legend=False, ax=ax[1]) sns.lineplot(data=summary['f1'].reset_index(), x='n_records', y='f1', hue='model', legend=False, ax=ax[2]) ax[2].set_xscale('log') fig.tight_layout();
В целом, прогностическая эффективность между ними очень похожа, хотя есть небольшая разница, когда обучающие данные меньше на 75 и 750.
Как вы уже заметили, второе преимущество HGBM заключается в том, что он очень хорошо масштабируется с большими наборами данных по сравнению с GBM.
Вот и все! Надеюсь, вам понравилось знакомство с этим гибким и масштабируемым оценщиком, и вы с нетерпением ждете его дальнейшего изучения. Если вы хотите узнать больше, HGBM также имеет встроенную поддержку категориальных функций. Эта документация показывает несколько отличных примеров использования этой функции.
Хотели бы вы получить доступ к большему содержанию, подобному этому? Участники Medium получают неограниченный доступ к любым статьям на Medium. Если вы станете участником, используя мою реферальную ссылку, часть вашего членского взноса пойдет непосредственно на мою поддержку.
Спасибо, что прочитали эту статью. Если интересно, вот ссылки на некоторые другие мои посты:
◼️️ От модели ML к ML Pipeline
◼️️ Объяснение моделей Scikit-learn с помощью SHAP
◼️️ 4 простых совета по построению нескольких графиков в Python
◼️ Приведение в порядок фреймов данных pandas
◼ Простые способы визуализации данных в Python, которые вам пригодятся️
◼️ 6 простых советов, как сделать красивее и индивидуальные графики в Seaborn (Python)
Пока пока 🏃 💨