[scikit-learn]OneHotEncoderの使い方

指定した配列を(0,1)の2値で構成される配列に変換するためのクラス。

機械学習を実行する際の前処理として、カテゴリ変数を処理するために利用する。
例えば、

```math
\begin{pmatrix}
a & c\\
b & c\\
a & d
\end{pmatrix}
```

のようなデータを

```math
\begin{pmatrix}
1 & 0 & 1 & 0 \\
0 & 1 & 1 & 0 \\
1 & 0 & 0 & 1 \\
\end{pmatrix}
```
といった形に変換できる。

## コンストラクタ
主なパラメータは以下の通り。
####categories
デフォルト値は'auto'
 
'auto'：列に含まれる値から、カテゴリ値を自動的に抽出し決定する。

list：リストのリスト。
　1) 各リスト内の値は文字列か数値で、同一リスト内の値は型が統一されている必要あり。
　2) リストを数値で構成している場合は、昇順ソートされていないとNG。
　3) i列目に含まれる値がcategories[i]に含まれていない場合の挙動は、handle_unknownの設定次第。（※1）
　4) categories[i]に含まれている値が、i列目に含まれていない場合は問題なし。
　　この場合、結果として得られる配列に全て0の列ができるだけ。
　5) リストの長さは、配列の列数と同じとする必要がある。

####sparse
transform、fit_transformの実行結果の型を指定する。デフォルト値はTrue。
・True  : 2次元のscipy.sparse.csr.csr_matrix
・False : 2次元のnumpy.ndarray

####handle_unknown 
※1に記載した部分の挙動に影響する。デフォルト値は'error'。
'error'：※1のケースにて、処理が異常終了する。
'ignore'：※1のケースにて、categories[i]に含まれていないカテゴリ値を無視する。

## メソッド
#### set_params( **params )
エンコーダが適用するパラメータを設定（または変更）する。

### get_params()
エンコーダに設定されているパラメータを取得する。

#### fit_transform(X[, y])
Xを変換した行列を取得する。

## サンプルコード
####サンプル1：sparse=Falseの場合

```python
import sklearn.preprocessing as sp
import numpy as np
import pandas as pd

df = pd.DataFrame( ['c','b','a'] )
enc = sp.OneHotEncoder( sparse=False )

# 結果(ndarray)
print( enc.fit_transform( df ) )
[[0. 0. 1.]
 [0. 1. 0.]
 [1. 0. 0.]]
```

OneHotEncoderのコンストラクト時にcategoriesを指定していないので、取り扱うカテゴリ変数としは"fit(あるいはfit_transform)実行時の入力に含まれる値"をカテゴリ変数として選択します。
また、どの列にどのカテゴリ変数を対応させるか、その順序は文字列の場合は辞書式での"昇順ソート結果"となるようです。

このため、上記の例では1列目／2列目／3列目が、それぞれ「入力配列の各要素がaかどうか」「同bかどうか」「同cかどうか」を表現することになります。

---
####サンプル2：sparse=Trueの場合

```python
df = pd.DataFrame( ['c','b','a'] )
# パラメータ変更
enc.set_params( sparse=True )

# 結果(csr_matrix)
print( enc.fit_transform( df ) )
  (0, 2)	1.0
  (1, 1)	1.0
  (2, 0)	1.0
```
csr_matrix型を結果として取得するので、保持している情報が簡素になります。

---
####サンプル3：カテゴリ指定(文字列)
```python

df = pd.DataFrame( ['c','b','a'] )
# 入力配列には'c'を含んでいるが、指定するcategoriesには含めていない
enc = sp.OneHotEncoder( categories=[['a','b']] )
enc.fit_transform( df )

# エラー発生
ValueError: Found unknown categories ['c'] in column 0 during fit

# handle_unknownにignoreを指定すれば処理は正常終了。
enc = sp.OneHotEncoder( categories=[['a','b']], handle_unknown='ignore', sparse=False )
print( enc.fit_transform( df ) )

# 結果（カテゴリ値が'a','b'以外の場合、全ての値が0の行に変換される）
[[0. 0.]
 [0. 1.]
 [1. 0.]]

# 入力配列には'd'を含んでいないが、指定するcategoriesには含めている（これは問題なし）。
enc = sp.OneHotEncoder( categories=[['d','b','c','a']],sparse=False )

# 結果
print( enc.fit_transform( df ) )
[[0. 0. 1. 0.]
 [0. 1. 0. 0.]
 [0. 0. 0. 1.]]

```

結果の1列目は「入力配列のi行目の値が'd'の場合1」となりますが、入力配列には値として'd'を持つ行が存在しないため、結果の1列目はすべての値が0となっています。
また、categoriesの指定内容が昇順ソートになっていませんが、特に問題はありません。

---
####サンプル4：カテゴリ指定（数値）
```python
# 正常に動作する例
df = pd.DataFrame( [1,3,5,1,3] )
enc = sp.OneHotEncoder( categories='auto', sparse=False )
print( enc.fit_transform( df ) )

# 結果
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [1. 0. 0.]
 [0. 1. 0.]]

# カテゴリ指定も可能（入力配列にない値をカテゴリ指定に含めても問題なし）
enc.set_params( categories=[[1,2,3,4,5]] )
print( enc.fit_transform( df ) )

# 結果
[[1. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0.]]

# カテゴリ指定時に数値を指定する場合は、昇順ソートしていないとエラー
enc.set_params( categories=[[1,3,4,2,5]] )
print( enc.fit_transform( df ) )

# 結果（fit_transform実行時にエラー発生）
ValueError: Unsorted categories are not supported for numerical categories
```

##参考サイト
-https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html