[機械学習のはじめ方] Part17: サポートベクターマシン(SVM)のカーネルとマージン

機械学習の分類問題でよく使われる強力なアルゴリズムの一つに、サポートベクターマシン (SVM) があります。SVMは、データが高次元であっても高い汎化性能を発揮することが期待できる手法です。

この記事では、SVMを理解する上で欠かせない二つの重要な概念、マージン最大化カーネルトリックについて、初学者の方にも分かりやすく解説していきます。SVMがどのようにデータを分類するのか、その核心に迫りましょう!

マージン最大化: SVMの賢い境界線の引き方

SVMの基本的な考え方は、2つのクラスを分ける「境界線」(専門用語では決定境界超平面と呼びます)を引くことです。そして、SVMの最大の特徴は、この境界線を引く際に「マージン」を最大化しようとすることです。

マージンとは、決定境界と、境界線に最も近い各クラスのデータ点との距離のことです。SVMは、このマージンをできるだけ大きく取るように決定境界を設定します。なぜなら、マージンが大きいほど、未知のデータに対する予測性能(汎化性能)が高くなる傾向があるからです。境界線ギリギリにデータがあると、少しノイズが乗っただけで誤分類してしまう可能性が高まりますが、マージンに余裕があれば、そのような誤分類を防ぎやすくなります。

マージンを決定する上で最も重要な役割を果たす、境界線に最も近いデータ点のことをサポートベクターと呼びます。SVMという名前の由来にもなっていますね。

ハードマージン vs ソフトマージン

完全にデータを分離できる(誤分類を全く許さない)前提でマージンを最大化することをハードマージンと呼びます。しかし、現実のデータにはノイズが含まれていたり、そもそも完全に線形分離できない場合が多くあります。

そこで、多少の誤分類やマージン内への侵入を許容することで、より現実的なデータに対応できるようにしたのがソフトマージンです。ソフトマージンSVMでは、ハイパーパラメータ C を使って、誤分類へのペナルティの大きさを調整します。Cが大きいほど誤分類を許さずハードマージンに近づき、小さいほど誤分類を許容してマージンを広く取ろうとします。このCの調整は、モデルの性能に大きく影響します。

カーネルトリック: 非線形データも攻略!

SVMは元々、直線(あるいは平面、超平面)で分離できるデータ(線形分離可能なデータ)を対象としていました。しかし、実際のデータはもっと複雑で、単純な直線ではうまく分離できない(非線形な)場合がほとんどです。

ここで登場するのがカーネルトリック(カーネル法)です! カーネルトリックは、元の特徴空間では線形分離できないデータを、より高次元の特徴空間に写像(変換)することで、線形分離可能にするテクニックです。

例えば、一次元のデータ「●●〇〇●●」(●と〇を分けたい)は直線では分けられませんが、二次元にうまく変換できれば、直線で分離できるかもしれません。カーネルトリックのすごいところは、実際に高次元空間へのデータ変換を行わなくても、カーネル関数と呼ばれる関数を使って、高次元空間での内積計算(データ間の類似度のようなもの)を効率的に行える点です。これにより、計算コストを抑えつつ、非線形なデータに対応できます。

代表的なカーネル関数

よく使われるカーネル関数には、以下のようなものがあります。それぞれの特性を理解し、データに合わせて選択することが重要です。

カーネル関数 主な特徴 主なハイパーパラメータ 適している場面
線形カーネル (linear) 元の特徴空間で線形分離を試みる(カーネルトリックを使わない)。計算が高速。 C データが線形分離可能な場合、データ数が非常に多い場合、特徴量の次元が高い場合。
多項式カーネル (poly) データ間の関係を多項式で表現する。 C, degree (次数), coef0 (切片) 画像処理などで使われることがある。
RBFカーネル (ガウスカーネル) 最もよく使われるカーネルの一つ。複雑な非線形境界を表現できる。 C, gamma 汎用性が高く、多くの場合で良好な性能を示す。gammaは境界の複雑さに影響。
シグモイドカーネル (sigmoid) ニューラルネットワークの活性化関数に似た形。 C, gamma, coef0 特定のケース(例:二値分類問題の一部)で有効なことがあるが、RBFほど一般的ではない。

特にRBFカーネルは汎用性が高く、よく使われます。ハイパーパラメータのgammaは、一つのデータ点の影響が及ぶ範囲を調整します。gammaが大きいと影響範囲が狭くなり、境界線が複雑になりがち(過学習のリスク)で、小さいと影響範囲が広くなり、境界線が滑らかになりがちです。Cgammaの適切な組み合わせを見つけることが、SVMの性能を引き出す鍵となります(グリッドサーチなどの手法が使われます)。

Python (scikit-learn) での実装例

Pythonの機械学習ライブラリであるscikit-learnを使うと、SVMを簡単に実装できます。ここでは、分類問題用のSVC (Support Vector Classifier) を使ってみましょう。


from sklearn.svm import SVC
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score

# 1. データの生成 (例として分類用データを生成)
X, y = make_classification(n_samples=100, n_features=2, n_informative=2, n_redundant=0, random_state=42)

# 2. データの分割と標準化
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 3. SVMモデルの作成と学習 (RBFカーネル、C=1.0, gamma='scale'がデフォルト)
# カーネルやパラメータを指定する場合はここで設定
# 例: 線形カーネルの場合 -> SVC(kernel='linear', C=0.1)
# 例: RBFカーネルでgammaを指定 -> SVC(kernel='rbf', C=10, gamma=0.1)
svm_model = SVC(kernel='rbf', C=1.0, gamma='scale', random_state=42) # デフォルトのRBFカーネルを使用

# 学習の実行
svm_model.fit(X_train_scaled, y_train)

# 4. テストデータで予測
y_pred = svm_model.predict(X_test_scaled)

# 5. 性能評価 (例: 正確度)
accuracy = accuracy_score(y_test, y_pred)
print(f"SVMモデルの正確度 (Accuracy): {accuracy:.4f}")

# 使われたサポートベクターの数なども確認できる
print(f"サポートベクターの数: {svm_model.n_support_}")
      

このコードでは、まずサンプルデータを生成し、学習データとテストデータに分割後、標準化を行っています(SVMはデータのスケールに影響を受けやすいため、標準化は重要です)。その後、SVCクラスを使ってSVMモデルを作成し、fitメソッドで学習させます。SVCの引数でkernel, C, gammaなどのハイパーパラメータを指定できます。最後に、テストデータで予測を行い、精度を評価しています。

まとめ

今回は、サポートベクターマシン(SVM)の核心となるマージン最大化カーネルトリックについて解説しました。

  • マージン最大化: 決定境界と最も近いデータ点(サポートベクター)との距離を最大化することで、高い汎化性能を目指します。ソフトマージンにより、現実のノイズや分離不可能なデータにも対応します(Cで調整)。
  • カーネルトリック: 元の空間で線形分離できないデータを、高次元空間に写像して線形分離可能にするテクニックです。カーネル関数(線形、多項式、RBF、シグモイドなど)の選択が重要です(RBFがよく使われ、gammaで複雑さを調整)。

SVMは、特に高次元データや非線形な問題に対して強力な分類器ですが、その性能は適切なカーネルの選択ハイパーパラメータ(C, gammaなど)の調整に大きく依存します。

この記事が、SVMの理解を深める一助となれば幸いです。次は、モデルの評価方法について学んでいきましょう!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です