0
0

More than 3 years have passed since last update.

カーネルSVM(make_circles)

Last updated at Posted at 2020-11-20

■ はじめに

今回は、簡単なカーネルSVMの実装をまとめていきます。

【対象とする読者の方】
・カーネルSVMの簡単なコードを学びたい方
・理論は分からないが、実装を見てイメージをつけたい方 など

■ カーネルSVMの手順

次の7つのSTEPで進めます。

  1. モジュールの用意
  2. データの準備
  3. データの可視化
  4. モデルの作成
  5. モデルのプロット
  6. 予測値の出力
  7. モデルの評価

1. モジュールの用意

最初に、必要なモジュールをインポートしておきます。


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.datasets import make_circles
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, roc_auc_score
from sklearn.metrics import accuracy_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report


2. データの準備

今回はsklearnに用意されている、make_circlesというデータセットを使用します。

最初にデータの取得をし、標準化を行ってから分割します。


X , y = make_circles(n_samples=100, factor = 0.5, noise = 0.05)

std = StandardScaler()
X = std.fit_transform(X)

標準化は、例えば2桁と4桁の特徴量(説明変数)があった際に、後者の影響が大きくなってしまうため
全ての特徴量に対して平均が0・分散は1になるように調整して、スケールを揃えています。


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state=123)

print(X.shape)
print(y.shape)
# (100, 2)
# (100,)

print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
# (70, 2)
# (70,)
# (30, 2)
# (30,)


3. データの可視化

カーネルSVMで、二値分類をする前のデータプロットを見ておきます。


fig, ax = plt.subplots()

ax.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], c = "red", label = 'class 0' )
ax.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1], c = "blue", label = 'class 1')

ax.set_xlabel('X0')
ax.set_ylabel('X1')
ax.legend(loc = 'best')

plt.show()

class 0 (y_train ==0) に対応する特徴量(X0 を横軸, X1 を縦軸):赤
class 1 (y_train ==1) に対応する特徴量(X0 を横軸, X1 を縦軸):青
image.png
上記は少し冗長なコードとなっていますが、簡潔に短く書くことも可能です。


plt.scatter(X_train[:, 0], X_train[:, 1], c = y_train)
plt.show()

image.png

4. モデルの作成

カーネルSVMのインスタンスを作成し、学習させます。


svc = SVC(kernel = 'rbf', C = 1e3, probability=True)
svc.fit(X_train, y_train)

今回はすでに線形分離(1本の直線で分ける)が不可能なため、引数に kernel = 'rbf' を設定しています。

また C はハイパーパラメータで、出力数値やプロットを見ながら自身で調整していくものです。

5. モデルのプロット

カーネルSVMのモデルが作成できたので、プロットして確認します。

前半は、先ほどの散布図コードと全く同じです。
それ以降は少し難しいですが、そのままペーストするだけで、他データでもプロットできます。
(多少の微調整は必要となります)


fig, ax = plt.subplots()

ax.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], c='red', marker='o', label='class 0')
ax.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1], c='blue', marker='x', label='class 1')

xmin = -2.0
xmax = 2.0
ymin = -2.0
ymax = 2.0

xx, yy = np.meshgrid(np.linspace(xmin, xmax, 100), np.linspace(ymin, ymax, 100))

xy = np.vstack([xx.ravel(), yy.ravel()]).T
p = svc.decision_function(xy).reshape(100, 100)  
ax.contour(xx, yy, p, colors='k', levels=[-1, 0, 1], alpha=1, linestyles=['--', '-', '--'])

ax.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1],
           s=250, facecolors='none', edgecolors='black')

ax.set_xlabel('X0')
ax.set_ylabel('X1')

ax.legend(loc = 'best')

plt.show()

image.png

6. 予測値の出力

作成したモデルで、分類の予測値を出していきます。


y_proba = svc.predict_proba(X_test)[: , 1]
y_pred = svc.predict(X_test)

print(y_proba[:5])
print(y_pred[:5])
print(y_test[:5])

# [0.99998279 0.01680679 0.98267058 0.02400808 0.82879465]
# [1 0 1 0 1]
# [1 0 1 0 1]


7. 性能評価

ROC曲線を用いて、AUCの値を求めます。


fpr, tpr, thresholds = roc_curve(y_test, y_proba)
auc_score = roc_auc_score(y_test, y_proba)
plt.plot(fpr, tpr, label='AUC = %.3f' % (auc_score))
plt.legend()
plt.title('ROC curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.grid(True)

print('accuracy:',accuracy_score(y_test, y_pred))
print('f1_score:',f1_score(y_test, y_pred))

# accuracy: 1.0
# f1_score: 1.0

image.png


classes = [1, 0]
cm = confusion_matrix(y_test, y_pred, labels=classes)

cmdf = pd.DataFrame(cm, index=classes, columns=classes)

sns.heatmap(cmdf, annot=True)
print(classification_report(y_test, y_pred))

'''
              precision    recall  f1-score   support

           0       1.00      1.00      1.00        17
           1       1.00      1.00      1.00        13

    accuracy                           1.00        30
   macro avg       1.00      1.00      1.00        30
weighted avg       1.00      1.00      1.00        30

'''

image.png

■ 最後に

上記1~7の手順をもとに、カーネルSVMのモデル作成・性能評価ができました。

初学者の方にとって、少しでもお役に立てたようでしたら幸いです。

■ 参考文献

Pythonによるあたらしいデータ分析の教科書

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0