使用 xgboost 进行校准

问题描述 投票:0回答:2

我想知道是否可以在 xgboost 中进行校准。更具体地说,xgboost 是否带有像 scikit-learn 中那样的现有校准实现,或者是否有一些方法可以将 xgboost 中的模型放入 scikit-learn 的 CalibrateClassifierCV 中?

据我所知,在 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 树模型放入 CaliberatedClassifierCV 中,将会抛出错误(当然):

RuntimeError: classifier has no decision_function or predict_proba method.

有没有办法将scikit-learn优秀的标定模块与xgboost集成起来?

scikit-learn xgboost
2个回答
10
投票

回答我自己的问题,通过编写如下例所示的包装类,可以将 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

请参阅完整示例此处

请随时提供更智能的方法来执行此操作!


3
投票

2020 年 7 月地狱景观的笔记:

您不再需要包装类。 Predict_proba 方法内置于 xgboost sklearn python api 中。不确定它们是什么时候添加的,但 v1.0.0 肯定有它们。

注意:这当然仅适用于具有 Predict_proba 方法的类。例如:XGBRegressor 没有。 XGBClassifier 可以。

© www.soinside.com 2019 - 2024. All rights reserved.