サポート ベクター マシンは、より少ない計算コストで比較的優れたパフォーマンスを発揮するもう 1 つの単純なアルゴリズムです。回帰では、SVM は、マージンを考慮しながら多次元データに適合する N 次元空間 (N 個の特徴) で超平面を見つけることによって機能します。分類では、同じ超平面が計算されますが、マージンを考慮しながらデータ ポイントを再度明確に分類します。選択可能な超平面が多数存在する可能性があります。ただし、目的は、ターゲット クラス間の最大距離を意味する、最大のマージンを持つ超平面を見つけることです。
SVM は回帰問題と分類問題の両方に使用できますが、分類に広く使用されています。
先に進む前に、いくつかの用語について説明しましょう。
カーネルは、データを高次元に変換するために使用される関数です。
超平面は、クラスを分離する線です (分類問題の場合)。回帰の場合、継続的な結果の値を予測するためにデータに当てはめた線です。
境界線は、前述のエラーのある領域を形成する線です。それらはマージンを表す超平面の周りの 2 本の線です。
サポート ベクターは、これらの境界線に最も近いデータ ポイントです。
カーネルは、データを高次元に変換する機能であると述べました。さて、それは私たちにとってどのように役立ちますか?
線形の線 (区切り記号) を使用して正確な適合を得ることが不可能な方法でデータが分散される場合があります。 SVR は、カーネル関数を使用して高度に非線形なデータを処理できます。この関数は、機能をより高い次元に暗黙的にマッピングします。つまり、より高い機能空間を意味します。これにより、線形超平面を使用して記述することもできます。
最もよく使用される 3 つのカーネルは次のとおりです。
線形回帰モデルと同様に、SVR もデータセットに最適な曲線を見つけようとします。線形回帰からの 1 つの特徴を持つデータセットの方程式を思い出してください。
y=w1x1+c
1 つの特徴を持つデータセットの SVR を考慮すると、方程式は似ていますが、エラーを考慮しています。
−e≤y−(w1x1+c)≤e
式を見ると、e error 領域外のポイントのみがコスト計算で考慮されることが明らかです。
SVR はもちろん、多項式回帰と同様の高次元の特徴項を使用することで、より多くの特徴を持つ複雑なデータセットにも使用できます。
超平面は、可能な最大数の点と一致する場合にデータに最適です。超平面に最も近い点が境界線内にあるように、境界線 (超平面からの距離である e の値) を決定します。
マージン(境界線の間)は許容されるため、エラーとして計算されないことに注意してください。この用語を使用して、モデルの複雑さを調整する方法 (アンダーフィッティング/オーバーフィッティング) をすでに想像できると思います。
import numpy as np from sklearn.svm import SVR import matplotlib.pyplot as plt np.random.seed(5) X = np.sort(5 * np.random.rand(40, 1), axis=0) T = np.linspace(0, 5, 5)[:, np.newaxis] y = np.sin(X).ravel() # Add noise to targets y[::5] += 1 * (0.5 - np.random.rand(8)) # Fit regression model SVR_rbf = SVR(kernel='rbf' ) SVR_lin = SVR(kernel='linear') SVR_poly = SVR(kernel='poly') y_rbf = SVR_rbf.fit(X, y).predict(X) y_lin = SVR_lin.fit(X, y).predict(X) y_poly = SVR_poly.fit(X, y).predict(X) # look at the results plt.scatter(X, y, c='k', label='data') plt.plot(X, y_rbf, c='b', label='RBF') plt.plot(X, y_lin, c='r',label='Linear') plt.plot(X, y_poly, c='g',label='Polynomial') plt.xlabel('data') plt.ylabel('outcome') plt.title('Support Vector Regression') plt.legend() plt.show()
「サポート ベクター マシン (SVM)」アルゴリズムが回帰でどのように機能するかは既に説明しました。分類については、考え方は実際にはほとんど同じです。実際、SVM は主に分類問題に使用されます。理由はもうお分かりだと思いますが…
回帰については、SVM がデータセットに最適な曲線を見つけようとし、その曲線を使用して新しい点を予測しようとすることを説明しました。同じ曲線を使用して、データを 2 つの異なるクラスに簡単に分類できます。 n 次元の多次元空間 (n 個の特徴を持つデータを意味する) の場合、モデルは 2 つのクラスを最もよく区別する超平面 (決定境界とも呼ばれます) に適合します。カーネルについて説明した回帰セクションの画像を思い出してください…
マージンは、超平面から最も近い点 (サポート ベクター) までの距離である、各クラスの 2 つの最も近い点の間のギャップです。データに最もよく適合する超平面、つまり 2 つのクラスを最もよく分離する超平面は、可能な限り最大のマージンを持つ超平面です。したがって、SVM アルゴリズムは、マージン (最も近い点までの距離) が最大の超平面を検索します。
回帰のセクションですでに述べたように、一部のデータセットは線形超平面で分類するのに適していません... この場合も、「カーネルのトリック」が助けになり、データを暗黙的に高次元にマッピングするため、次のことが可能になります。線形超平面によって分類されるデータ。カーネルの種類とその仕組みについては既に説明したので、実装例を続けます…
scikit Learn ライブラリの癌データセットを引き続き使用しましょう。
from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split X, y = load_breast_cancer(return_X_y = True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_sub = X[:, 0:2] # create a mesh to plot in x_min, x_max = X_sub[:, 0].min() - 1, X_sub[:, 0].max() + 1 y_min, y_max = X_sub[:, 1].min() - 1, X_sub[:, 1].max() + 1 h = (x_max / x_min)/100 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) #import the SVM model from sklearn import svm C = 1.0 # SVM regularization parameter svc = svm.SVC(kernel='linear').fit(X_sub, y) #play with this, change kernel to rbf plt.subplot(1, 1, 1) Z = svc.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8) plt.scatter(X_sub[:, 0], X_sub[:, 1], c=y, cmap=plt.cm.Paired) plt.scatter(X_sub[svc.support_, 0], X_sub[svc.support_, 1],c='k', cmap=plt.cm.Paired) plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.xlim(xx.min(), xx.max()) plt.title('SVC with linear kernel') plt.show()
#Create and instance of the classifier model with a linear kernel lsvm = svm.SVC(kernel="linear") #fit the model to our train split from previous example lsvm.fit(X_train,y_train) #Make predictions using the test split so we can evaluate its performance y_pred = lsvm.predict(X_test)
予測をテスト セットの実際の値と比較して、モデルのパフォーマンスを比較してみましょう…
from sklearn import metrics print("Accuracy:",metrics.accuracy_score(y_test, y_pred)) print("Precision:",metrics.precision_score(y_test, y_pred)) print("Recall:",metrics.recall_score(y_test, y_pred))
精度は 95.6% と非常に良好です。トレーニングとテストのスコアを比較して、オーバーフィッティングをチェックしましょう…
print("training set score: %f" % lsvm.score(X_train, y_train)) print("test set score: %f" % lsvm.score(X_test, y_test))
トレーニングの点数は、テストの点数より少し高いようです。それほど多くはありませんが、モデルはオーバーフィッティングであると言えます。
これが気に入ったら、無料の機械学習チュートリアルとコースをフォローしてください。