非線形SVC(分類)のハイパーパラメータとチューニング

# はじめに
　乳癌の腫瘍が良性であるか悪性であるかを判定するためのウィスコンシン州の乳癌データセットについて、線形SVCとハイパーパラメータのチューニングにより分類器を作成する。データはsklearnに含まれるもので、データ数は569、そのうち良性は212、悪性は357、特徴量は30種類ある。

シリーズ

- [線形重回帰による決定係数の算出とモデルの選択](https://qiita.com/FujiedaTaro/items/4ef757370ca19abe783c)
- [線形重回帰による決定係数の算出とモデルの選択 part_2](https://qiita.com/FujiedaTaro/items/a7a23ce321f7733ae9cf)
- [単回帰分析による寄与率の算出](https://qiita.com/FujiedaTaro/items/090bad07672c322bceeb)
- [線形回帰と特徴量の絞り込み](https://qiita.com/FujiedaTaro/items/3fd874ae91b511eb1d1f)
- [ロジスティック回帰(分類)とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/5784eda386146f1fd6e7)
- [線形SVC(分類)とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/3e469688ad6f0dca62c0)
- [非線形SVC(分類)とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/e5583f8767173e6a6f9a)
- [決定木とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/47e06c758b451cbda412)
- [決定木とハイパーパラメータのチューニング２](https://qiita.com/drafts/0cc107bd69e9a0d2ce38/edit)

# サポートベクタマシンとは
>教師あり学習を用いるパターン認識モデルの一つである。分類や回帰へ適用できる。1963年に Vladimir N. Vapnik, Alexey Ya. Chervonenkis が線形サポートベクターマシンを発表し、1992年に Bernhard E. Boser, Isabelle M. Guyon, Vladimir N. Vapnik が非線形へと拡張した。

>サポートベクターマシンは、現在知られている手法の中でも認識性能が優れた学習モデルの一つである。サポートベクターマシンが優れた認識性能を発揮することができる理由は、未学習データに対して高い識別性能を得るための工夫があるためである。
（wikipediaより）

# 線形SVCのハイパーパラメータ
詳細は以下を参照されたい。
[sklearn.svm.SVC](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html)

|ハイパーパラメータ|選択肢|default|
|:---|:---|:---|
|C|float型|1|
|kernel|linear、poly、rbf、sigmoid、precomputed|rbf|
|degree|float型|3|
|gamma|float型|auto|
|coef0|float型|0|
|Cshrinking|bool型|True|
|probability|bool型|False|
|tol|float型|0.001|
|cache_size|float型|-|
|class_weight|辞書型、balanced|1(全クラス)|
|verbose|bool型|False|
|max_iter|int型|-1|
|decision_function_shape|ovo、ovr|ovr|
|random_state|int型|None|

# 手順
- 乳癌データの読み込み
- 条件設定
- トレーニングデータ、テストデータの分離
- グリッドサーチ
- ランダムサーチ
- ハイパーパラメータをチューニングしない場合との比較
# pythonによる実装

```python
%%time
import scipy.stats
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score

#乳癌データの読み込み
cancer_data = load_breast_cancer()

#条件設定
max_score = 0
SearchMethod = 0
SVC_grid = {SVC(): {"C": [10 ** i for i in range(-5, 6)],
                    "kernel": ["linear", "rbf", "sigmoid"],
                    "decision_function_shape": ["ovo", "ovr"],
                    "random_state": [i for i in range(0, 101)]
                   }}
SVC_random = {SVC(): {"C": scipy.stats.uniform(0.00001, 1000),
                    "kernel": ["linear", "rbf", "sigmoid"],
                    "decision_function_shape": ["ovo", "ovr"],
                    "random_state": scipy.stats.randint(0, 100)
                     }}

#トレーニングデータ、テストデータの分離
train_X, test_X, train_y, test_y = train_test_split(cancer_data.data, cancer_data.target, random_state=0)

#グリッドサーチ
for model, param in SVC_grid.items():
    clf = GridSearchCV(model, param)
    clf.fit(train_X, train_y)
    pred_y = clf.predict(test_X)
    score = f1_score(test_y, pred_y, average="micro")
    
    if max_score < score:
        max_score = score
        best_param = clf.best_params_
        best_model = model.__class__.__name__

#ランダムサーチ
for model, param in SVC_random.items():
    clf =RandomizedSearchCV(model, param)
    clf.fit(train_X, train_y)
    pred_y = clf.predict(test_X)
    score = f1_score(test_y, pred_y, average="micro")
    
    if max_score < score:
        SearchMethod = 1
        max_score = score
        best_param = clf.best_params_
        best_model = model.__class__.__name__
    
if SearchMethod == 0:
    print("サーチ方法:グリッドサーチ")
else:
    print("サーチ方法:ランダムサーチ")
print("ベストスコア:{}".format(max_score))
print("モデル:{}".format(best_model))
print("パラメーター:{}".format(best_param))

#ハイパーパラメータを調整しない場合との比較
model = SVC()
model.fit(train_X, train_y)
score = model.score(test_X, test_y)
print("")
print("デフォルトスコア:", score)
```
# 結果

```
サーチ方法:グリッドサーチ
ベストスコア:0.958041958041958
モデル:SVC
パラメーター:{'C': 100, 'decision_function_shape': 'ovo', 'kernel': 'linear', 'random_state': 0}

デフォルトスコア: 0.629370629371
Wall time: 5h 49min 30s
```
# おわりに
　ハイパーパラメータのチューニングにより、デフォルトよりも高い正解率を得ることができた。