非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

【Python/scikit-learn】SVMで非線形データを分類!RBFカーネルを使った簡単な解説と実装

   

サポートベクタマシン(SVM)は、データ分類の強力なアルゴリズムの一つですが、単純な線形分離だけでなく非線形データにも対応できます。

RBFカーネル(Radial Basis Function Kernel)を使うことでSVMは入力データを高次元空間にマッピングし複雑なパターンを捉えることが可能になります。Scikit-learnを使ってRBFカーネルを適用したSVMの実装方法を解説し、どのように非線形データを効果的に分類できるのかを実際のコードとともに紹介します。

RBFカーネルの特徴

非線形の問題に適用可能

線形分離できない複雑なデータセットでも、高次元空間での線形分離を実現します。

ガンマパラメータ (gamma)

RBFカーネルは、ガンマパラメータを用いてデータポイントの影響範囲を調整します。gammaが大きいほど、モデルが各データポイントに敏感になり、局所的にフィッティングされますが、過剰適合のリスクが高まります。逆にgammaが小さいと、データ全体に対して緩やかにフィッティングされます。

デフォルトで使われるカーネル

SVCクラスでは、RBFカーネルがデフォルトのカーネルとなっています。つまり、SVC()と書くだけでRBFカーネルが適用されます。

 

RBFカーネルを用いたSVMのプログラム例

RBFカーネルを用いたSVMの実装例を示します。この例では、Scikit-learnのmake_circles関数を使って非線形なデータを生成しRBFカーネルで分類します。

# 必要なライブラリをインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score

# 非線形データを生成(2つの同心円)
X, y = make_circles(n_samples=100, factor=0.3, noise=0.1, random_state=42)

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# SVMモデルの作成(RBFカーネルを使用)
svm_model = SVC(kernel='rbf', gamma=1.0)

# モデルの訓練
svm_model.fit(X_train, y_train)

# テストデータを使って予測
y_pred = svm_model.predict(X_test)

# モデルの精度を計算
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy * 100:.2f}%")

# 境界線を描画
def plot_svm_decision_boundary(model, X, y):
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
                         np.arange(y_min, y_max, 0.01))

    # 各点のクラスを予測
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    # 境界線の描画
    plt.contourf(xx, yy, Z, alpha=0.8)
    plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
    plt.title('SVM with RBF Kernel')
    plt.show()

# 訓練データとSVMによる境界線を描画
plot_svm_decision_boundary(svm_model, X_test, y_test)
 

 

コードの説明

データ生成

make_circles関数で、2つの同心円を形成する非線形なデータを生成しています。factor=0.3で内側と外側の円の間隔を設定し、noise=0.1でデータに若干のノイズを加えています。

SVMモデルの作成

SVC(kernel=’rbf’, gamma=1.0)でRBFカーネルを指定し、gamma=1.0としています。gammaの値はRBFカーネルのガウス関数の幅を調整するパラメータで、大きくするとよりローカルな決定境界を作ります。

モデルの訓練と予測

訓練データでSVMを訓練し、テストデータで予測を行います。

精度評価

accuracy_scoreを使ってモデルの分類精度を計算しています。

決定境界の可視化

plot_svm_decision_boundary関数で、SVMが生成したクラスの境界線を描画します。非線形データである同心円に対して、RBFカーネルを用いることで非線形の決定境界が形成されていることが確認できます。

実行結果

こちらが実行結果です。このプロットは、RBFカーネルを使用してSVMが非線形データを分類した結果を示しています。

背景の色分け
  • 紫色の背景部分は、一方のクラスに分類された領域を示しています。
  • 黄緑色の背景部分は、もう一方のクラスに分類された領域を表しています。
  • これらの背景色の境界は、SVMがデータを分離するために見つけた非線形な境界線です。この境界線は、RBFカーネルによってデータが高次元空間にマッピングされ、非線形のパターンを捉えることができています。
データポイント
  • 黄色の丸は、1つ目のクラスに属するデータポイントです。これらは円の中心付近に集まっています。
  • 紫色の丸は、2つ目のクラスに属するデータポイントです。これらは外側の領域に散らばっています。
  • このように、2つのクラスは円状に分布しており、線形分離が不可能なパターンです。しかし、RBFカーネルを使用することで、このような複雑なパターンでも正確に分類されています。
分類境界

RBFカーネルの特性により、SVMは円形の境界線を描き、中心に位置するデータポイント(黄色の丸)を外側のデータポイント(紫色の丸)と分離しています。このような非線形のデータセットでは、RBFカーネルの使用が非常に有効です。

 

まとめ

今回の例はRBFカーネルを使ったSVMが線形では分離できないデータをどのようにして分類しているかを視覚的に示しています。

SVMはデータポイントを高次元空間にマッピングし非線形の境界を作ることで、中心に密集したクラスと外側に広がるクラスをしっかりと分離しています。今回の例はSVMの非線形カーネル(特にRBFカーネル)がどれほど強力かを示していると思います。

 

スポンサーリンク

 - Python