statsuのblog

愛知のデータサイエンティスト。自分の活動記録。主に機械学習やその周辺に技術について学んだことを記録していく予定。

分位点回帰を使ってLightGBMの推定値の分布と不確かさを評価する

分位点回帰を使った推定値の分布評価と不確かさ評価について気になっていたので試してみました。
記事タイトル及び検証ではLightGBMを使っていますが、他の手法でも同じ考え方を適用できるはずです。
以下の検証に関するコードはgithubにあげてあります。
quantile_regression_gbdt/quantile_regression.ipynb at main · statsu1990/quantile_regression_gbdt · GitHub

記事の概要

  • 分位点回帰についての簡単な説明
  • LightGBMでの検証

分位点回帰(Quantile Regression)について

通常の回帰問題では目的変数の平均値や中央値を推定するモデルを作ることが多いと思います。
分位点回帰では、1/4分位や3/4分位など指定の分位での目的変数の値(分位点)を推定するモデルを作れます。分位点での目的変数の値がわかると、目的変数の分布を推定することができるようになります。分布を推定できると推定値の不確かさを評価できるなど、実用上嬉しいことがたくさんあります。

よく使われる回帰問題と分位点回帰の違いは損失関数のみです。MSE Lossを使うと平均値、MAEを使うと中央値、Pinball Lossを使うと分位点を推定するモデルとなります。
Pinball Lossは全然複雑ではないのでcustom lossとして自分で作ることも簡単ですし、LightGBMではobjectiveとして用意されていたりするので、分位点回帰を使うハードルはかなり低いです。

詳細はこちらのサイト等を参照してください。
分位点回帰を使って、「その回帰予測どれぐらい外れるの?」を説明する - BASEプロダクトチームブログ
ピンボールロス(Pinball loss)の解説 – S-Analysis
QRNN ニューラルネットを用いた分位点回帰 - 学習する天然ニューラルネット

LightGBMでの検証

LightGBMでの分位点回帰の有効性を検証してみました。
データはKaggle House Pricesの学習データを使いました。Kaggle House Pricesは、部屋の広さ等の説明変数から家の販売価格を予測するタスクです。
House Prices - Advanced Regression Techniques | Kaggle

検証の概要

  • LightGBMでの分位点回帰の実装
  • 分位点の可視化
  • 分位点の妥当性評価
  • 推定誤差と分位点から算出した標準偏差の関係性の評価

検証の条件

  • データを、49%学習データ、21%バリデーションデータ、30%テストデータに分割
  • 目的変数はlog(家の販売価格)
  • 説明変数は数値変数のみ使用(カテゴリ変数は削除)
  • LightGBMのパラメータサーチはしない
  • (0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95)の分位点を推定するモデルを作成

LightGBMでの分位点回帰の実装

objectiveにquantileを指定し、alphaに分位を指定するだけで分位点回帰になります。

mdl = LGBMRegressor(objective='quantile', alpha=0.4)

複数の分位点を推定したい場合、分位ごとにモデルを作る必要があります。なお、NNだと1つのモデルで複数出力にできると思います。

quantiles = (0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95)
qr_models = []
for q in quantiles:
    mdl = LGBMRegressor(objective='quantile', alpha=q)
    mdl.fit(tr_x, tr_y)
    qr_models.append(mdl)

分位点の可視化

分位点をうまく推定できていれば、小さい分位での推定値は小さく、大きい分位での推定値は大きくなるはずです。可視化して確認してみます。
学習データ

f:id:st1990:20201223012932p:plain
正解値 vs 推定値 (学習データ)
f:id:st1990:20201223013559p:plain
分位 vs 推定値(学習データ)

テストデータ

f:id:st1990:20201223013037p:plain
正解値 vs 推定値 (テストデータ)
f:id:st1990:20201223013705p:plain
分位 vs 推定値(テストデータ)

良い感じですね。基本的に分位が大きいほど推定値が大きくなっています。ただ、一部そうなっていないところもあります。原理的に多少の誤差はあるようです。
また、正解値が大きいときに分位0.05がサチっているように見える、正解値が小さいときに分位0.95がサチっているように見えるのですが、理由はわかりません。とりあえずスルーします。

分位点の妥当性評価

分位点を推定できるようになりましたが、推定した分位点が本当にその分位での目的変数の値なのか評価したいです。「指定した分位での目的変数の正解値」は普通わからないので、正解値と直接比較するような評価はできません。ここでは、分位点の定義に立ち戻って評価します。
分位点の定義より、「正解値が分位点以下になる確率」=「分位」となるはずです。そうなっているか可視化してみます。

f:id:st1990:20201223014421p:plain
分位 vs 正解値が分位点以下になる確率 (学習データ)
f:id:st1990:20201223014509p:plain
分位 vs 正解値が分位点以下になる確率 (テストデータ)
テストデータでは少しずれてしまっていますが、かなり良い感じではないでしょうか。思っていたより良くてびっくりです。

推定誤差と分位点から算出した標準偏差の関係性の評価

推定した分位点から、推定値の平均値と標準偏差を計算できます。正解値とこの平均値の差を推定誤差としたとき、推定値の標準偏差(=不確かさ)が大きいほど推定誤差も大きくなると考えられます。このような関係となっているか可視化して確認します。

f:id:st1990:20201223015124p:plain
推定誤差と推定値の標準偏差(=不確かさ)の関係 (学習データ)
f:id:st1990:20201223015229p:plain
推定誤差と推定値の標準偏差(=不確かさ)の関係 (テストデータ)
推定値の標準偏差(=不確かさ)が大きいほど推定誤差も大きくなっていますね。いい感じです。

まとめ

  • 分位点回帰について説明しました。
  • LightGBMでの分位点回帰の実装方法について説明しました。
  • Kaggle House Pricesデータを使って、分位点回帰で分位点を推定できていること、推定値の不確かさを評価できることを確認しました。