カテゴリ変数の取り扱い方法
都道府県の名称など、値自体に意味が無い変数を扱う場合は、そのまま機械学習にかけてしまうと意味不明な結果が出る。
そこで、よく使うカテゴリ変数の対処方法をまとめた。
ダミー変数化
変数を各種類ごとのカラムに分けて、0,1表記にしよう。と言うもの
一番ポピュラーなカテゴリ変数の扱い。
ターゲットエンコーダー
各カテゴリ変数の各値で、正解である割合を各変数の持つ変数値として持たせる方法
参考資料 Feature Engineering
somoothing_encoder
図 3の「埼玉」みたいに、ターゲットエンコーダーを実際の現場で活用すると、たまたま少ない数の目的変数が全て1であった場合、ターゲットエンコーダーの値が1になって信頼性が疑わしい。
ので、パラメーターとして、学習データの中の「埼玉の割合」を重み付けする係数を追加する。
式は以下の感じ。
これを通じて、目的変数の発生確率を重み付け、たまたま「埼玉」が1になる時に、信頼性を重み付けられるようにしている。
詳しくは参考資料を
A Preprocessing Scheme for High-Cardinality Categorical Attributes in Classification and Prediction Problems
light gbmのカテゴリ変数の扱い
種類がめっちゃ多いカテゴリ変数を、ダミー化して変数を構築すると、カテゴリ変数の種類の分だけ列が増え計算量が増大してしまうし、最適化がされにくいらしい。
Particularly for high-cardinality categorical features, a tree built on one-hot features tends to be unbalanced(ドキュメントより引用)
とりあえず、カテゴリ変数を、各分岐点での (sum_gradient / sum_hessian)の値でヒストグラムを構築し、損失関数が最小になるところで分岐させる
documentによると、大体はダミー化するよりいいモデルができるらしい。
CatBoost
上記に書いたみたいに、lightGBMでは分岐させるときに、データの勾配を使って学習を行わせる。 ただ、これだと真のデータ分布に従うか分からないのに、観測データだけでモデルを作るようなものなので、バイアスが掛かって過学習してしまう。 (ちょっといい感じに日本語に訳せないので、論文の原文を引用。)
This leads to a shift of the distribution of estimated gradients in any domain of feature space in comparison with the true distribution of gradients in this domain, which leads to overfitting.
解決策としては、勾配の分布をモデリングするモデルを別途作りましょう。と言う感じ。 カテゴリ変数を扱う上では有用らしいが、全体の精度としては正直LightGBMとかと変わらない気がする。
とりあえず、CatBoostではカテゴリ変数を数値に変換しており、方法は以下の式のようになる。
- CountInclass :ターゲットエンコーダーと同じ
- propr:ユーザー側で指定するパラメーター
- totalCount:該当の値の数
参考資料
CatBoost: gradient boosting with categorical features
support
Transforming categorical features to numerical features