SVMの各カーネルにおけるハイパラメータと識別精度を比較する

はじめに

 本記事では、SVMを使用する際にもっとも適したカーネルを選択する方法として、グリッドサーチと交差検証によって、カーネルのバンド幅gammaと正則化パラメータCを決定し、各カーネルのもっとも良いパラメータを比較する。
 データセットはアヤメのデータセットを使用する。

データセットのロード

# 前処理 データセットのダウンロード

%matplotlib inline

from sklearn import datasets
import numpy as np

# アヤメデータセットを用いる
iris = datasets.load_iris()
# データセットのdict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])

# 例として、3,4番目の特徴量の2次元データで使用
# iristデータの特徴量['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']の3、4番目を使用
x = iris.data[:, [2,3]]

# クラスラベルを取得
# target_names : ['setosa' 'versicolor' 'virginica']
y = iris.target

交差検証・グリッドサーチの実装

gammaとCのパラメータは0.001, 0.01, 0.1, 1, 10, 100について探索して、適したパラメータを決定します。

# モデルの学習~精度評価
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
from mlxtend.plotting import plot_decision_regions

x_trainval, x_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0)
x_train, x_valid, y_train, y_valid = train_test_split(x_trainval, y_trainval, random_state=0)

kernel_str = ["linear", "poly", "rbf", "sigmoid"]
param_list = [0.001, 0.01, 0.1, 1, 10, 100]

for k in kernel_str:
    print(k)
    best_score = 0
    best_parameters = {}
    # 交差検証を用いたグリッドサーチ
    for gamma in param_list:
        for C in param_list:
            # SVCのインスタンス生成
            model = SVC(kernel = k, gamma=gamma, C=C, random_state=None)
            # 交差検証 パラメータcvで分割方法を設定
            scores = cross_val_score(model, x_trainval, y_trainval, cv=5)
            # 交差検証による評価値の平均
            score = np.mean(scores)
            if score>best_score:
                best_score = score
                best_parameters = {'gamma' : gamma, 'C' : C}
    
    # もっともスコアの高いパラメータで識別器をインスタンス
    model = SVC(kernel=k, **best_parameters)
    # best_parametersにおける識別器を作成
    model.fit(x_trainval, y_trainval)
    # testデータの評価
    test_score = model.score(x_test, y_test)
    
    print('Best score on validation set: {}'.format(best_score))
    print('Best parameters: {}'.format(best_parameters))
    print('Test set score with best parameters: {}'.format(test_score))

実行結果は以下のようになる。

linear
Best score on validation set: 0.9731225296442687
Best parameters: {'gamma': 0.001, 'C': 1}
Test set score with best parameters: 0.9736842105263158
poly
Best score on validation set: 0.9731225296442687
Best parameters: {'gamma': 0.01, 'C': 100}
Test set score with best parameters: 0.9736842105263158
rbf
Best score on validation set: 0.9731225296442687
Best parameters: {'gamma': 0.1, 'C': 10}
Test set score with best parameters: 0.9736842105263158
sigmoid
Best score on validation set: 0.9553359683794467
Best parameters: {'gamma': 0.001, 'C': 100}
Test set score with best parameters: 0.9736842105263158