初めての特徴量エンジニアリング

# 初めての特徴量エンジニアリング
## この記事を読んでわかること
- 特徴量・特徴量エンジニアリングなどの用語が何か、何をするものかがわかる
- 特徴量の初歩的な作成方法がわかる 
- 特徴量の性質に応じて適切な手法を使い分けられるようになる. 

## 特徴量とは
特徴量とは、**対象の特徴を数値で表したもの**である。   
人間の特徴ならば身長や体重、出生地、生年月日など数値で表せるものはなんでも特徴量と言える。  
ここで、出生地？数値じゃなくない？と思うかもしれないが、エンコーディングを行えば数値に変換でき、モデルへのinputとして使用できる。これは後で説明する。  
数値であることに拘ったが、この理由としては機械学習の識別器は数値データしか扱えないためである。
## 数値データとカテゴリカルデータ
### 数値データ
数値データとは、数値で表現されているデータである。一般的には実数を用いる。整数などでもOK。    
例：ある月に読んだ本の数、ある日のYouTubeの試聴時間  

数値の特徴量として考えうる問題としては例えば以下のようなものが挙げられ、これらを解消することでモデルの性能向上に影響する。　　  
- 分布の形がガウス分布ではない。
- 外れ値がある。
- 特徴量の間でスケールが異なる。

以下それぞれについて簡単に解説する。これらの問題の解消法は後の一つの特徴量に関する処理の項目で詳しく扱う。
- **分布の形がガウスではない**    
モデルのいくつか（線形モデル、ニューラルネットなど）は、入力としてガウス分布を仮定している。なのでこれから外れた分布はあまり良くない性能となってしまうことがある。
- **外れ値がある**  
外れ値とは、あるデータにおいて明らかに正しくない、もしくは正しくてもボリュームゾーンからかけ離れているもののことを指す。  
例: 日にちのデータで43日、年収のデータでビルゲイツの年収のデータ（平均などを取る際に明らかに上振れすると予測できる)  
これらは取り除くか、四分位の近いものに割り振るなどの操作をすることで性能が良くなることがある。  
- **特徴量の間でスケールが異なる。**  
スケールの違いとは、簡単に言えば変数の大きさの違いである。  
例: 象と蟻の体重のデータがあるときに前者と後者では全然大きさが異なるだろう。  
このようなデータで起きる不都合としては、あるモデル（線形モデルやニューラルネットなどの変数の値を足すことがあるモデル）において、大きいデータは重要度が高く見え、小さいデータは重要度が低く見えてしまうことがある。  

ただし決定木ベースのモデル（決定木、ランダムフォレスト、lightGBMなど）は変数間の順位のみに依存するため上であげたことにそこまで影響されない。外れ値への対処はしてもいいかもしれない。

### カテゴリカルデータ
カテゴリカルデータとは連続な数値以外で表現されたデータである。  
厳密性を欠くが、四則演算が意味を持たないデータとも言えるだろう。  
例：好きな楽器の種類、米の品種、国籍など。  
コシヒカリとササニシキを足しても意味がわからないことは容易に想像がつくと思う

このカテゴリカルデータを扱うには数値に変換する必要がある。その手法としてエンコーディングというものがある。  
この文脈でのエンコーディングとは、**カテゴリを数値に対応させること**である。  
その手法をいくつか紹介する。
- **one-hot-encoding**  
あるカテゴリがある場合1, ない場合0としてフラグを立てた特徴量を作成する。　　
利点としては、ほとんどどのモデルでもうまく作用する。特徴量の取捨選択ができるので過学習を防げる可能性がある。  
デメリットは特徴量の数が増えるので学習に時間がかかる。
以下は例  

| 出身地 | Hokkaido | Aomori | Akita | Iwate |   
| :---: | :---: | :---: | :---: | ---: |  
| 秋田 | 0 | 0 | 1 | 0 |  
| 青森 | 0 | 1 | 0 | 0 |  

- **カテゴリカルエンコーディング**  
ある全単射な写像を用いて、カテゴリを数値に置き換える。  
メリットは特徴量が増えないこと。  
デメリットはそもそも使えない、もしくはうまく作用しないモデルがあること。

| 出身地 | from | 
| :---: | :---: |
| 秋田 | 1 |
| 青森 | 2 |
| 岩手 | 3 |
| 北海道 | 4 |
| 青森 | 2 |
- **ターゲットエンコーディング**  
カテゴリ変数の値を、そのカテゴリごとのターゲットの統計量で置き換える。  
例:　職業のカテゴリをその職種ごとの年収の平均で置き換える。
メリットは数値として意味を持っている（c.f. カテゴリカルエンコーディングは数字の値としては意味を持たない変換）ので学習に有利なことがある。  
デメリットは、そもそも変換するのにハードルが高い。理由としては、変数にリークが起きる可能性があるためである。（リークとは、ターゲットの情報が訓練に使用されてしまい正しく訓練できなくなること。）

| 職業 | job | salary | 
| :---: | :---: | :---: |
| アルバイト | 20 |10|
| 自営業 | 30 |20|
| アルバイト | 20 |30|
| 自営業 | 30 |40|
| 会社員 | 50 |50|

**解説**
今回はsalaryを予測したい変数（target）であるとする  
アルバイトの平均賃金は(10+30)/2 = 20  
なのでアルバイトの人のjob欄を20で置き換えている。他も同様。  
ここで問題点として、会社員はjobがsalaryそのままである。
これは明らかにリークであっていいモデルは作れない。  
直感的な説明をすると、答えを教えてしまっているので、他の特徴量がサボってしまい、汎化性能が低くなる。
## 特徴量エンジニアリングとは
特徴量エンジニアリングとは、**特徴量をより使いやすい形に変換する**行為全般を指す。  
例：身長と体重を用いてBMIという指標を作る。年収のデータについて、今年のデータから去年のものを引いて伸び率のデータを作る。  
作成以外にも、欠損値の処理や外れ値の除去なども含む
## 特徴量の作成
新たに作成する方法についてまとめる。  
これ以降扱うデータに対しては以下の仮定を置く。  
**=>時系列ではない数値のデータとする。**

### 作成の手順
1. 新しい特徴量についての仮説を立てる  
1. 1.を元に作成する。

仮説の立て方は主に、
- データを可視化して良さそうなものを探す。  
- 経験をもとに作成する
- 知識をベースに作成する。(俗にドメイン知識などと呼ばれる。)
- とりあえず複数項目を四則演算（運が良ければいいものが作成できる） 

知識ベースのものについての例を与える。
- 日にちのデータに曜日の情報を付加する（7日間周期があることはモデルは主に読み取れない）

作成の部分に関しては、まずライブラリに存在するものが使えないかを検討する。  
次に、これができない場合は、自作することになるが、pandasの機能をうまく使うと簡単にできることが多い。  

### 一つの特徴量についての操作
ある単独の特徴量（年齢や身長など）についての手法をまとめる。  
この章では主に新しいものを作るというよりもデータの不都合を解消することでモデルの性能向上に寄与していくことを目的とする。　　
先ほど出てきた数値データに対する問題点を再度載せておく。　　
- 分布の形がガウス分布ではない。
- 外れ値がある。
- 特徴量の間でスケールが異なる。

これらの問題はモデルに悪影響を与えるので対処する必要がある。
モデルは入力変数の分布として正規分布を仮定しており、これを満たさない場合あまりいい性能が出ないことがある。
この問題への対処としては、logをとるというものがある。(画像を添付する)  

**分布がガウス分布から程遠い問題**  
分布がガウスでない問題について、今回は主に以下の図のような分布に対しての手法を紹介する。
![変換前](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711801/d0dff20a-3960-6546-b72e-67d48f48d250.png)
このような分布に対してはlogで変数変換することで正規分布に近い形となる。
![変換後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711801/b7894333-57c3-6e60-1bd5-4580a94666da.png)

**スケールが違う問題**
スケールに関してやりたいことしては、全ての変数の大きさを同じ程度にすることである。
この手法をスケーリングといい２つ紹介する。
1. 標準化  
標準化は、データの分布の平均を0, 分散を1に揃えることである。  
計算方法としては、データから平均を引き、分散のルートで割ることにより標準化できる。
2. 最大を1, 最小を0に揃える正規化  
この正規化のメリットは、全てのデータの最大と最小が揃っているので扱いやすい点がある。   
一方デメリットとしては、外れ値に弱い、ニューラルネットなどは標準正規分布を仮定しているなどがある。
特別なケースを除いては標準化をするのが無難だろう。


### 二つ以上のの特徴量についての操作
ある２つ以上の特徴量の組(体重と身長、年収と年齢など)についての手法をまとめる。    
ここでは主に新しく特徴量を作成する部分に焦点を当てる。  
作る上で主に使うものは四則演算と変換(log, sqrt, powerなど)！  

仮説がある場合は、仮説に基づいて特徴量を作成すれば良い。  
ない、もしくは全く思いつかない場合もあるだろう。  
そのような時は、仮説の部分を省略して、とりあえず大量に作ってみると良いものが作れる時がある。

体重と身長を例として用いるが、体重と身長の積、身長あたりの体重、身長を二乗、体重を1/2乗して積を取るなど。このように組み合わせを変えれば色々作成できる。  

ただし、この手法はかなり適当に作成しているので特徴量の選択をした方がいい場合がある。
モデルに入力として与え、性能が改善されるかなどを見れば大まかな良し悪しが判断できる。

最後に、適当に作って意味あるの？と思われるかもしれないが、モデルによっては、積や商を作り出せないものもある。なので、これは前処理としてやる価値があるのである。  
## まとめ
- 特徴量・特徴量エンジニアリングなどの用語について説明した。
- データの性質（カテゴリカル、数値）に応じてどのような違いがあるか、またどのような処理をするのかを説明した。
- 初歩的な特徴量エンジニアリングを説明した。  

## 参考文献
https://www.tryeting.jp/column/1000/  
https://uribo.github.io/practical-ds/intro.html