2016-12-14 9 views
1

Я пытаюсь сделать классификатор в наборе данных. Я впервые использовал XGBoost:Почему xgboost.cv и sklearn.cross_val_score дают разные результаты?

import xgboost as xgb 
import pandas as pd 
import numpy as np 

train = pd.read_csv("train_users_processed_onehot.csv") 
labels = train["Buy"].map({"Y":1, "N":0}) 

features = train.drop("Buy", axis=1) 
data_dmat = xgb.DMatrix(data=features, label=labels) 

params={"max_depth":5, "min_child_weight":2, "eta": 0.1, "subsamples":0.9, "colsample_bytree":0.8, "objective" : "binary:logistic", "eval_metric": "logloss"} 
rounds = 180 

result = xgb.cv(params=params, dtrain=data_dmat, num_boost_round=rounds, early_stopping_rounds=50, as_pandas=True, seed=23333) 
print result 

И результат:

 test-logloss-mean test-logloss-std train-logloss-mean 
0    0.683539   0.000141   0.683407 
179   0.622302   0.001504   0.606452 

Мы можем видеть это составляет около 0,622;

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

from sklearn.model_selection import cross_val_score 
from xgboost.sklearn import XGBClassifier 
import pandas as pd 

train_dataframe = pd.read_csv("train_users_processed_onehot.csv") 
train_labels = train_dataframe["Buy"].map({"Y":1, "N":0}) 
train_features = train_dataframe.drop("Buy", axis=1) 

estimator = XGBClassifier(learning_rate=0.1, n_estimators=190, max_depth=5, min_child_weight=2, objective="binary:logistic", subsample=0.9, colsample_bytree=0.8, seed=23333) 
print cross_val_score(estimator, X=train_features, y=train_labels, scoring="neg_log_loss") 

и результат: [-4.11429976 -2.08675843 -3.27346662], после реверсирования она все еще далека от 0,622.

Я бросил точку разрыва в cross_val_score и увидел, что классификатор делает сумасшедшие предсказания, пытаясь предсказать, что каждый кортеж в тестовом наборе будет отрицательным с вероятностью около 0,99.

Мне интересно, где я ошибся. Может кто-нибудь мне помочь?

ответ

2

Этот вопрос немного устарел, но сегодня я столкнулся с проблемой и выяснил, почему результаты, полученные xgboost.cv и sklearn.model_selection.cross_val_score, совершенно разные.

По умолчанию cross_val_score использует KFold или StratifiedKFold, чей аргумент тасования False, поэтому складки не извлекаются случайным образом из данных.

Так что, если вы это сделаете, то вы должны получить те же результаты,

cross_val_score(estimator, X=train_features, y=train_labels, scoring="neg_log_loss", cv = StratifiedKFold(shuffle=True, random_state=23333)) 

Держите random state в StratifiedKfold и seed в xgboost.cv же, чтобы получить точно воспроизводимые результаты.