2016-02-23 2 views
5

Мне интересно, могу ли я сделать калибровку в xgboost. Чтобы быть более конкретным, есть ли xgboost с существующей реализацией калибровки, например, в scikit-learn, или есть некоторые способы поместить модель из xgboost в CalibratedClassifierCV scikit-learn?Калибровка с помощью xgboost

Насколько я знаю, в sklearn это обычная процедура:

# 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 

Если я поставил модель дерева xgboost в CalibratedClassifierCV об ошибке будет сгенерировано (конечно):

RuntimeError: classifier has no decision_function or predict_proba method.

Есть ли способ интегрировать отличный калибровочный модуль scikit-learn с xgboost?

Цените свои проницательные идеи!

ответ

4

Отвечая на мой вопрос, xgboost GBT можно интегрировать с scikit-learn, написав класс-оболочку, как в случае ниже.

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 

Полный текст примера here.

Пожалуйста, не стесняйтесь предоставить более разумный способ сделать это!

+0

хорошая работа. Я обнаружил, что дополнительная калибровка по методам, когда логлосс прямо оптимизирован (например, xgboost), не дает столько же. Случайные леса и SVM являются известными виновниками высокодискриминационных классификаторов, но потому, что они оптимизируют разные вещи, могут использовать некоторую калибровку. Хорошая работа –

Смежные вопросы