川雲さんの分析ブログ

興味のあることの分かりにくい要約です。最近は機械学習、データ分析など。

特徴量抽出 - カテゴリ変数と数値変数の取り扱い方

1. 特徴量抽出とは

特徴量抽出(Feature Engineering)は機械学習の実応用において重要な工程です。
機械学習分野の大家であるAndrew Ng先生は次のように仰ったそうです(出典が見つからないので本当かは分かりません)。

"Coming up with feature is difficult, time-consuming, requires expert knowledge.
'Applied machine learning' is basically feature engineering."

実際に、Kaggleでも良い特徴量を見つけられるかどうかが順位を左右することがあるそうです。
しかしながら、特徴量抽出はアカデミックな研究対象ではないので、網羅的な解説が中々見つかりません。
そんな中で良い資料がありましたので、この内容を簡単にまとめます。
ただし、前半のカテゴリ値と数値の取り扱いのみです。

www.slideshare.net

2. 尺度水準

特徴量抽出の前に、まずは統計学の測定尺度についておさらいします。
測定尺度とは、データセットの中の数値を4種類に分類したものです。
それぞれの尺度で許される処理が異なるので注意が必要です。

尺度水準 - Wikipedia

  1. 名義尺度:数字をただの名前と考えたものです。例えばID、電話番号などです。カテゴリ値とも言われます。
  2. 順序尺度:順序を表す数字です。例えばレースの準位、地震の震度、成績表などが当てはまります。数字の大小に意味はありますが、差や比は意味を成しません。順序付きのカテゴリ値とも呼べるでしょう。
  3. 間隔尺度:間隔に意味のある数字です。「値の比」に意味はありませんが、「値の間隔の比」には意味があります。有名なのは℃単位の温度です。例えば「夏の最高気温30℃は春の最高気温15℃より2倍大きい」と言うことに意味はありませんが、「夏の一日の寒暖差(最高気温と最低気温の"間隔")6℃は、春の寒暖差12℃より2倍小さい」と言うことは可能です。
  4. 比例尺度:四則演算が全て使える数字です。物理学の数式に登場するほとんどの物理量はこれに属します。例えば、先程の温度も絶対温度K(ケルビン)に直せば比例尺度になります。年齢、金額、期間などもこれに属します。

機械学習においては数式上で四則演算を行うので、基本的に全ての値を比例尺度に変換する必要があります。
(ただし、モデルによってはカテゴリ値も扱えます。例えば決定木ベースのXGBoostやLightGBMではカテゴリ変数を扱うオプションがあります。)
従って、1.~3.の尺度を比例尺度に変換することが特徴量抽出の一つの目標となります。
なお、元の資料との整合の都合上、カテゴリ値と数値という分け方をします。

3. カテゴリ値の扱い

ここでは、カテゴリ値を扱います。
先程もお話した通りカテゴリ値はただの名前ですから、何かしらの処理が必要です。
ここではカテゴリを表す文字列を例として扱いますが、(ID等の)数字の場合でも同じ処理が可能です。

3.1. One-hot encoding

最初に挙げられる基本的な手法がOne-hot encodingです。
カテゴリ毎に列を作り、その内の一つだけを1、それ以外を0にします。
スパース行列ですのでメモリをあまり使いませんが、それでもカテゴリ数が大きくなると大変です。

国名 国名=JP 国名=US 国名=UK
JP 1 0 0
US 0 1 0
UK 0 0 1

3.2. Hash Encoding

上記のOne-hot encodingでは、カテゴリ数に応じて列数が増えることや、新しい値が出現する度に列数を増やす必要があることが問題点として挙げられます。
これを解決するために、ハッシュ関数を用いて固定の配列に変換するのがHash encodingです。
ハッシュ関数とは、ある値(キー)を別の値(ハッシュ)にマッピングする操作です。
このマッピングを予め設定しておくことで、一意な変換が可能です。
しかし、長さ(ハッシュ値の数)を固定するので、カテゴリ数の方が大きい場合は複数のカテゴリが同じハッシュ値マッピングされ得ます(これを衝突と呼びます)。
そこで、複数のハッシュ関数を用意して、最も精度の良いものを選ぶそうです。

もっとも、衝突は必ずしも悪いことではありません。
例えば、複数形(catとcats)や表現の違い(JapanとJP)は同じことを指しているので、同じハッシュ値になった方が良い表現だと言えます。
One-hotでは複数の列に割り振られてしまうものを一つに纏められるのがHash encodingの強みでもあります。

参考:PFI Seminar 2012/03/15 カーネルとハッシュの機械学習

  • hash('JP') = 2
  • hash('US') = 4
  • hash('UK') = 1
国名 hash_1 hash_2 hash_3 hash_4 hash_5
JP 0 1 0 0 0
US 0 0 0 1 0
UK 1 0 0 0 0

3.3. Label encoding

カテゴリを表す文字列を数字に置き換えます。

国名 hash_1
JP 1
US 2
UK 3

3.4. Count encoding

ラベルの出現回数で置き換えます。
名義尺度を比例尺度に置き換えているとも言えます。
ただし、元々は違う値だったものが同じ値に変換され得ます。

国名 国名_count
JP 4
US 2
UK 1
JP 4
JP 4
US 2
JP 4

3.5. Label-Count encoding

ラベルの出現回数の順序に置き換えます。
つまり、名義尺度を順序尺度に置き換えています。
下の例では、出現回数の少ない方からランキングしています。

国名 国名_count
JP 3
US 2
UK 1
JP 3
JP 3
US 2
JP 3

3.6. Target encoding

ターゲット変数の平均値で置き換えます。
これも、名義尺度を比例尺度に置き換えています。
二値、もしくは回帰問題の場合に使える手法です。

国名 ターゲット 国名_count
JP 1 0.75
US 0 0.5
UK 1 1.0
JP 0 0.75
JP 1 0.75
US 1 0.5
JP 1 0.75

3.7. Category Embedding

Neural Networkを使って密な表現を作ります。
詳しくは、arXivの論文をご参照下さい。

[1604.06737] Entity Embeddings of Categorical Variables

3.8. NaN encoding

欠損値のある場合の対処法です。
欠損値は、その名の通りデータの値がなくNaNとなっているものを指します。
欠損値を補完する方法もあるのですが、そもそも欠損していることに意味がある場合もあります。
例えば、室温を測る温度センサーを測るときに40℃を超えるとデータが欠損する場合などです。
これをMNAR(Missing Not At Random)と言います。
(参考:前処理大全

では欠損値をどのように扱うのかというと、One-hot encodingで欠損値用の列を用意すればいいわけです。

国名 国名=JP 国名=US 国名=NaN
JP 1 0 0
US 0 1 0
JP 1 0 0
UK 0 0 1
US 0 1 0

3.9. Polynomial encoding

カテゴリ変数同士の組み合わせの特徴量を新しく作ります。
この動機は、単純な線形回帰などではXORの演算が出来ない点にあります。

A B ターゲット A=1*B=1 A=1*B=0 A=0*B=1 A=0*B=0 ターゲット
1 1 1 1 0 0 0 1
1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 1

3.10. Expansion encoding

一つの長い特徴量から複数の特徴量を分割します。
例えば、長い文章に含まれる単語を抜き出すことが挙げられます。

WIndows10, Python 3.6, Chrome

OS Coding Browser
Windows10 Python Chrome

3.11. Consolidation encoding

複数のカテゴリ値を同じ変数に変換します。
スペルミス、ほぼ同じ内容の表現などをまとめることが出来ます。

名前 地域 国名
Japan Asia Japan
JP Asia Japan
Japn Asia Japan
US North America USA
USA North America USA
America North America USA

4. 数値の扱い

数値の場合は、基本的にこのままアルゴリズムで学習させることが可能です。
従って、いかに述べる操作は必須ではないかもしれません。

4.1. Rounding

数値を丸め込みます。
よくあるのは小数点以下の切り捨てですが、例えば1の位を切り捨てるとカテゴリ変数のようにも扱えます。

年齢 年齢1 年齢2
22.25 22 2
29.10 29 2
25.52 25 2
19.80 19 1
15.41 15 1

4.2. Binning

連続値を、特定の区間毎に区切ります。

年齢 20歳以下 20~25歳 26歳以上
22.25 0 1 0
29.10 0 0 1
25.52 0 0 1
19.80 1 0 0
15.41 1 0 0

4.3. Scaling

値を特定の範囲内に変換します。
* Standard Scaling: 正規化のことです。平均0、分散1の範囲に値が収まります。
* MinMax Scaling: 値の範囲が[0, 1]に収まります。 * Log Scaling: (1を足して)対数をとる。

4.4. Imputation

欠損値を埋める方法です。
平均値・中央値で埋める、無視する、線形回帰モデルを使うなどの手法があります。

5. 他のデータの取り扱い方

この他にも、日付、位置情報、自然言語の特徴量抽出が紹介されています。
そちらは理解できていない部分がありますので、ここでは割愛致します。

6. 最後に

ここでは特徴量抽出の基本的な処理の仕方を述べました。
しかし、最初のNg先生の言葉にもあるように、特徴量抽出には各分野特有のドメイン知識が必要なことも多々あることと思います。
これは経験を積んで身に付けるしかないのかもしれません。

なお、他の特徴量抽出手法や、実際のコーディングなどは前処理大全という書籍に詳しく載っています。
よろしければどうぞ。

以上です。