カテゴリカル変数はなんでもダミー変換すればよいのか?-アルゴリズムに応じたOne Hot EncodingとLabel Encodingの使い分け

カテゴリカル変数はなんでもダミー変換すればよいのか?-アルゴリズムに応じたOne Hot EncodingとLabel Encodingの使い分け


KaggleのKernelを見ていると、カテゴリカル変数に対して特に理由もなくpandasのget_dummiesメソッドでOne Hot Encodingをしている場合が多いようです。
本人たちは理解してカテゴリカル変数をEncodingしていると思いますが、なぜそのEncodingなのかを説明しているKernelを私は見たことがありません。
そこで自分の頭の整理を兼ねて、カテゴリカル変数をEncodingする場合にはOne Hot Encoding、Label Encodingのどちらを使用するべきなのかをまとめてみようと思います。

準備

以下のような、ある店の曜日別来店数のデータを前提に説明していきます。

day_of_weekvisitors
300
100
110
120
130
200
320

day_of_week(曜日)がカテゴリカル変数になります。

Label encodingとは何か

カテゴリカル変数をスカラ値(数値)に変換することです。
day_of_weekをLabel Encodingすると以下のようになります。

  • 日→0
  • 月→1
  • 火→2
  • 水→3
  • 木→4
  • 金→5
  • 土→6

カラム数はそのままで、数値に置き換わるので、メモリを節約できます。

One hot Encodingとは何か

カテゴリカル変数に対して、各要素が該当するなら1、該当しないなら0とするカラムを変数の要素数分作ることです。
先ほどの曜日をOne hot Encodingすると以下になります。

isSunisMonisTueisWenisThuisFriisSatvisitors
1000000300
0100000100
0010000110
0001000120
0000100130
0000010200
0000001320

Label Encodingとは異なり、カテゴリカル変数の要素の数だけカラムが増え、sparseなデータとなります。
したがって、かなりメモリを消費します。

どんなアルゴリズムに適用すべきか?

重み \( w \) と特徴量の線形結合が入力値となるアルゴリズムと、決定木ベースのアルゴリズムでEncodingが変わります。
まず、Label Encodingは決定木ベースのアルゴリズムで有効です。
上記のデータを訓練すると以下のようなロジックになります。
以下、学習データをフルに使ったoverfittingなモデルでの説明ですが、細かいことは気にせずに読んでいただけると幸いです。

この場合、しっかりと予測できるモデルになっているのがわかります。
しかし、線形回帰やニューラルネットなどの重み\( w \)と特徴量の線形結合が入力値となるアルゴリズムの場合には有効とは言えません。
Label Encodingした曜日別来店数データに対しては以下のモデルが作られることになります。

$$ predict = w_{0} \times day \_ of \_ week \, + \, bias $$

\( day \_ of \_ week \) に応じて値は変わるものの、 \( day \_ of \_ week \) の値の大きさに意味を持つモデルになっています。
日曜(0)が低く、月曜(1)、火曜(2)、・・・、土曜(6)になるにつれて予測値が増大してしまいます。

一方、One Hot Encodingであれば決定木ベースや線形回帰やニューラルネットでも有効に作用します。
以下に線形回帰やニューラルネットにおける入力値の例を示します。

$$ predict = w_{0} \times isSun \, + w_{1} \times isMon + \, \cdots + w_{6} \times isSat \, + \, bias $$

上式であれば、カテゴリカル変数のそれぞれの要素に応じて重みづけができ、正確な予測ができます。

まとめ

Kaggleに取り組んでいるときにカテゴリカル変数に出くわすと何の気なしにまずはダミー化(One Hot Encoding)しがちですが、データ量が多い場合にはかなりのメモリ消費を強いられます。
扱うアルゴリズムに応じて適切なEncodingを使わなくてはいけないなと思い返すいい機会になりました。