【问题标题】:Calibration with xgboost使用 xgboost 进行校准
【发布时间】:2016-02-23 19:00:16
【问题描述】:

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

据我所知,这是 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集成?

欣赏您富有洞察力的想法!

【问题讨论】:

    标签: scikit-learn xgboost


    【解决方案1】:

    2020 年 7 月的地狱景象:

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

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

    【讨论】:

      【解决方案2】:

      回答我自己的问题,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

      请不要犹豫,提供一种更智能的方法!

      【讨论】:

      • 干得好。我发现对直接优化 logloss 的技术(如 xgboost)进行额外校准不会产生太多效果。众所周知,随机森林和 SVM 是高判别分类器的罪魁祸首,但由于它们正在优化不同的事物,因此可以使用一些校准。干得好
      猜你喜欢
      • 2021-04-07
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 2015-11-11
      • 2018-10-23
      • 1970-01-01
      相关资源
      最近更新 更多