2017-05-12 6 views
1

J'essaie d'obtenir les meilleurs hyperparamètres pour XGBClassifier qui conduiraient à obtenir la plupart des attributs prédictifs. J'essaye d'employer RandomizedSearchCV pour itérer et valider par KFold. Comme j'exécute ce processus au total 5 fois (numFolds = 5), je veux que les meilleurs résultats soient sauvegardés dans une base de données appelée collector (spécifiée ci-dessous). Donc, à chaque itération, je voudrais que les meilleurs résultats et les scores soient ajoutés à la base de données du collecteur.Optimisation de l'hyperparamètre Python pour XGBClassifier utilisant RandomizedSearchCV

from scipy import stats 
from scipy.stats import randint 
from sklearn.model_selection import RandomizedSearchCV 
from sklearn.metrics import 
precision_score,recall_score,accuracy_score,f1_score,roc_auc_score 

clf_xgb = xgb.XGBClassifier(objective = 'binary:logistic') 
param_dist = {'n_estimators': stats.randint(150, 1000), 
       'learning_rate': stats.uniform(0.01, 0.6), 
       'subsample': stats.uniform(0.3, 0.9), 
       'max_depth': [3, 4, 5, 6, 7, 8, 9], 
       'colsample_bytree': stats.uniform(0.5, 0.9), 
       'min_child_weight': [1, 2, 3, 4] 
      } 
clf = RandomizedSearchCV(clf_xgb, param_distributions = param_dist, n_iter = 25, scoring = 'roc_auc', error_score = 0, verbose = 3, n_jobs = -1) 

numFolds = 5 
folds = cross_validation.KFold(n = len(X), shuffle = True, n_folds = numFolds) 

collector = pd.DataFrame() 
estimators = [] 
results = np.zeros(len(X)) 
score = 0.0 

for train_index, test_index in folds: 
    X_train, X_test = X[train_index], X[test_index] 
    y_train, y_test = y[train_index], y[test_index] 
    clf.fit(X_train, y_train) 
    estimators.append(clf.best_estimator_) 
    estcoll = pd.DataFrame(estimators) 


    estcoll['score'] = score 
    pd.concat([collector,estcoll]) 
    print "\n", len(collector), "\n" 
score /= numFolds 

Pour une raison quelconque, il n'y a rien d'enregistré dans l'image, merci de nous aider.

En outre, j'ai environ 350 attributs à parcourir avec 3.5K lignes en train et 2K en test. Est-ce que l'exécution de ce processus d'optimisation hyperparamétrique bayésienne pourrait améliorer mes résultats? ou ce serait seulement économiser sur le temps de traitement?

Répondre

2

RandomizedSearchCV() fera plus pour vous que vous ne le pensez. Explorez l'attribut cv_results de votre objet CV ajusté at the documentation page

Voici votre code à peu près inchangé. Les deux changements que j'ajouté:

  1. j'ai changé n_iter=5 de 25. Cela va faire 5 séries de paramètres, avec votre 5 fois signifie validation croisée 25 crises au total.
  2. J'ai défini votre objet kfold avant RandomizedSearchCV, puis référencé dans la consruction de RandomizedSearchCV comme cv
param

_

clf_xgb = xgb.XGBClassifier(objective = 'binary:logistic') 
param_dist = {'n_estimators': stats.randint(150, 1000), 
       'learning_rate': stats.uniform(0.01, 0.6), 
       'subsample': stats.uniform(0.3, 0.9), 
       'max_depth': [3, 4, 5, 6, 7, 8, 9], 
       'colsample_bytree': stats.uniform(0.5, 0.9), 
       'min_child_weight': [1, 2, 3, 4] 
      } 

numFolds = 5 
kfold_5 = cross_validation.KFold(n = len(X), shuffle = True, n_folds = numFolds) 

clf = RandomizedSearchCV(clf_xgb, 
         param_distributions = param_dist, 
         cv = kfold_5, 
         n_iter = 5, # you want 5 here not 25 if I understand you correctly 
         scoring = 'roc_auc', 
         error_score = 0, 
         verbose = 3, 
         n_jobs = -1) 

est ici où ma réponse dévie de votre code de manière significative. Il suffit de monter l'objet randomizedsearchcv une fois, pas besoin de faire une boucle. Il gère la boucle de CV avec son argument cv.

clf.fit(X_train, y_train) 

Tous les résultats de la Croix-valdated sont maintenant en clf.cv_results_. Par exemple, vous pouvez obtenir un score de train avec validation croisée (moyenne sur 5 fois) avec: clf.cv_results_['mean_train_score'] ou un score de test croisé validé (données bloquées) avec clf.cv_results_['mean_test_score']. Vous pouvez également obtenir d'autres choses utiles comme mean_fit_time, params, et clf, une fois monté, se souviendra automatiquement de votre best_estimator_ comme attribut.

Ce sont les éléments pertinents pour déterminer le meilleur ensemble d'hyperparamètres pour l'ajustement de modèles. Un seul ensemble d'hyperparamètres est constant pour chacun des 5 plis utilisés dans une seule itération de n_iter, de sorte que vous n'avez pas à scruter les différents scores entre les plis au sein d'une itération.

+0

Merci et cela aide! Savez-vous pourquoi cette erreur se produit et dois-je supprimer/réparer? /model_selection/_validation.py:252: FitFailedWarning: l'ajustement du classeur a échoué. Le score sur cette partition train-test pour ces paramètres sera fixé à 0.000000. Détails: XGBoostError ('valeur 1.8782 pour le paramètre colsample_bytree dépassé bound [0,1]',) "Détails: \ n% r"% (error_score, e), FitFailedWarning) – zad0xlik

+0

le message d'erreur que vous avez posté indique 'XGBoostError (' La valeur 1.8782 pour le paramètre colsample_bytree dépasse bound [0,1] '.La raison pour laquelle vous obtenez cela est parce que '' colsample_bytree ': stats.uniform (0.5, 0.9) 'donnera une valeur parfois en dehors de la plage requise [0,1] pour ce paramètre. –