サポートベクターマシンへの優しい入門
Introduction to Support Vector Machines
サポートベクターマシンは、分類と回帰の両方のタスクに使用される単純で強力な機械学習アルゴリズムの一種です。この議論では、分類のためのサポートベクターマシンの使用に焦点を当てます。
まず、クラス分類とクラスを分離するハイパープレーンの基礎を見ていきます。次に、最大マージン分類器について説明し、徐々にサポートベクターマシンとアルゴリズムのscikit-learn実装について詳しく説明します。
分類問題と分離ハイパープレーン
分類は教師あり学習の問題であり、ラベル付きのデータポイントがあり、機械学習アルゴリズムの目標は新しいデータポイントのラベルを予測することです。
簡単のために、2つのクラス、すなわちクラスAとクラスBの2値分類問題を考えましょう。そして、これらの2つのクラスを分離するハイパープレーンを見つける必要があります。
数学的には、ハイパープレーンは、アンビエント空間より1次元低い次元の部分空間です。つまり、アンビエント空間が1次元の直線である場合、ハイパープレーンは点です。アンビエント空間が2次元平面である場合、ハイパープレーンは直線です。
したがって、2つのクラスを分離するハイパープレーンがある場合、クラスAに属するデータポイントはハイパープレーンの一方の側にあり、クラスBに属するデータポイントはハイパープレーンの他方の側にあります。
したがって、1次元空間では、分離ハイパープレーンは点です:
2次元では、クラスAとクラスBを分離するハイパープレーンは直線です:
そして、3次元では、分離ハイパープレーンは平面です:
同様に、N次元の場合、分離ハイパープレーンは(N-1)次元の部分空間になります。
よく見ると、2次元空間の例では、以下のいずれもクラスAとクラスBを分離する有効なハイパープレーンです:
では、どのハイパープレーンが最適かどうやって決めるのでしょうか?それが最大マージン分類器の登場です。
最大マージン分類器
最適なハイパープレーンは、2つのクラスを分離しながらそれらの間のマージンを最大化するものです。そして、そのように機能する分類器は最大マージン分類器と呼ばれます。
ハードマージンとソフトマージン
完全に分離可能なクラスの場合、最大マージン分類器は良い選択肢でした。
しかし、このようにデータポイントが分布している場合はどうでしょうか?クラスはまだハイパープレーンによって完全に分離されており、マージンを最大化するハイパープレーンは次のようになります:
しかし、このアプローチには問題がありますか?まだクラスの分離は成し遂げられています。ただし、これは高分散モデルであり、おそらくクラスAのポイントに過剰にフィットしようとしているかもしれません。
ただし、マージンには誤分類されたデータポイントはありません。このような分類器はハードマージン分類器と呼ばれます。
代わりに、次の分類器を見てください。このような分類器の方が優れた性能を発揮するでしょうか?これは、クラスAとクラスBの両方のポイントを適切に分類する低分散モデルです。
線形サポートベクター分類器 | 著者による画像
マージン内に誤分類されたデータポイントがあることに注意してください。最小限の誤分類を許容する分類器は、ソフトマージン分類器と呼ばれます。
サポートベクトル分類器
私たちが持っているソフトマージン分類器は、線形サポートベクトル分類器です。ポイントは線(または線形方程式)で分離可能です。これまで追ってきた方なら、「サポートベクトル」が何であるか、なぜそのように呼ばれるのかは明らかだと思います。
各データポイントは特徴空間内のベクトルです。分離超平面に最も近いデータポイントは、分類をサポートまたは援助するためにサポートベクトルと呼ばれます。
興味深いことに、サポートベクトルではない単一のデータポイントまたはデータポイントの部分集合を削除した場合、分離超平面は変化しません。ただし、1つ以上のサポートベクトルを削除すると、超平面が変化します。
これまでの例では、データポイントは線形に分離可能でした。したがって、最小限のエラーでソフトマージン分類器をフィットすることができました。しかし、次のようにデータポイントが分布している場合はどうでしょうか?
線形分離不可能なデータ | 著者による画像
この例では、データポイントは線形に分離できません。誤分類を許容するソフトマージン分類器があっても、これらの2つのクラスで良い性能を実現する線(分離超平面)を見つけることはできません。
では、どうすればいいのでしょうか?
サポートベクターマシンとカーネルトリック
以下は私たちが行うことの要約です:
- 問題:元の特徴空間でデータポイントが線形に分離できません。
- 解決策:データポイントを線形に分離できるようにより高次元の空間に射影します。
ただし、データポイントを元の特徴空間から高次元空間に射影するには、データポイントを再計算する必要があります。
この再計算には、特に射影先の空間が元の特徴空間よりもはるかに高い次元である場合、無視できないオーバーヘッドが伴います。ここでカーネルトリックが登場します。
数学的には、サポートベクトル分類器は以下の式[1]で表されます:
ここで、は定数であり、はサポートポイントに対応するインデックスの集合を合計することを示しています。
は、ポイントとの内積です。ベクトルaとbの内積は次のようになります:
カーネル関数K(.)により、線形サポートベクトル分類器を非線形な場合にも一般化することができます。内積をカーネル関数に置き換えます:
カーネル関数は非線形性を考慮しています。また、元の特徴空間のデータポイントを再計算することなく、計算を実行することも可能にしています。
線形サポートベクトル分類器の場合、カーネル関数は単純に内積であり、以下の形式を取ります:
Scikit-Learnにおけるサポートベクトルマシン
サポートベクトルマシンの直感を理解したので、scikit-learnライブラリを使用してクイックな例をコーディングしましょう。
scikit-learnライブラリのsvmモジュールには、Linear SVC、SVC、およびNuSVCなどのクラスの実装が付属しています。これらのクラスは、二値分類および多クラス分類の両方に使用することができます。Scikit-learnの拡張ドキュメントには、サポートされているカーネルの一覧が記載されています。
組み込みのワインデータセットを使用します。これは、ワインの特徴を使用して、出力ラベル(0、1、または2のいずれか)を予測する分類問題です。約178のレコードと13の特徴を持つ小さなデータセットです。
ここでは、次の作業に焦点を当てます:
- データの読み込みと前処理
- データセットに分類器を適合させる
ステップ1 – 必要なライブラリをインポートし、データセットを読み込む
まず、scikit-learnのdatasetsモジュールにあるワインデータセットを読み込みましょう:
from sklearn.datasets import load_wine
# ワインデータセットを読み込む
wine = load_wine()
X = wine.data
y = wine.target
ステップ2 – データセットをトレーニングセットとテストセットに分割する
データセットをトレーニングセットとテストセットに分割しましょう。ここでは、データポイントの80%と20%がトレーニングセットとテストセットに入るように、80:20の割合を使用します:
from sklearn.model_selection import train_test_split
# データセットをトレーニングセットとテストセットに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10)
ステップ3 – データセットを前処理する
次に、データセットを前処理します。データポイントが平均がゼロで分散が1の分布に従うように、StandardScaler
を使用してデータを変換します:
# データの前処理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
テストデータセットにfit_transform
を使用しないように注意してください。これはデータのリークの微妙な問題を引き起こす可能性があります。
ステップ4 – SVM分類器をインスタンス化し、トレーニングデータに適合させる
この例では、SVC
を使用します。svm
という名前のSVCオブジェクトをインスタンス化し、トレーニングデータに適合させます:
from sklearn.svm import SVC
# SVM分類器を作成する
svm = SVC()
# SVM分類器をトレーニングデータに適合させる
svm.fit(X_train_scaled, y_train)
ステップ5 – テストサンプルのラベルを予測する
テストデータのクラスラベルを予測するには、svm
オブジェクトのpredict
メソッドを呼び出すことができます:
# テストセットのラベルを予測する
y_pred = svm.predict(X_test_scaled)
ステップ6 – モデルの正確性を評価する
議論をまとめるために、正確性スコアのみを計算します。ただし、詳細な分類レポートや混同行列も取得することもできます。
from sklearn.metrics import accuracy_score
# モデルの正確性を計算する
accuracy = accuracy_score(y_test, y_pred)
print(f"{accuracy=:.2f}")
出力 >>> accuracy=0.97
以下は完全なコードです:
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# ワインのデータセットを読み込む
wine = load_wine()
X = wine.data
y = wine.target
# データセットをトレーニングセットとテストセットに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10)
# データの前処理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# SVM分類器を作成する
svm = SVC()
# SVM分類器をトレーニングデータに適合させる
svm.fit(X_train_scaled, y_train)
# テストセットのラベルを予測する
y_pred = svm.predict(X_test_scaled)
# モデルの正確性を計算する
accuracy = accuracy_score(y_test, y_pred)
print(f"{accuracy=:.2f}")
シンプルなサポートベクトル分類器を使用しています。サポートベクトル分類器の性能を向上させるために調整できるハイパーパラメータがあります。一般的に調整されるハイパーパラメータには、正則化定数Cとガンマ値があります。
結論
このサポートベクトルマシンの入門ガイドが役に立ったことを願っています。サポートベクトルマシンの動作原理を理解するために必要な直感と概念を十分にカバーしました。もっと深く掘り下げたい場合は、以下の参考文献をチェックしてください。学習を続けましょう!
参考文献と学習リソース
[1] サポートベクトルマシンの章、統計的学習の入門(ISLR)
[2] カーネルマシンの章、機械学習の入門
[3] サポートベクトルマシン、scikit-learnドキュメント Bala Priya Cは、インド出身の開発者兼技術ライターです。彼女は数学、プログラミング、データサイエンス、コンテンツ作成の交差点での仕事が好きです。彼女の関心と専門知識の範囲には、DevOps、データサイエンス、自然言語処理が含まれます。彼女は読書、執筆、コーディング、コーヒーを楽しんでいます!現在は、チュートリアル、ハウツーガイド、意見記事などを執筆することによって、開発者コミュニティと知識を共有する学習を進めています。