グリッドサーチで少し無理をしていろいろなパラメータの組み合わせを検討する

##はじめに
この記事は[MicroAd Advent Calendar 2017](https://qiita.com/advent-calendar/2017/microad)の22日目の記事です。

##背景･目的
機械学習の処理でチューニングするパラメータの数は通常限られています。そこで、今回は様々なチューニングをためしてみようと思います。そして、可能であればパラメータの組み合わせと性能の関連性について検討してみようと思います。

##お題
タイタニックの乗客生存予測

##環境
MacBook Air(プロセッサ:1.7GHz Intel Core i7, メモリ:8GB)
python 3.6.1
jupyter notebook 5.0.0

##プログラム
本来的には様々なデータを検討する必要がありますが、上記の問題設定で簡単な傾向を捉えてみたいとおもいます。今回チューニング対象とする機械学習のロジックは下記の3種です。それぞれの説明についてはリンクをたどっていただければいいかなと思います。

-K neighbors classifier(KNN)
[K近傍法(多クラス分類)](https://qiita.com/yshi12/items/26771139672d40a0be32)
-Random forest classifier(RFC)
[決定木とランダムフォレスト](https://qiita.com/yshi12/items/6d30010b353b084b3749)
-Gradient boosting classifier(GBC)
[勾配ブースティングについてざっくりと説明する](http://smrmkt.hatenablog.jp/entry/2015/04/28/210039)

パラメータのチューニングはグリッドサーチで行っています。チューニングに関する説明は本家のチュートリアルがわかりやすいかと思います。
[3.2. Tuning the hyper-parameters of an estimator](http://scikit-learn.org/stable/modules/grid_search.html)

下記プログラムを実行し、各ロジックのパラメータをチューニングした場合に性能がどの程度変化するか検討します。


```python3
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score
from IPython.display import display

#データのインポート
titanic_raw = pd.DataFrame(sns.load_dataset('titanic'))

#データ型の明示的な変換
df=titanic_raw.astype({'survived':'int',
                    'pclass':'int',
                    'sex':'object',
                    'age':'object',
                    'sibsp':'int',
                    'parch':'int',
                    'fare':'float',
                    'embarked':'object',
                    'class':'object',
                    'who':'object',
                    'adult_male':'object',
                    'deck':'object',
                    'embark_town':'object',
                    'alive':'object',
                    'alone':'object'})

#説明変数(X)と目的変数(y)の分離と不要特徴量の削除
X = df.drop(['survived','alive'],axis=1)
y = df.loc[:,['survived']]

#カテゴリカル変数の数値への変換(one hot encodingの実施)
ohe_columns = ['sex','embarked','class','who','adult_male','deck','embark_town','alone']
X_ohe = pd.get_dummies(X, dummy_na=True,columns=ohe_columns)
X_ohe.describe

#連続欠損値補完
from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values='NaN',strategy='mean',axis=0)
imputer.fit(X_ohe)
X_new_columns = X_ohe.columns.values
#print(X_new_columns)
X_new = pd.DataFrame(imputer.transform(X_ohe),columns=X_new_columns)
print(X_new.shape)
#display(X_new)

#PIPELINEの作成
pipeline_knn = Pipeline([('scl',StandardScaler()),('est',KNeighborsClassifier())])
pipeline_RFC = Pipeline([('scl',StandardScaler()),('est',RandomForestClassifier(random_state=1))])
pipeline_GBC = Pipeline([('scl',StandardScaler()),('est',GradientBoostingClassifier(random_state=1))])

#パラメータのチューニング
from sklearn.model_selection import GridSearchCV

param_gs_knn ={'est__n_neighbors':[1,2,3,4,5,],
              'est__weights':['uniform','distance'],
              'est__algorithm':['auto','ball_tree','kd_tree','brute'],
              'est__leaf_size':[1,10,20,30,40,50],
              'est__p':[1,2]}

param_gs_RFC={'est__n_estimators':[5,10,20,50,100],
             'est__criterion':['gini','entropy'],
             'est__max_features':['auto','sqrt','log2'],
             'est__max_depth':[1,2,3,4,5],
             'est__min_samples_split':[0.1,0.3,0.5,0.7,0.9],
             'est__min_samples_leaf':[1,2,4,6,8],
             'est__bootstrap':[True,False]}

param_gs_GBC={'est__loss':['deviance','exponential'],
             'est__learning_rate':[0.001,0.01,0.1],
             'est__n_estimators':[5,10,50,100,500],
             'est__max_depth':[1,2,3,4,5],
              'est__criterion':['friedman_mse','mae','mse'],
              'est__min_samples_split':[0.1,0.3,0.5,0.7,0.9],
              'est__min_samples_leaf':[1,2,4,6,8] }

pipes=[pipeline_RFC,pipeline_GBC]
params=[param_gs_RFC,param_gs_GBC]

for elem in zip(pipes, params):
    print('----------------------------------------------------------------------------------------------')
    pipe, param = elem[0], elem[1]
    print('探索空間:%s' % param)
    gs = GridSearchCV(estimator=pipe, param_grid=param, scoring='roc_auc',cv=5,n_jobs=-1)
    gs = gs.fit(X_new, y.as_matrix().ravel())
    display(pd.DataFrame(gs.cv_results_).sort_values(by=['rank_test_score'],ascending=True))
    print('#############################')
```


##結果
欲張りすぎて、すぐ結果がでなかったです。。。
結果がでたら、すぐにまとめます。。。