盆暗の学習記録

データサイエンス ,エンジニアリング,ビジネスについて日々学んだことの備忘録としていく予定です。初心者であり独学なので内容には誤りが含まれる可能性が大いにあります。

LightGBMにおける欠損値の扱い

Githubでの議論などを見てわかったことをメモしておきます。

前提

欠損値に関するハイパーパラメータがデフォルトのまま(use_missing = truezero_as_missing = false)の場合の挙動について。

学習時の欠損値の取り扱い

numerical featureの欠損値

最も誤差を小さくする枝に割り振る

categorical featureの欠損値

常に右側の枝に割り振る

  • categorical featureの分岐は下の図のようになっていて、その変数の値がある値に該当すれば左に分岐し、それ以外はすべて右に分岐する( if x == 'A' then left, else rightといった感じ)
  • 欠損値は全部の分岐でelseになったパターンになるはず

f:id:nigimitama:20200926175137p:plain

予測時の欠損値の取り扱い

numerical featureの欠損値

  • 学習時に欠損値があった場合: 学習時に割り振った側の枝に割り振って予測する
  • 学習時に欠損値がなかった場合: 欠損値はゼロに変換される1

categorical featureの欠損値

常に右側の枝に分岐していった先で予測が行われる

  • 訓練データに入っていなかったカテゴリはすべて右に分岐する。欠損値も同様。

まとめると

numerical feature categorical feature
学習 最も誤差を下げる枝に割り振る 常に右側の枝に割り振る
予測(欠損既知) 割り振った側の枝で予測する 常に右側の枝で予測
予測(欠損未知) 欠損値をゼロに置換して予測する 常に右側の枝で予測
  • 欠損既知:学習時に当該特徴量が欠損値のレコードがあった
  • 欠損未知:学習時に当該特徴量が欠損値のレコードが無かった

考察

ゼロとして扱われる場合に要注意

numerical featureで予測時にのみ欠損値がある場合は欠損値がゼロとして扱われるため、これの影響がどう出るかはそのデータの分布によって変わりそう。

もしその特徴量においてゼロがめったに出ない値なのであれば、欠損値は別のもっともらしい値で埋めたほうがよさそう。(具体的には、欠損値を埋めるための予測モデルを作って埋めたり、あるいは単にその特徴量の平均値で埋めたり)

各決定木の間の相関が低ければ悪影響は低いのかも?

categorical featureにおける欠損値は「どのカテゴリでもない」という扱いになってしまうが、このときの予測精度はどの程度のものになるのだろう…。

例えば、あるcategorical feature  x が'A', 'B', 'C'の3カテゴリがあるとして、ある木の中では

if x == 'A':
    ...(1)
else:
    if x == 'B':
        ...(2)
    else:
        ...(3)

という感じの分岐になった場合、(3)の領域に含まれる訓練データは'C'であり、 xが'C'のデータに対する誤差(不純度)を最小化するように学習される。

もしこの木で予測をするときに xが欠損値なら、「AでもBでもない」ということで(3)の領域に入り、 xが'C'である場合と同じ扱いを受けるはず。

もし、その予測したいデータの xが実は'C'なのであれば誤差は小さくなるだろうし、それ以外のカテゴリであれば誤差は大きいと考えられる。

単体の決定木で考えると、上のように考えられるが、LightGBMは基本的に多くの木を使用し、feature_fraction(各決定木で使用する特徴量をランダムに選び出した一部の特徴量のみにする)などのハイパーパラメータを使って各決定木の相関が低くなるように成長させていく。

そのため、各決定木間の相関が十分に低ければ、「ある木では欠損値が'A'として扱われ、ある木では'B'として扱われ、ある木では'C'として扱われる…」というのを繰り返していき、最終的には各カテゴリの平均のような値になるのかもしれない。

ただ、仮に全カテゴリの平均に近い値が予測値になるように収束するのだとしても、もし欠損値がある程度予測できるのであればできるかぎり予測して補完したほうが無難な気がする。