2018.03.06

【Techブログ】キャリブレーション用のEstimatorを作りました

DSOC R&Dグループの中野です。

前回の記事では、XGBoost単調性制約Probability calibrationについて記事を書きましたが、ブースティングを使ってキャリブレーションをやることに関心がある日本語圏の人は少ないだろうと反省がありました。

少しでもリーチする人を増やすために、本家へのマージを目指して取り組んでいることを紹介します。

やったこと

前回の記事にもあるように、単調性制約は param['monotone_constraints'] = '(0,1,0,-1,0)' といった具合にタプルを文字列にして設定してあげる必要があり、直感的に使いにくいと感じられます。Isotonic regression感覚で使えるキャリブレーション用クラスが便利なので、実装を試みました。

実装について

単調性制約をかければ、Isotonic regression相当に機能するので、数値計算の処理を書く必要はありません。パラメータを渡してやるだけです。

キャリブレーションは分類問題に対して行うので、 XGBClassifier を継承することにします。このときにユーザーを煩わせることなく、単調性制約が設定されるようにしました。

class XGBCalibrator(XGBClassifier):
  def __init__(self, max_depth=5, **kwargs):
    kwargs_calibration = kwargs
    kwargs_calibration['monotone_constraints'] = '(1)'
    super(XGBCalibrator, self).__init__(max_depth, **kwargs_calibration)

これで目的は達成されたのですが、もう一工夫します。

fit に特徴量として1次元配列を渡すと、XGBoostの内部的に利用するデータ構造がうまく作れないためにエラーが出てしまいます。また、キャリブレーション用であれば、ベースのモデルが出力した確率が1次元配列となることが多く、不便です。

1次元配列を渡してもエラーとならないようにしましょう。

def fit(self, X, y, sample_weight=None, eval_set=None, eval_metric=None,
    early_stopping_rounds=None, verbose=True, xgb_model=None):
  if len(X.shape) == 1:
    # 1d array
    X = np.reshape(X, (len(X), 1))
  super(XGBCalibrator, self).fit(X, y, sample_weight, eval_set, eval_metric,
                                 early_stopping_rounds, verbose, xgb_model)
  return self

インプットを2次元配列に変換した後は親クラスと同じ処理になるので、 super()を使って親クラスのメソッドを呼びます。

これで完成です。

今後の展望

現在は、Issueを立てて様子を伺っている状況です。キャリブレーションにブースティングを使ってみたい人が多いようであれば、PRを出してみたいです。

今回の開発は、チームメンバーにSlackで意見をもらって、Pythonの多重継承や sklearn.base.BaseEstimator についての理解を再確認することができました。

OSS開発は自分にとっても得るものが大きく、またXGBoostをはじめとしたデータ分析周辺のライブラリーには日頃からお世話にもなっていますので、何かしらコミュニティーへ貢献できるように取り組みを続けていきたいです。

“Most competitions are won using either the XGBoost library (for shallow machine learning) or Keras (for deep learning). So you’ll fit right in! By participating in a few competitions, maybe as part of a team, you’ll become more familiar with the practical side of some of the advanced best practices described in this book, especially hyperparameter tuning, avoiding validation-set overfitting, and model ensembling.”

—François Chollet, Deep Learning with Python

「浅いモデルはXGBoostで」

2週続けて同じネタになってしまいましたね。来週は、別の話題で書きたいと思います。

リンク

執筆者プロフィール

text: DSOC R&Dグループ 中野良則