Алгоритм XGBoost получил известность в области прикладного машинного обучения. Из-за его быстрой скорости выполнения и производительности модели он предпочтительнее других машин повышения градиента (GBM). Его можно использовать с Java, C++, R, Julia, Python, командной строкой, Scala и другими языками JVM.

Во время обучения XGBoost использует параллельные вычисления для построения деревьев на всех процессорах. Параметр «максимальная глубина» используется вместо обычных критериев остановки (т. е. сначала критерий), а обрезка дерева начинается в обратном направлении. Это значительно повышает вычислительную эффективность и скорость XGBoost по сравнению с конкурирующими платформами GBM. Затем он может автоматически определить оптимальное недостающее значение на основе потерь при обучении, что позволяет лучше обрабатывать различные шаблоны разреженности во входных данных. В одном исследовании проверялась производительность алгоритма XGBoost по сравнению с другими алгоритмами машинного обучения, включая случайный лес, логистическую регрессию, классическое повышение градиента и другие, и было обнаружено, что XGBoost является наиболее эффективным методом в целом. Давайте рассмотрим несколько примеров запуска XGBoost на наборе данных об оттоке. Наша цель — спрогнозировать, будут ли пользователи приложения продолжать пользоваться сервисом через 5 месяцев, используя данные за первый месяц. Типичная установка для задачи прогнозирования оттока показана здесь. Это будет достигнуто путем разделения данных на обучающие и тестовые наборы, установки крошечной модели xgboost на обучающем наборе и оценки производительности модели на тестовом наборе путем определения ее точности.

# Create arrays for the features and the target: X, y
X, y = churn_data.iloc[:,:-1], churn_data.iloc[:,-1]
# Create the training and test sets
X_train, X_test, y_train, y_test= train_test_split(X, y, test_size=0.2, random_state=123)
# Instantiate the XGBClassifier: xg_cl
xg_cl = xgb.XGBClassifier(objective='binary:logistic', n_estimators=10, seed=123)
# Fit the classifier to the training set
xg_cl.fit(X_train,y_train)
# Predict the labels of the test set: preds
preds = xg_cl.predict(X_test)
# Compute the accuracy: accuracy
accuracy = float(np.sum(preds==y_test))/y_test.shape[0]
print("accuracy: %f" % (accuracy))
accuracy: 0.743300

XGBoost обычно используется с деревьями в качестве базовых обучающих программ. Базовым учащимся может быть любой отдельный алгоритм обучения в ансамблевом алгоритме. Это важно, поскольку сам XGBoost использует выходные данные многочисленных моделей для получения окончательного прогноза, который представляет собой метод ансамблевого обучения. Используя граф, напоминающий дерево, дерево решений представляет собой метод обучения, который имитирует непрерывный или категорический выбор на основе входных данных. Он состоит из серии вопросов «да-или-нет» или «верно-ложно», ответы на которые по порядку дают предсказание о текущих фактах (эти предсказания происходят на листьях дерева). Деревья решений строятся итеративно (то есть одно двоичное решение за раз) до тех пор, пока не будет удовлетворен критерий остановки (например, глубина дерева не достигнет некоторого заранее определенного максимального значения). Дерево строится по одному расщеплению за раз. Метод выбора разделения (т. е., на какой признак и где в диапазоне значений признака должен быть разделен) может варьироваться, но он всегда влечет за собой выбор точки разделения, которая более эффективно разделяет целевые значения (делит каждую целевую категорию на сегменты). в которых все больше доминирует только одна категория) до тех пор, пока все ценности в данном разделении не будут принадлежать исключительно той или иной категории.

Повышение — это метод, который можно использовать с различными моделями машинного обучения, а не с одним алгоритмом машинного обучения. На самом деле это мета-алгоритм. Это особый метаалгоритм ансамбля, который в основном используется для уменьшения дисперсии любого отдельного ученика и преобразования большого количества слабых учеников в одного произвольно сильного ученика. Мы можем посмотреть на возможности перекрестной проверки XGBoost данных об оттоке.

# Create arrays for the features and the target: X, y
X, y = churn_data.iloc[:,:-1], churn_data.iloc[:,-1]
# Create the DMatrix from X and y: churn_dmatrix
churn_dmatrix = xgb.DMatrix(data=X, label=y)
# Create the parameter dictionary: params
params = {"objective":"reg:logistic", "max_depth":3}
# Perform cross-validation: cv_results
cv_results = xgb.cv(dtrain=churn_dmatrix, params=params, 
                  nfold=3, num_boost_round=5, 
                  metrics="error", as_pandas=True, seed=123)
# Print cv_results
print(cv_results)
# Print the accuracy
print(((1-cv_results["test-error-mean"]).iloc[-1]))
train-error-mean  train-error-std  test-error-mean  test-error-std
0          0.28232         0.002366          0.28378        0.001932
1          0.26951         0.001855          0.27190        0.001932
2          0.25605         0.003213          0.25798        0.003963
3          0.25090         0.001845          0.25434        0.003827
4          0.24654         0.001981          0.24852        0.000934
0.75148

После перекрестной проверки для вычисления средней точности AUC (после преобразования ошибки) очень легко вычислить любую другую метрику, которая может нас заинтересовать, например AUC.

# Perform cross_validation: cv_results
cv_results = xgb.cv(dtrain=churn_dmatrix, params=params, 
                  nfold=3, num_boost_round=5, 
                  metrics="auc", as_pandas=True, seed=123)
# Print cv_results
print(cv_results)
# Print the AUC
print((cv_results["test-auc-mean"]).iloc[-1])
train-auc-mean  train-auc-std  test-auc-mean  test-auc-std
0        0.768893       0.001544       0.767863      0.002820
1        0.790864       0.006758       0.789157      0.006846
2        0.815872       0.003900       0.814476      0.005997
3        0.822959       0.002018       0.821682      0.003912
4        0.827528       0.000769       0.826191      0.001937
0.826191

AUC 0,82 довольно сильный. Как мы видели, API обучения XGBoost позволяет очень легко вычислить любую метрику.

Когда использовать XGBoost?

Любая задача машинного обучения с учителем, которая удовлетворяет следующему требованию — у нас есть большое количество обучающих примеров; следует учитывать для XGBoost. Большой набор данных — это набор данных с небольшим количеством атрибутов и не менее 1000 образцов. Однако, вообще говоря, мы должны быть в безопасности, пока количество функций в нашем обучающем наборе меньше, чем количество экземпляров, которые у нас есть. XGBoost обычно работает хорошо, когда у нас есть и категории, и числовые функции, или когда у нас есть только числовые функции.

Когда не использовать XGBoost?

Наиболее важные типы проблем, для которых XGBoost является неоптимальным решением, — это либо те, которые были успешно решены с использованием других передовых алгоритмов, либо проблемы с размером набора данных. В частности, XGBoost не очень хорошо подходит для задач распознавания изображений, компьютерного зрения или обработки и понимания естественного языка, поскольку алгоритмы глубокого обучения значительно эффективнее решают эти типы проблем. Если у нас очень маленькие обучающие наборы (менее 100 обучающих экземпляров) или если количество обучающих примеров намного меньше, чем количество функций, используемых для обучения, XGBoost не рекомендуется. Давайте попробуем построить модель XGBoost для прогнозирования цен на жилье в Бостоне, штат Массачусетс. Данные уже импортированы как df и разделены на X и y как функцию и метку.

# Create the training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
# Instantiate the XGBRegressor: xg_reg
xg_reg = xgb.XGBRegressor(objective= 'reg:linear',n_estimators=10,seed =123)
# Fit the regressor to the training set
xg_reg.fit(X_train,y_train)
# Predict the labels of the test set: preds
preds = xg_reg.predict(X_test)
# Compute the rmse: rmse
rmse = np.sqrt(mean_squared_error(y_test, preds))
print("RMSE: %f" % (rmse))
RMSE: 78847.401758

Теперь мы можем обучать модель XGBoost, используя линейные базовые обучающие программы и API обучения XGBoost.

# Convert the training and testing sets into DMatrixes: DM_train, DM_test
DM_train = xgb.DMatrix(data=X_train,label=y_train)
DM_test =  xgb.DMatrix(data=X_test,label=y_test)
# Create the parameter dictionary: params
params = {"booster":"gblinear", "objective":"reg:linear"}
# Train the model: xg_reg
xg_reg = xgb.train(params = params, dtrain=DM_train, num_boost_round=5)
# Predict the labels of the test set: preds
preds = xg_reg.predict(DM_test)
# Compute and print the RMSE
rmse = np.sqrt(mean_squared_error(y_test,preds))
print("RMSE: %f" % (rmse))
RMSE: 41983.953755

Похоже, что ученики с линейной базой показали лучшие результаты. Теперь мы сравним RMSE и MAE перекрестной проверки модели XGBoost на данных о жилье Эймса.

# Create the DMatrix: housing_dmatrix
housing_dmatrix = xgb.DMatrix(data=X, label=y)
# Create the parameter dictionary: params
params = {"objective":"reg:linear", "max_depth":4}
# Perform cross-validation: cv_results
cv_results = xgb.cv(dtrain=housing_dmatrix, params=params, nfold=4, num_boost_round=5, metrics="rmse", as_pandas=True, seed=123)
# Print cv_results
print(cv_results)
# Extract and print final boosting round metric
print((cv_results["test-rmse-mean"]).tail(1))
train-rmse-mean  train-rmse-std  test-rmse-mean  test-rmse-std
0    141767.531250      429.454591   142980.429688    1193.794436
1    102832.542969      322.473304   104891.394532    1223.158855
2     75872.617187      266.469946    79478.935547    1601.344218
3     57245.649414      273.626175    62411.921875    2220.149857
4     44401.298828      316.423666    51348.279297    2963.377719
4    51348.279297
Name: test-rmse-mean, dtype: float64
# Create the DMatrix: housing_dmatrix
housing_dmatrix = xgb.DMatrix(data=X, label=y)
# Create the parameter dictionary: params
params = {"objective":"reg:linear", "max_depth":4}
# Perform cross-validation: cv_results
cv_results = xgb.cv(dtrain=housing_dmatrix, params=params, nfold=4, num_boost_round=5, metrics='mae', as_pandas=True, seed=123)
# Print cv_results
print(cv_results)
# Extract and print final boosting round metric
print((cv_results["test-mae-mean"]).tail(1))
train-mae-mean  train-mae-std  test-mae-mean  test-mae-std
0   127343.484375     668.343954  127633.972656   2404.007282
1    89770.052734     456.959831   90122.500000   2107.913315
2    63580.790039     263.409758   64278.563477   1887.565119
3    45633.154297     151.886059   46819.168945   1459.817731
4    33587.094727      86.997933   35670.646485   1140.607463
4    35670.646485
Name: test-mae-mean, dtype: float64

В XGBoost функции потерь дополнительно учитывают сложность модели в дополнение к тому, насколько точно прогнозы модели соответствуют фактическим значениям.

Регуляризация относится к концепции наказания моделей по мере их усложнения. В результате модели, которые являются точными и настолько простыми, насколько это возможно, могут быть найдены с использованием функций потерь в XGBoost. В XGBoost можно изменить ряд параметров, чтобы уменьшить сложность модели, изменив функцию потерь. Для обучающихся на основе дерева параметр гаммы определяет, будет ли конкретный узел разделяться на основе ожидаемого уменьшения потерь, которые последуют за разделением, причем большие значения приводят к меньшему количеству разделений. Более сильная регуляризация L1 вызвана более высокими значениями альфа, что приводит к тому, что многие веса листьев в базовых обучающихся становятся равными нулю. Другое название регуляризации l2 — лямбда. Вместо того, чтобы устанавливать строгие ограничения разреженности на веса листьев, как в l1, регуляризация L2 имеет значительно более плавный штраф и заставляет веса листьев постепенно уменьшаться.

# Create the DMatrix: housing_dmatrix
housing_dmatrix = xgb.DMatrix(data=X, label=y)
reg_params = [1, 10, 100]
# Create the initial parameter dictionary for varying l2 strength: params
params = {"objective":"reg:linear","max_depth":3}
# Create an empty list for storing rmses as a function of l2 complexity
rmses_l2 = []
# Iterate over reg_params
for reg in reg_params:
# Update l2 strength
    params["lambda"] =reg
    
    # Pass this updated param dictionary into cv
    cv_results_rmse = xgb.cv(dtrain=housing_dmatrix, params=params, nfold=2, num_boost_round=5, metrics="rmse", as_pandas=True, seed=123)
    
    # Append best rmse (final round) to rmses_l2
    rmses_l2.append(cv_results_rmse["test-rmse-mean"].tail(1).values[0])
# Look at best rmse per l2 param
print("Best rmse as a function of l2:")
print(pd.DataFrame(list(zip(reg_params, rmses_l2)), columns=["l2", "rmse"]))
   
Best rmse as a function of l2:
        l2          rmse
    0    1  52275.359375
    1   10  57746.064453
    2  100  76624.625000

Похоже, что значение 'lambda' увеличивается, как и RMSE. Мы построили и оценили модели классификации и регрессии, используя XGBoost; мы должны иметь возможность визуально исследовать ваши модели. Теперь мы визуализируем полностью усиленную модель, которую генерирует XGBoost, используя весь набор данных о жилье в виде отдельных деревьев.

# Create the DMatrix: housing_dmatrix
housing_dmatrix = xgb.DMatrix(data=X, label=y)
# Create the parameter dictionary: params
params = {"objective":"reg:linear", "max_depth":2}
# Train the model: xg_reg
xg_reg = xgb.train(params=params, dtrain=housing_dmatrix, num_boost_round=10)
# Plot the first tree
xgb.plot_tree(xg_reg,num_trees=0)
plt.show()
# Plot the fifth tree
xgb.plot_tree(xg_reg,num_trees=4)
plt.show()
# Plot the last tree sideways
xgb.plot_tree(xg_reg,num_trees=9,rankdir="LR")
plt.show()

Мы пролили свет на расхождения, которые модель использовала для своих окончательных суждений, а также на то, как она пришла к этим решениям. Это позволяет нам определить, какие характеристики имеют решающее значение при определении цены дома. Изучение относительных весов каждого столбца признаков в исходном наборе данных в модели — еще один подход к визуализации наших моделей XGBoost.

# Create the DMatrix: housing_dmatrix
housing_dmatrix = xgb.DMatrix(data=X, label=y)
# Create the parameter dictionary: params
params = {"objective":"reg:linear", "max_depth":4}
# Train the model: xg_reg
xg_reg = xgb.train(params=params, dtrain=housing_dmatrix, num_boost_round=10)
# Plot the feature importances
xgb.plot_importance(xg_reg)
plt.show()

Таким образом, мы увидели из этого примера, что GrLivArea является самой важной функцией. Таким образом, эту функцию XGboost можно использовать для разработки функций.