メインコンテンツへスキップ

E.C.1 サポートベクターマシン

SVM の最大マージンとサポートベクトル図

SVM のパラメータ C と kernel 選択図

SVM は、マージンができるだけ大きい決定境界を探します。境界に最も近い点がサポートベクトルで、境界の位置を強く決める重要なサンプルです。

準備するもの

  • Python 3.10+
  • 現在の安定版 scikit-learnnumpy
python -m pip install -U scikit-learn numpy

重要用語

  • Margin(マージン):境界から最も近いサンプルまでの距離。
  • Support vector(サポートベクトル):境界近くの重要サンプル。
  • C:誤分類をどれだけ許すかを調整する値。大きいほど訓練データに強く合わせやすい。
  • Kernel(カーネル):境界を線形にするか非線形にするかを決める。
  • Scaling(スケーリング):SVM では特徴量の範囲をそろえることが多くの場合必要。

線形 SVM ベースラインを動かす

svm_baseline.py を作成します。

import numpy as np
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

X = np.array([
[1.0, 1.2],
[1.3, 0.9],
[1.1, 1.0],
[4.0, 4.2],
[4.3, 3.8],
[3.9, 4.1],
])
y = np.array([0, 0, 0, 1, 1, 1])

model = make_pipeline(
StandardScaler(),
SVC(kernel="linear", C=1.0),
)

model.fit(X, y)
pred = model.predict([[1.2, 1.1], [4.2, 4.0]])
svc = model.named_steps["svc"]

print("predictions:", pred.tolist())
print("support_per_class:", svc.n_support_.tolist())

実行します。

python svm_baseline.py

期待される出力:

predictions: [0, 1]
support_per_class: [2, 1]

これが最小限の SVM 習慣です。特徴量をスケーリングし、モデルを学習し、予測し、サポートベクトルを確認します。

境界を変える

この単独の比較コードを実行します。

from sklearn.svm import SVC

for kernel in ["linear", "rbf"]:
if kernel == "linear":
model = SVC(kernel="linear", C=1.0)
else:
model = SVC(kernel="rbf", C=1.0, gamma="scale")
print(model)

期待される出力の先頭は次のようになります。

SVC(kernel='linear')
SVC()

境界が単純なら、まず linear を使います。線形 SVM が明らかに足りない場合や、境界が曲線的に見える場合に rbf を試します。

実用的な判断

SVM を試す場面:

  1. データが小中規模。
  2. 特徴量がすでに意味を持っている。
  3. クラス境界が比較的はっきりしている。
  4. 重いモデルの前に強いベースラインがほしい。

データが非常に大きい場合や、予測レイテンシが極端に厳しい場合は注意します。

よくある間違い

  • StandardScaler() を忘れる。
  • 線形を試す前に複雑な kernel から始める。
  • 特徴量の質を確認せず、C と kernel だけを調整する。

練習

境界付近にノイズ点を2つ追加し、C=0.1C=1.0C=10.0 を比べます。それぞれのサポートベクトル数を記録してください。