Использование Hyper-параметров из H2O для перекомпоновки XGBoost в Sklearn дает разницу производительности в Python - PullRequest
8 голосов
/ 17 июня 2019

После использования модуля Python H2O AutoML обнаруживается, что XGBoost находится в верхней части таблицы лидеров. Затем я попытался извлечь гиперпараметры из H2O XGBoost и скопировать в XGBoost Sklearn API. Однако производительность этих двух подходов различна:


from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_predict
from sklearn.metrics import classification_report

import xgboost as xgb
import scikitplot as skplt
import h2o
from h2o.automl import H2OAutoML
import numpy as np
import pandas as pd

h2o.init()


iris = datasets.load_iris()
X = iris.data
y = iris.target

data = pd.DataFrame(np.concatenate([X, y[:,None]], axis=1)) 
data.columns = iris.feature_names + ['target']
data = data.sample(frac=1)
# data.shape

train_df = data[:120]
test_df = data[120:]

# Import a sample binary outcome train/test set into H2O
train = h2o.H2OFrame(train_df)
test = h2o.H2OFrame(test_df)

# Identify predictors and response
x = train.columns
y = "target"
x.remove(y)

# For binary classification, response should be a factor
train[y] = train[y].asfactor()
test[y] = test[y].asfactor()

aml = H2OAutoML(max_models=10, seed=1, nfolds = 3,
                keep_cross_validation_predictions=True,
                exclude_algos = ["GLM", "DeepLearning", "DRF", "GBM"])
aml.train(x=x, y=y, training_frame=train)
# View the AutoML Leaderboard
lb = aml.leaderboard
lb.head(rows=lb.nrows)

model_ids = list(aml.leaderboard['model_id'].as_data_frame().iloc[:,0])
m = h2o.get_model([mid for mid in model_ids if "XGBoost" in mid][0])
# m.params.keys()
  1. Производительность H2O Xgboost
skplt.metrics.plot_confusion_matrix(test_df['target'], 
                                    m.predict(test).as_data_frame()['predict'], 
                                    normalize=False)

enter image description here

  1. Репликация в XGBoost Sklearn API:
mapping_dict = {
        "booster": "booster",
        "colsample_bylevel": "col_sample_rate",
        "colsample_bytree": "col_sample_rate_per_tree",
        "gamma": "min_split_improvement",
        "learning_rate": "learn_rate",
        "max_delta_step": "max_delta_step",
        "max_depth": "max_depth",
        "min_child_weight": "min_rows",
        "n_estimators": "ntrees",
        "nthread": "nthread",
        "reg_alpha": "reg_alpha",
        "reg_lambda": "reg_lambda",
        "subsample": "sample_rate",
        "seed": "seed",

        # "max_delta_step": "score_tree_interval",
        #  'missing': None,
        #  'objective': 'binary:logistic',
        #  'scale_pos_weight': 1,
        #  'silent': 1,
        #  'base_score': 0.5,
}

parameter_from_water = {}
for item in mapping_dict.items():
    parameter_from_water[item[0]] = m.params[item[1]]['actual']
# parameter_from_water

xgb_clf = xgb.XGBClassifier(**parameter_from_water)
xgb_clf.fit(train_df.drop('target', axis=1), train_df['target'])
  1. Производительность Sklearn XGBoost:
    (всегда хуже, чем H2O во всех примерах, которые я пробовал.)
skplt.metrics.plot_confusion_matrix(test_df['target'], 
                                    xgb_clf.predict(test_df.drop('target', axis=1)  ), 
                                    normalize=False);

enter image description here

Что-нибудь очевидное, что я пропустил?

1 Ответ

5 голосов
/ 20 июня 2019

Когда вы используете H2O auto ml со следующими строками кода:

aml = H2OAutoML(max_models=10, seed=1, nfolds = 3,
                keep_cross_validation_predictions=True,
                exclude_algos = ["GLM", "DeepLearning", "DRF", "GBM"])
aml.train(x=x, y=y, training_frame=train)

Вы используете опцию nfolds = 3, что означает, что каждый алгоритм будет обучен три раза, используя 2/3 данных в качестве обучения и одну треть в качестве проверки. Это позволяет алгоритму быть более стабильным и иногда иметь лучшую производительность, чем если бы вы давали весь свой тренировочный набор данных за один раз.

Это то, что вы делаете, когда тренируете свой XGBoost, используя fit(). Даже если у вас есть такой же алгоритм (XGBoost) с такими же гиперпараметрами , вы не используете обучающий набор так же, как H2O. Отсюда и разница в ваших путаницах!

Если вы хотите иметь ту же производительность при копировании лучшей модели, вы можете изменить параметр H2OAutoML(..., nfolds = 0)


Кроме того, там, где H2O учитывает приблизительно 60 различных параметров, вы пропустили несколько важных в своем словаре, например, min_child_weight. Так что ваш xgboost не совсем совпадает с вашим H2O, что может объяснить разницу в производительности

...