AI Technology Community
payititi-AI助手
2021-12-06 16:18:59
機械学習――SVMアルゴリズム実現
一. sklearnのデータセットを使用したケース
%matplotlib inline import numpy as np import matplotlib.pyplot as plt from scipy import stats # seabornを使用してデフォルト値を描画 import seaborn as sns; sns.set() #ランダムにデータを生成 from sklearn.datasets.samples_generator import make_blobs X, y = make_blobs(n_samples=50, centers=2, random_state=0, cluster_std=0.60) plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
適当にいくつかの分割線を引いて、どれが良いか見てみましょう。
xfit = np.linspace(-1, 3.5) plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn') plt.plot([0.6], [2.1], 'x', color='red', markeredgewidth=2, markersize=10) for m, b in [(1, 0.65), (0.5, 1.6), (-0.2, 2.9)]: plt.plot(xfit, m * xfit + b, '-k') plt.xlim(-1, 3.5);
さらに、決定境界の領域を観察し、影を描画します。
xfit = np.linspace(-1, 3.5) plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn') for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]: yfit = m * xfit + b plt.plot(xfit, yfit, '-k') plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none', color='#AAAAAA', alpha=0.4) plt.xlim(-1, 3.5);
二. SVMの訓練
from sklearn.svm import SVC # "Support vector classifier" model = SVC(kernel='linear') model.fit(X, y)
#描画関数def plot_svc_decision_function(model, ax=None, plot_support=True): """2次元SVCの決定関数を描画""" if ax is None: ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim() # モデルを評価するためのグリッドを作成 x = np.linspace(xlim[0], xlim[1], 30) y = np.linspace(ylim[0], ylim[1], 30) Y, X = np.meshgrid(y, x) xy = np.vstack([X.ravel(), Y.ravel()]).T P = model.decision_function(xy).reshape(X.shape) # 決定境界と小領域を描画 ax.contour(X, Y, P, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--']) # サポートベクトルを描画 if plot_support: ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=300, linewidth=1, facecolors='none'); ax.set_xlim(xlim) ax.set_ylim(ylim)plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')plot_svc_decision_function(model)
この線が私たちが求める決定境界です。
観察すると、3つの点が特別にマークされています。これらはすべて境界上の点です。
これらがサポートベクトル(support vectors)です。
Scikit-Learnでは、これらはsupport_vectors_(属性)に格納されています。
model.support_vectors_
観察すると、サポートベクトルだけでモデルを構築できることがわかります。
三. 次に、異なる数のデータ点を使用して、結果が変化するかどうかを試してみましょう。それぞれ60個と120個のデータ点を使用します。
def plot_svm(N=10, ax=None): X, y = make_blobs(n_samples=200, centers=2, random_state=0, cluster_std=0.60) X = X[:N] y = y[:N] model = SVC(kernel='linear', C=1E10) model.fit(X, y) ax = ax or plt.gca() ax.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn') ax.set_xlim(-1, 4) ax.set_ylim(-1, 6) plot_svc_decision_function(model, ax)fig, ax = plt.subplots(1, 2, figsize=(16, 6))fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)for axi, N in zip(ax, [60, 120]): plot_svm(N, axi) axi.set_title('N = {0}'.format(N))
観察すると、サポートベクトルが変わらなければ、他のデータをどのように追加しても問題ありません!
四. カーネル関数を導入したSVM
まず、線形カーネルを使用して、以下のような難しいデータセットでも分類できるかどうかを見てみましょう。
from sklearn.datasets.samples_generator import make_circles X, y = make_circles(100, factor=.1, noise=.1)clf = SVC(kernel='linear').fit(X, y)plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')plot_svc_decision_function(clf, plot_support=False)
明らかにできません。次に、高次元のカーネル変換を試してみましょう。
まず、3次元グラフを使用して、この追加のデータ次元を表現します。
#新しい次元rを追加from mpl_toolkits import mplot3d r = np.exp(-(X ** 2).sum(1))def plot_3D(elev=30, azim=30, X=X, y=y): ax = plt.subplot(projection='3d') ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='autumn') ax.view_init(elev=elev, azim=azim) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel(
3
item of content
サポートベクターマシン(Support Vector Machines, SVM)は二値分類モデルであり、その基本モデルは特徴空間上で定義された最大の間隔を持つ線形分類器です。この間隔最大化により、SVMはパーセプトロンとは区別されます。また、SVMにはカーネルトリックが含まれており、これにより実質的に非線形分類器となります。SVMの学習戦略は間隔の最大化であり、これは凸二次計画問題の解決形式として表現され、正則化されたヒンジ損失関数の最小化問題と等価です。SVMの学習アルゴリズムは凸二次計画の最適化アルゴリズムを求解するものです。
- 548hits
- 0replay
-
0like
- collect
- send report