sklearnをpandasから使う場合の便利ツール

## sklearn-pandas とは？
pandasのDataFlameからsklearnのモデルやpiplineを使う際に若干の煩わしさが残っていたが、最近はsklearn-pandasというパッケージが開発されており扱い易くなっているようだ。

https://github.com/scikit-learn-contrib/sklearn-pandas

このパッケージを使うと、例えば次のようなことができるようだ。
* pandasのDataFlameをそのまま入力できて、なおかつ、出力もDataFlameで取り出せる。
* 特定のコラム（特徴量）のみへの処理をsklearnのmodelと同様の形式で定義できる。
* 従来より柔軟なpipelineを作成できる。　

従来、pandasのDataFlameをsklearnの適当なmodelで学習する場合、DataFlameの特定のコラムのみを抽出し、エンコーディング、欠損補完、スケーリング等を行った後、np.arrayとして、sklearnのmodel(pipline等)に渡す必要があった。
また、sklearnのmodel.transform()や、model.predict()等で出力された予測、推論の結果はnp.arrayで出力される為、pandasのDataFlameに変換し,その他の情報と結合をする必要があった。このため解析のフローがコーディングがまとまりにくく、簡潔さが損なわれていた。
sklearn-pandasのDataFlameMapperを使えば、結果がpandasとして取得できるだけでなく、入力や出力に関する処理もsklearnのmodelと同様な定義が可能になる。

# install

下記でインストール可能。

```shell
pip install sklearn-pandas
```

# DataFlameMapperの利用例

#### 1. dfを使いPCAして、結果をDataFlameで取得する
DataFlameMapperを使うと、read_csv等で読み込んだDataFlameは解析に用いない行はそのままで、必要なところだけ計算してくれる。もちろんモデルはPCAでなくても良い。
modelの入出力にDataFlameを使いたい場合、下記2つのオプションだけ設定すれば良い。

* input_df = True
* df_out = True

ここでは、もう一つのオプションとして、以下を指定うる。
* default = None
default=Noneの場合は、dfに含まれるその他の情報も保持されて、outputに出力される。
デフォルトはdafault=Falseで、この場合は明示的に指定されていないdfのコラムは除去される。他に、例えばdefault=StandardScaler()のようにメソッドを指定された場合は、明示的に指定されていないコラムはすべてStandardScaler()が適用される。
下記がサンプルになる。

```python
import pandas as pd
from sklearn_pandas import DataFrameMapper
from sklearn.pipeline import Pipeline 

# --- sample data ------
df = pd.DataFrame({'pet':     ['cat', 'dog', 'dog', 'fish', 'cat', 'dog', 'cat', 'fish'],
                     'children': [4., 6, 3, 3, 2, 3, 5, 4],
                     'salary':   [90., 24, 44, 27, 32, 59, 36, 27]})
#
# DataFlameMapper利用例1
#
# 引数はタプルのリスト[('column名',そのcolumnに適用する各メソッド名)]で指定
# します。
#
# 'children','salary'の列（コラム）で主成分分析を行い、次元圧縮して取り出す。
#
# default=None: 処理しない列（コラム）を残す。
# 入出力をpandas DataFlameにするかどうかのオプション
# input_df=True
# df_out=True

from sklearn.decomposition import PCA
# childrenとsalaryのみにPCAをかけ、１つの特徴量取り出します。
model1 = DataFrameMapper([
    (['children', 'salary'], PCA(1))
                        ],default=None,input_df=True,df_out=True)

model1.fit_transform(df).head()
```
出力は以下のようになり、PCAの結果がDataFlameの形式で取得できることが確認できる。

|   |   |   |  
|:--|:--|:--|
|   | children_salary | pet |
| 0 | 47.621951 | cat |
| 1 | -18.390777 | dog |
| 2 | 1.630377 | dog |
| 3 | -15.369180 | fish |
| 4 | -10.362085 | cat |

#### 2. 特定のcolumnのみ処理するモデルを作成する。

```python
#
# DataFlameMapper利用例 2
# 
# Githubと同一の例です。
# dfの特定のcolumnにLabelBinarizerを作用させOneHotEncodingを行います。
# pandasにはpd.get_dummies(df)が用意されていますので、このような使い方は
# 適切かどうか微妙ですが、使い方は参考になるはずです。
# 
from sklearn.preprocessing import LabelBinarizer

# model2 : 
model2=DataFrameMapper([
                     ('pet',LabelBinarizer()),
                    ],default=None,input_df=True,df_out=True)

model2.fit_transform(df).head()
```
.fit_transform()で次のようなDataFlameの出力が直接得られます。

|  | pet_cat | pet_dog | pet_fish | children | salary |
|--:|--:|--:|--:|--:|--:|
| 0 | 1 | 0 | 0 | 4.0 | 90.0 |
| 1 | 0 | 1 | 0 | 6.0 | 24.0 |
| 2 | 0 | 1 | 0 | 3.0 | 44.0 |
| 3 | 0 | 0 | 1 | 3.0 | 27.0 |
| 4 | 1 | 0 | 0 | 2.0 | 32.0 |


#### その他　CategoricalImputer
この他、sklearn_pandasのCategoricalImputer()を使えば.fit_transform()でデータの欠損を修正できる。

以上