2016-02-23 28 views
5

Mi chiedo se posso eseguire la calibrazione in xgboost. Per essere più specifici, xgboost è dotato di un'implementazione di calibrazione esistente come in scikit-learn, o ci sono alcuni modi per inserire il modello da xgboost in un CalibratedClassifierCV di scikit-learn?Calibrazione con xgboost

Per quanto ne so in sklearn questa è la procedura comune:

# Train random forest classifier, calibrate on validation data and evaluate 
# on test data 
clf = RandomForestClassifier(n_estimators=25) 
clf.fit(X_train, y_train) 
clf_probs = clf.predict_proba(X_test) 
sig_clf = CalibratedClassifierCV(clf, method="sigmoid", cv="prefit") 
sig_clf.fit(X_valid, y_valid) 
sig_clf_probs = sig_clf.predict_proba(X_test) 
sig_score = log_loss(y_test, sig_clf_probs) 
print "Calibrated score is ",sig_score 

Se metto un modello di albero xgboost nella CalibratedClassifierCV verrà generato un errore (ovviamente):

RuntimeError: classifier has no decision_function or predict_proba method.

C'è un modo per integrare l'eccellente modulo di calibrazione di scikit-learn con xgboost?

Apprezzate le vostre idee penetranti!

risposta

4

Rispondendo alla mia domanda, un GBT xgboost può essere integrato con scikit-learn scrivendo una classe wrapper come nel caso seguente.

class XGBoostClassifier(): 
def __init__(self, num_boost_round=10, **params): 
    self.clf = None 
    self.num_boost_round = num_boost_round 
    self.params = params 
    self.params.update({'objective': 'multi:softprob'}) 

def fit(self, X, y, num_boost_round=None): 
    num_boost_round = num_boost_round or self.num_boost_round 
    self.label2num = dict((label, i) for i, label in enumerate(sorted(set(y)))) 
    dtrain = xgb.DMatrix(X, label=[self.label2num[label] for label in y]) 
    self.clf = xgb.train(params=self.params, dtrain=dtrain, num_boost_round=num_boost_round) 

def predict(self, X): 
    num2label = dict((i, label)for label, i in self.label2num.items()) 
    Y = self.predict_proba(X) 
    y = np.argmax(Y, axis=1) 
    return np.array([num2label[i] for i in y]) 

def predict_proba(self, X): 
    dtest = xgb.DMatrix(X) 
    return self.clf.predict(dtest) 

def score(self, X, y): 
    Y = self.predict_proba(X) 
    return 1/logloss(y, Y) 

def get_params(self, deep=True): 
    return self.params 

def set_params(self, **params): 
    if 'num_boost_round' in params: 
     self.num_boost_round = params.pop('num_boost_round') 
    if 'objective' in params: 
     del params['objective'] 
    self.params.update(params) 
    return self 

Vedere l'esempio completo here.

Si prega di non esitare a fornire un modo più intelligente di farlo!

+0

bel lavoro. Ho trovato che la calibrazione aggiuntiva sulle tecniche in cui logloss è ottimizzato direttamente (come xgboost) non produce tanto. Le foreste casuali e gli SVM sono noti colpevoli di essere classificatori altamente discriminanti, ma poiché stanno ottimizzando cose diverse, possono utilizzare alcune calibrazioni. Bel lavoro –