Машина опорных векторов — это контролируемое обучение, которое находит гиперплоскость в N-мерном пространстве для четкой классификации точек данных. SVM использует функцию потери шарнира и регуляризацию L2.

  1. Загрузка библиотек —
import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt

from sklearn import datasets
from sklearn.svm import SVC

%matplotlib inline
plt.rcParams['figure.figsize'] = (10, 5)

2. Загрузка и предварительная обработка набора данных —

# Loading the Iris Dataset. 
iris = datasets.load_iris()

# Concatenating the first 2 features and Target column. 
df = pd.concat([pd.DataFrame(iris.data[:,:2], columns=iris.feature_names[:2]), pd.DataFrame({'Target':iris.target})], axis=1)
print("Dataset : \n", df.head())

# Splitting the feature and target columns
X = df.drop('Target', axis=1).values
y = df['Target'].values

3. Создание функции построения графика —

def make_meshgrid(x, y, h=.02, lims=None):
    """Create a mesh of points to plot in
    
    Parameters
    ----------
        x: data to base x-axis meshgrid on
        y: data to base y-axis meshgrid on
        h: stepsize for meshgrid, optional
        
    Returns
    -------
        xx, yy : ndarray
    """
    if lims is None:
        x_min, x_max = x.min() - 1, x.max() + 1
        y_min, y_max = y.min() - 1, y.max() + 1
    else:
        x_min, x_max, y_min, y_max = lims
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    return xx, yy

# https://jakevdp.github.io/PythonDataScienceHandbook/04.04-density-and-contour-plots.html
def plot_contours(ax, clf, xx, yy, proba=False, **params):
    """Plot the decision boundaries for a classifier.
    
    Parameters
    ----------
        ax: matplotlib axes object
        clf: a classifier
        xx: meshgrid ndarray
        yy: meshgrid ndarray
        params: dictionary of params to pass to contourf, optional
    """
    # if proba==True then make a probability contour graph. 
    if proba:
        # ravel()   - flattens the array to 1D. 
        # .c_[a, b] - Add in the second axis. Row remains same but column adds. https://stackoverflow.com/questions/10894323/what-does-the-c-underscore-expression-c-do-exactly 
        Z = clf.predict_proba(np.c_[xx.flatten(), yy.flatten()])[:,-1]
        Z = Z.reshape(xx.shape)
        out = ax.imshow(Z,extent=(np.min(xx), np.max(xx), np.min(yy), np.max(yy)), 
                        origin='lower', vmin=0, vmax=1, **params)
        ax.contour(xx, yy, Z, levels=[0.5])
    
    # if proba==False then make a normal contour graph
    else:
        Z = clf.predict(np.c_[xx.flatten(), yy.flatten()])
        Z = Z.reshape(xx.shape)
        out = ax.contourf(xx, yy, Z, **params)
    return out

# Will only work for 2 columns in X and 1 in Y, proba can be set to True or False
def plot_classifier(X, y, clf, xlab, ylab, title, ax=None, ticks=False, proba=False, lims=None): 
    # assumes classifier "clf" is already fit
    
    # get all the values in first and second columns in X0 and X1. 
    X0, X1 = X[:, 0], X[:, 1]
    
    # makes a meshgrid from min-1 to max+1 with intervals of 0.2
    xx, yy = make_meshgrid(X0, X1, lims=lims)
    
    # if axis is None then make axes. 
    if ax is None:
        plt.figure()
        ax = plt.gca()
        show = True
    else:
        show = False
        
    # can abstract some of this into a higher-level function for learners to call
    cs = plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8, proba=proba)
    if proba:
        cbar = plt.colorbar(cs)
        cbar.ax.set_ylabel('probability of red $\Delta$ class', fontsize=20, rotation=270, labelpad=30)
        cbar.ax.tick_params(labelsize=14)
        #ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=30, edgecolors=\'k\', linewidth=1)
    labels = np.unique(y)
    if len(labels) == 2:
        ax.scatter(X0[y==labels[0]], X1[y==labels[0]], cmap=plt.cm.coolwarm, 
                   s=60, c='b', marker='o', edgecolors='k')
        ax.scatter(X0[y==labels[1]], X1[y==labels[1]], cmap=plt.cm.coolwarm, 
                   s=60, c='r', marker='^', edgecolors='k')
    else:
        ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=50, edgecolors='k', linewidth=1)

    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    #     ax.set_xlabel(data.feature_names[0])
    #     ax.set_ylabel(data.feature_names[1])
    if ticks:
        ax.set_xticks(())
        ax.set_yticks(())
        #     ax.set_title(title)
    if show:
        plt.xlabel(xlab)
        plt.ylabel(ylab)
        plt.title(title)
        plt.show()
    else:
        return ax

4. Линейный классификатор SVM —

# Linear SVM Classifier
svm = SVC(kernel='linear')
svm.fit(X, y)

plot_classifier(X, y, svm, "Sepal Length (cm)", "Sepal Width (cm)", "Iris Dataset")

5. Построение опорных векторов линейного классификатора SVM —

# Subsetting the support vectors.
X_small = X[svm.support_]
y_small = y[svm.support_]

# Linear SVM Classifier fitted with the support vectors.
svm_n1 = SVC(kernel='linear')
svm_n1.fit(X_small, y_small)

plot_classifier(X_small, y_small, svm_n1, "Sepal Length (cm)", "Sepal Width (cm)", "Iris Dataset")

6. Классификатор SVM —

# Normal SVM Classifier
svc = SVC()
svc.fit(X, y)

plot_classifier(X, y, svc, "Sepal Length (cm)", "Sepal Width (cm)", "Iris Dataset")

7. Построение опорного вектора классификатора SVM —

# Subsetting the support vectors.
X_small = X[svc.support_]
y_small = y[svc.support_]

# SVM Classifier fitted with the support vectors.
svc_n1 = SVC()
svc_n1.fit(X_small, y_small)

plot_classifier(X_small, y_small, svc_n1, "Sepal Length (cm)", "Sepal Width (cm)", "Iris Dataset")

Как мы видим на приведенных выше графиках, потеря шарнира учитывает только ошибочно предсказанные значения и точки вблизи границы решения. Все остальные точки данных игнорируются и не учитывают классификацию модели.

Я ценю вас и время, которое вы потратили на чтение этого дня!

Линкедин | СтекОверФлоу | Электронная почта