2016-02-23 21 views
5

Ich frage mich, ob ich Kalibrierung in xgboost tun kann. Um genauer zu sein, kommt xgboost mit einer vorhandenen Kalibrierungsimplementierung wie in scikit-learn, oder gibt es einige Möglichkeiten, das Modell von xgboost in einen CalibratedClassifierCV von scikit-learn zu bringen?Kalibrierung mit xgboost

Soweit ich in sklearn weiß, ist dies das gemeinsame Verfahren:

# 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 

Wenn ich ein xgboost Baummodell in die CalibratedClassifierCV wird ein Fehler gesetzt (natürlich) geworfen werden:

RuntimeError: classifier has no decision_function or predict_proba method.

Gibt es eine Möglichkeit, das exzellente Kalibrierungsmodul von scikit-learn mit xgboost zu integrieren?

Schätzen Sie Ihre aufschlussreichen Ideen!

Antwort

4

Als Antwort auf meine eigene Frage kann ein xgboost GBT in scikit-learn integriert werden, indem eine Wrapper-Klasse wie im folgenden Fall geschrieben wird.

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 

Siehe vollständiges Beispiel here.

Bitte zögern Sie nicht, einen klügeren Weg zu bieten, dies zu tun!

+0

netter Job. Ich habe festgestellt, dass die zusätzliche Kalibrierung von Techniken, bei denen logloss direkt optimiert wird (wie xgboost), nicht so viel ergibt. Random Forests und SVMs sind bekannt dafür, dass sie sehr diskriminierende Klassifikatoren sind, aber weil sie verschiedene Dinge optimieren, können sie einige Kalibrierungen verwenden. Gut gemacht –