Алгоритм 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 можно использовать для разработки функций.