データ前処理②  データを Categorical から Numerical に。

#OneHotEncoder の必要性

## OneHotEncoder とは、Scikit-learn を使う上で何故重要なのか。

機械学習においての、分類、回帰を使う時は、基本的に、コンピューターは、数字を連続する数字として扱う。　つまり、１ から 10 の数字があった時に、１は１０より必ず大きいと認識する。

何を当たり前のことを言っているんだ！　と思うだろう。

しかし、考えてみてほしい。

例えば、動物を下記のように数値に変換したとして、果たして、数値的に Tiger は Human よりも大きいということに意味があるだろうか。
例えば、下記の表を元に考えると、Tiger と Cat の平均をとると、Panda になってしまうという、なんともおかしな状況になってしまう。

| Animal       |    Transform to Numbers    |
|:-----------------|:------------------:|
| Tiger            |             0 |      
| Panda           |            1 |      
| Cat            |              2 |
| Human              |               3 |
| Python            |             4 |

このように、数字に変換した時に、数字の前後が全く意味をなさない時に使うのが、 OneHotEncoder だ。



## OneHotEncoder は既記の問題に対してどう対処するのか。

わかりやすく、上記の図を OneHotEncoder で処理するとこうなる。

| Tiger    |   Panda | Cat | Human | Python |
|:--------:|:-------:|:---:|:-----:|:------:|
| 1        |     0   |  0  |   0   |    0   |
| 0        |     1   |  0  |   0   |    0   |
| 0        |     0   |  1  |   0   |    0   |
| 0        |     0   |  0  |   1   |    0   |
| 0        |     0   |  0  |   0   |    1   |



つまり、ひとつひとつの連続しない物を、列ごとに分けて、カウントする方法である。
これを行うことによって、ひとつひとつの動物を連続する数としてではなく、独立する値として、扱うことができるのである。


##コード

```python:

>>>
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
>>> enc.n_values_
array([2, 3, 4])
>>> enc.feature_indices_
array([0, 2, 5, 9])
>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])

```
Retrieved from [公式ドキュメント](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html)


#LabelEncoder の必要性

## LabelEncoder とはなんなのか。

上記で使った表をもう一回ここで出してみる。
この表は、 Tiger, Panda などの動物の名前を、番号に置き換えている。
この置き換えの動作をするのが、 LabelEncoder である。
だから、LabelEncoder を適応した後に、 OneHotEncoder を適応する。


| Animal       |    Transform to Numbers    |
|:-----------------|:------------------:|
| Tiger            |             0 |      
| Panda           |            1 |      
| Cat            |              2 |
| Human              |               3 |
| Python            |             4 |


##コード

```python:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])

le.transform(["tokyo", "tokyo", "paris"]) 
>>>array([2, 2, 1]...)

list(le.inverse_transform([2, 2, 1]))
>>>['tokyo', 'tokyo', 'paris']

#ちなみに、df のある列を使うときは下記のようになる
# df の City という列に LabelEncoder を適応している。

df.City = le.fit_transform(df.City)
# または
df.City = le.fit_transform(df['City'].values)

# 元に戻すときは、

df.City = le.inverse_trainsform(df.City)


```

これが[公式ドキュメント](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html)

#Pandas の pd.get_dummies 関数

## get_dummies は OneHotEncoder のようなやつ。

筆者は、うまく LabelEncoder を使えたものの、 OneHotEncoder はうまく使うことができませんでした。なので、調べに調べた結果、Pandas の get_dummies がほぼ同じことをしてくれるらしいとの情報を入手しました。　ちなみに、 OneHotEncoder 教えてくれる方、いい感じにまとめられているサイトを知っている方がいらっしゃいましたら、ぜひ教えてください。
で、get_dummies は categorical value の要素ごとに列を作って、OneHotEncoder と同じ役割を果たしてくれるようです。
雰囲気は下記のような感じです。



| Tiger    |   Panda | Cat | Human | Python |
|:--------:|:-------:|:---:|:-----:|:------:|
| 1        |     0   |  0  |   0   |    0   |
| 0        |     1   |  0  |   0   |    0   |
| 0        |     0   |  1  |   0   |    0   |
| 0        |     0   |  0  |   1   |    0   |
| 0        |     0   |  0  |   0   |    1   |





```python: 

df = pd.get_dummies(df, columns = ['animal'])

# animal の要素ごとに列を作り、0,1 で表記してくれる。

```

こちら[公式ドキュメント](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html)



#違いをいい感じにまとめてあるやつ　（英語）

LabelEncoder と OneHotEncoder の違いをいい感じにまとめてくれています。
[これ](https://datascience.stackexchange.com/questions/9443/when-to-use-one-hot-encoding-vs-labelencoder-vs-dictvectorizor)