Kaggleタイタニックで色んな機械学習アルゴリズムを試してみる（非線形サポートベクターマシン編）

# 前回の記事
タイタニック号データを使って、基本的な機械学習アルゴリズムの練習を行っています。
前回は**線形サポートベクターマシン**を扱いました↓
https://qiita.com/hanata/items/22434accf1483958c9f9

今回は**非線形サポートベクターマシン**で予測を行います。

# 今回の流れ
0. 使用する変数
1. データ前処理
2. GridSearchCVでハイパーパラメータ探索 ←new!
3. モデル作成、予測
4. 一部データを標準化してモデル作成、予測
5. 一部データを正規化してモデル作成、予測
6. まとめ

今回はハイパーパラメータをGridSearchCVで決めます。
さらに、**SVMを扱うときは各特徴量の変位が同スケールにする必要がある** ということで、スケール変換したデータを使用したモデル作成、予測も行いたいと思います。

# 1. 使用する変数
前回と同じです。

* Pclass…チケットのクラス
* Sex…性別
* Age…年齢
* SibSp…タイタニックに乗船している兄弟or配偶者の数
* Parch…タイタニックに乗船している親or子供の数
* Embarked…タイタニックに乗船した港

以上の6つを使用します。SexとEmbarkedはダミー変数化します。

# 2. データ前処理
こちらも前回同様です。
訓練データ：Ageの欠損値は中央値、Embarkedの欠損値はSで埋めています。
テストデータ：Ageの欠損値は中央値、Fareの欠損値は中央値で埋めています。

# 3. GridSearchCVでハイパーパラメータ探索
前回はfor文でパラメータの調整を行っていたのですが、今回はGridSearchCVを使ってパラメータの調整を行いました。

```python

from sklearn.model_selection import GridSearchCV

param = {
    'C': [100, 10, 1, 0.1, 0.01, 0.001],
    'kernel': ['rbf'],
    'gamma':[100, 10, 1, 0.1, 0.01, 0.001]
}

gscv = GridSearchCV(SVC(), param, cv=5)
gscv.fit(x_data, y_data)
gscv.best_estimator_
```

GridSearchCVの引数に、モデル・パラメータが入った辞書型・交差検証の回数を指定するだけです。めっちゃ簡単ですね。
gscv.best_estimator_で最も良いスコアを出したパラメータを取り出すことができます。

```python
# output
SVC(C=100, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
```
ということで、**C=100,gamma=0.001**でやってみます。

# 4.モデル作成、予測
一旦、訓練データを使って精度の確認をしてみましょう。

```python

svm = SVC(kernel='rbf', C=100, gamma=0.001)
scores = cross_val_score(svm, x_data, y_data, cv=5)
print('平均すこあ：{}'.format(np.mean(scores)))

### output
平均すこあ：0.7958140392690954
```

ふむ。なんとも言えませんが、予測してみましょう。

```python
# 実際に予測して出力
svm.fit(x_data, y_data)
y_pred = svm.predict(test_x)
ans = pd.concat([p_id, pd.Series(y_pred)], axis=1)
ans.to_csv('ans_svm.csv', index=False)
```

さあ結果は…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405491/b1d6b03c-81a5-5b0a-af8e-9e8fa60b8cb9.png)

なんと**前回の線形サポートベクターマシンと全く同じスコアです**。(^.^;

# 5. 一部データを標準化してモデル作成、予測
おかしいなと思い、本を読んでみると、**SVMは各特徴量が同スケールじゃないとダメよ～**と書いてありました。なるほど。
今回使用する特徴量のうち、AgeとFareは明らかにスケールが違います。というわけで、この2つの特徴量を標準化していきます。

```python
x_norm = x_data.copy()
# age標準化
s = x_norm['Age']
x_norm['Age'] = (s - s.mean()) / s.std()

# fare標準化
t = x_norm['Fare']
x_norm['Fare'] = (t - t.mean()) / t.std()
x_norm.head()
```
<div class="output_subarea output_html rendered_html output_result"><div>
<style scoped="">
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Pclass</th>
      <th>Sex_male</th>
      <th>Age</th>
      <th>SibSp</th>
      <th>Parch</th>
      <th>Fare</th>
      <th>Embarked_Q</th>
      <th>Embarked_S</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>3</td>
      <td>1</td>
      <td>-0.565419</td>
      <td>1</td>
      <td>0</td>
      <td>-0.502163</td>
      <td>0</td>
      <td>1</td>
    </tr>
    <tr>
      <th>1</th>
      <td>1</td>
      <td>0</td>
      <td>0.663488</td>
      <td>1</td>
      <td>0</td>
      <td>0.786404</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>3</td>
      <td>0</td>
      <td>-0.258192</td>
      <td>0</td>
      <td>0</td>
      <td>-0.488580</td>
      <td>0</td>
      <td>1</td>
    </tr>
    <tr>
      <th>3</th>
      <td>1</td>
      <td>0</td>
      <td>0.433068</td>
      <td>1</td>
      <td>0</td>
      <td>0.420494</td>
      <td>0</td>
      <td>1</td>
    </tr>
    <tr>
      <th>4</th>
      <td>3</td>
      <td>1</td>
      <td>0.433068</td>
      <td>0</td>
      <td>0</td>
      <td>-0.486064</td>
      <td>0</td>
      <td>1</td>
    </tr>
  </tbody>
</table>
</div></div>

先程と同様に、GridSearchCVでベストなパラメータを調べます。
コードは割愛しますが、今度は**C=10,gamma=0.1**が最適のようです。
精度がどんなもんか見てみましょう。

```python
svm = SVC(kernel='rbf', C=10, gamma=0.1)
scores = cross_val_score(svm, x_norm, y_data, cv=5)
print('平均すこあ：{}'.format(np.mean(scores)))

### output
平均すこあ：0.8226929406423787
```

さっきより上がっていますね！テストデータで予測、スコアを見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405491/059c6625-95b0-ccc1-a6eb-1de7cb9ebfae.png)


結果は**0.77990**。ベストスコアです！

# 6. 一部データを正規化してモデル作成、予測
最後に正規化ver.を試してみたいと思います。正規化の処理↓

```python
x_sd = x_data.copy()

s = x_sd['Age']
x_sd['Age'] = (s - s.min()) / (s.max() - s.min())
t = x_sd['Fare']
x_sd['Fare'] = (t - t.min()) / (t.max() - t.min())
```
グリッドサーチの結果、最適パラメータは**C=10,gamma=0.1**でした。

さて結果は…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405491/673467d7-48b8-fb63-2b8d-82f05efce8e0.png)

何もしないときよりは良いですが、標準化した場合とそこまで差はないですね。

# 7. まとめ
データスケールをいじらない場合：C=100,gamma=0.001でスコア：0.76076
ageとfareを標準化した場合：C=10,gamma=0.1でスコア：0.77990
ageとfareを正規化した場合：C=10,gamma=0.1でスコア：0.77511

大きな差はないものの、やはり標準化や正規化を行った方が良さそうですね。
次回はサポートベクターマシンの理論について、記事を書こうと思います。