はじめに
この記事では、サポートベクターマシン(SVM)の一種であるカーネルSVMを使用して、非線形に分離可能なデータセットに対する分類問題を解決する方法について解説します。Pythonを使った実装例を通じて、初心者でもカーネルSVMの概念を理解し、実際にコードを書いてみることができるようになることを目指します。
カーネルSVMは、データが線形に分離不可能な場合に特に有効です。この記事で使用するPythonのコードには、各ステップを理解しやすくするためのコメントを豊富に含めています。
実装手順
1. ライブラリのインポート
最初に、実装に必要なライブラリをインポートします。numpy
は数値計算を効率的に行うために、matplotlib.pyplot
はグラフを描画するために、pandas
はデータセットの操作や分析を行うために使用します。
import numpy as np # 数値計算を行うためのライブラリ
import matplotlib.pyplot as plt # グラフの描画を行うためのライブラリ
import pandas as pd # データセットの操作や分析を行うためのライブラリ
2. データセットの生成
ここでは、scikit-learnのmake_circles
関数を用いて、簡単な非線形データセットを生成します。この関数は、指定された数のサンプルを生成し、それらが大きな円の内側と外側に位置するように配置します。このようなデータセットはカーネルSVMの概念を理解するのに適しています。
from sklearn.datasets import make_circles
X, y = make_circles(n_samples=400, factor=0.3, noise=0.05) # 400個のサンプルを生成
n_samples
は生成するサンプルの総数を指定します。この例では400個のサンプルを生成しています。factor
は内側の円と外側の円の間の比率を指定します。値が小さいほど、二つの円の間のギャップが大きくなります。noise
はサンプルに追加されるガウスノイズの量を指定します。これにより、データセットに多少のばらつきが生じ、実世界のデータセットを模倣します。
説明変数と目的変数
- 説明変数(
X
): これは、データセットの特徴を表す部分です。make_circles
関数によって生成されるX
は、各サンプルの2次元座標を含む400×2の配列です。これらの座標は、サンプルが空間上のどの位置に存在するかを示します。 - 目的変数(
y
): これは、各サンプルのラベルまたはクラスを表します。make_circles
関数では、サンプルが内側の円に属するか外側の円に属するかを示す0または1の値がy
に格納されます。これにより、二値分類問題が形成されます。
このようなデータセットは、カーネルSVMを用いて、単純な線形モデルでは分類できない複雑なパターンを識別する方法を学ぶのに最適です。次のセクションでは、このデータセットを使用してカーネルSVMモデルの訓練と評価を行う具体的な手順を説明します。
3. データセットを訓練セットとテストセットに分割
生成したデータセットを訓練用とテスト用に分割します。これにより、モデルが未知のデータに対してどのように振る舞うかを評価することができます。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0) # データセットを75%の訓練セットと25%のテストセットに分割
test_size
パラメーターはテストセットの割合を指定し、random_state
は実行ごとに結果が変わらないように乱数のシードを固定します。
4. 特徴量のスケーリング
多くの機械学習アルゴリズムでは、特徴量のスケーリングを行うことで性能が向上します。StandardScaler
を使用して、特徴量を標準化します(平均が0、標準偏差が1になるように変換します)。
from sklearn.preprocessing import StandardScaler
sc = StandardScaler() # スケーラーのインスタンスを作成
X_train = sc.fit_transform(X_train) # 訓練データをスケーリング
X_test = sc.transform(X_test) # テストデータをスケーリング
5. 訓練セットでモデルを学習
次に、カーネルSVMモデルを訓練します。ここではRBFカーネルを使用したSVC
クラスを利用します。
from sklearn.svm import SVC
classifier = SVC(kernel='rbf', random_state=0) # RBFカーネルを使用するSVCインスタンスを作成
classifier.fit(X_train, y_train) # モデルを訓練データにフィットさせる
6. 新しい結果の予測
訓練されたモデルを使用して、新しいデータポイントのクラスを予測します。
new_prediction = classifier.predict(sc.transform([[0.8, -0.6]])) # 新しいデータポイントに対する予測を行う
print(new_prediction) # 予測結果を出力
出力:
[0]
このステップでは、新しいデータポイント(ここでは[0.8, -0.6]
と仮定)をモデルに入力し、どのクラスに属するかを予測します。
7. テストセットで予測
テストセットを用いてモデルの予測性能を評価します。
y_pred = classifier.predict(X_test) # テストセットに対する予測を行う
8. 混同行列による精度の確認
混同行列と精度スコアを計算して、モデルの性能を詳細に分析します。
from sklearn.metrics import confusion_matrix, accuracy_score
cm = confusion_matrix(y_test, y_pred) # 混同行列を計算
print(cm)
print(accuracy_score(y_test, y_pred)) # 精度スコアを計算して出力
出力:
[[52 0]
[ 0 48]]
1.0
混同行列は、モデルの予測がどの程度実際のラベルと一致しているかを示します。精度スコアは、正しく予測されたデータポイントの割合です。
9. 訓練セットでの結果を可視化
訓練セットにおけるモデルの性能を視覚的に確認します。ここでは、訓練セットのデータポイントとモデルによって形成された決定境界を表示します。
from matplotlib.colors import ListedColormap
X_set, y_set = sc.inverse_transform(X_train), y_train
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(sc.transform(np.array([X1.ravel(), X2.ravel()]).T)).reshape(X1.shape),
alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('Kernel SVM (Training set)')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.show()

このコードは、訓練データの特徴量を元のスケールに戻し(スケーリング解除後)、データの分布とモデルによって生成された決定境界を可視化します。異なるクラスのデータポイントは異なる色で表示されます。
10. テストセットでの結果を可視化
同様に、テストセットに対するモデルの性能も視覚化します。これにより、モデルが見たことのないデータに対してどれだけうまく機能するかを視覚的に理解できます。
from matplotlib.colors import ListedColormap
X_set, y_set = sc.inverse_transform(X_test), y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(sc.transform(np.array([X1.ravel(), X2.ravel()]).T)).reshape(X1.shape),
alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('Kernel SVM (Test set)')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.show()

このステップでは、テストデータの特徴量を元のスケールに戻し、テストセットのデータポイントとモデルによって形成された決定境界を表示します。これにより、モデルが実際に未知のデータに対してどのように分類を行うかを視覚的に確認できます。
まとめ
カーネルSVMは、非線形分離可能なデータセットに対して強力な分類能力を持つ機械学習モデルです。この記事では、カーネルSVMの基本的な理解から、Pythonを使用した具体的な実装方法までを詳細に説明しました。理論だけでなく、実際にコードを書いてみることで、機械学習の深い理解につながります。
本コンテンツへの意見や質問