Machine à vecteurs de soutien (SVM)

Introduction à SVM

Les machines vectorielles de support (SVM) sont des algorithmes d'apprentissage automatique supervisé puissants mais flexibles qui sont utilisés à la fois pour la classification et la régression. Mais généralement, ils sont utilisés dans les problèmes de classification. Dans les années 1960, les SVM ont été introduits pour la première fois, mais ils ont ensuite été affinés en 1990. Les SVM ont leur mode de mise en œuvre unique par rapport aux autres algorithmes d'apprentissage automatique. Dernièrement, ils sont extrêmement populaires en raison de leur capacité à gérer plusieurs variables continues et catégorielles.

Fonctionnement de SVM

Un modèle SVM est essentiellement une représentation de différentes classes dans un hyperplan dans un espace multidimensionnel. L'hyperplan sera généré de manière itérative par SVM afin que l'erreur puisse être minimisée. Le but de SVM est de diviser les ensembles de données en classes pour trouver un hyperplan marginal maximal (MMH).

Les éléments suivants sont des concepts importants dans SVM -

  • Support Vectors- Les points de données les plus proches de l'hyperplan sont appelés vecteurs de support. La ligne de séparation sera définie à l'aide de ces points de données.

  • Hyperplane - Comme on peut le voir sur le schéma ci-dessus, il s'agit d'un plan ou d'un espace de décision qui est divisé entre un ensemble d'objets de classes différentes.

  • Margin- Il peut être défini comme l'écart entre deux lignes sur les points de données placard de différentes classes. Elle peut être calculée comme la distance perpendiculaire de la ligne aux vecteurs de support. Une grande marge est considérée comme une bonne marge et une petite marge est considérée comme une mauvaise marge.

L'objectif principal de SVM est de diviser les ensembles de données en classes pour trouver un hyperplan marginal maximal (MMH) et cela peut être fait dans les deux étapes suivantes -

  • Premièrement, SVM générera des hyperplans de manière itérative qui séparent les classes de la meilleure façon.

  • Ensuite, il choisira l'hyperplan qui sépare correctement les classes.

Implémentation de SVM en Python

Pour implémenter SVM en Python, nous commencerons par l'importation de bibliothèques standard comme suit -

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns; sns.set()

Ensuite, nous créons un exemple de jeu de données, ayant des données linéairement séparables, à partir de sklearn.dataset.sample_generator pour la classification à l'aide de SVM -

from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.50)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer');

Ce qui suit serait la sortie après la génération d'un échantillon de données contenant 100 échantillons et 2 clusters -

Nous savons que SVM prend en charge la classification discriminante. il divise les classes les unes des autres en trouvant simplement une ligne en cas de deux dimensions ou une variété en cas de dimensions multiples. Il est implémenté sur l'ensemble de données ci-dessus comme suit -

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
plt.plot([0.6], [2.1], 'x', color='black', markeredgewidth=4, markersize=12)
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);

La sortie est la suivante -

Nous pouvons voir à partir de la sortie ci-dessus qu'il existe trois séparateurs différents qui distinguent parfaitement les échantillons ci-dessus.

Comme discuté, l'objectif principal de SVM est de diviser les ensembles de données en classes pour trouver un hyperplan marginal maximal (MMH), donc plutôt que de dessiner une ligne zéro entre les classes, nous pouvons dessiner autour de chaque ligne une marge d'une certaine largeur jusqu'au point le plus proche. Cela peut être fait comme suit -

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
   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);

À partir de l'image ci-dessus en sortie, nous pouvons facilement observer les «marges» dans les classificateurs discriminants. SVM choisira la ligne qui maximise la marge.

Ensuite, nous utiliserons le classificateur de vecteurs de support de Scikit-Learn pour entraîner un modèle SVM sur ces données. Ici, nous utilisons un noyau linéaire pour ajuster SVM comme suit -

from sklearn.svm import SVC # "Support vector classifier"
model = SVC(kernel='linear', C=1E10)
model.fit(X, y)

La sortie est la suivante -

SVC(C=10000000000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
kernel='linear', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)

Maintenant, pour une meilleure compréhension, ce qui suit va tracer les fonctions de décision pour SVC 2D -

def decision_function(model, ax=None, plot_support=True):
   if ax is None:
      ax = plt.gca()
   xlim = ax.get_xlim()
   ylim = ax.get_ylim()

Pour évaluer le modèle, nous devons créer une grille comme suit -

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)

Ensuite, nous devons tracer les limites et les marges de décision comme suit -

ax.contour(X, Y, P, colors='k',
   levels=[-1, 0, 1], alpha=0.5,
   linestyles=['--', '-', '--'])

Maintenant, tracez de la même manière les vecteurs de support comme suit -

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)

Maintenant, utilisez cette fonction pour adapter nos modèles comme suit -

plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
decision_function(model);

Nous pouvons observer à partir de la sortie ci-dessus qu'un classificateur SVM s'adapte aux données avec des marges, c'est-à-dire des lignes pointillées et des vecteurs de support, les éléments pivots de cet ajustement, touchant la ligne pointillée. Ces points de vecteur de support sont stockés dans l'attribut support_vectors_ du classifieur comme suit -

model.support_vectors_

La sortie est la suivante -

array([[0.5323772 , 3.31338909],
   [2.11114739, 3.57660449],
   [1.46870582, 1.86947425]])

Noyaux SVM

En pratique, l'algorithme SVM est implémenté avec un noyau qui transforme un espace de données d'entrée dans la forme requise. SVM utilise une technique appelée l'astuce du noyau dans laquelle le noyau prend un espace d'entrée de faible dimension et le transforme en un espace de dimension supérieure. En termes simples, le noyau convertit les problèmes non séparables en problèmes séparables en y ajoutant plus de dimensions. Cela rend SVM plus puissant, plus flexible et plus précis. Voici quelques-uns des types de noyaux utilisés par SVM -

Noyau linéaire

Il peut être utilisé comme produit scalaire entre deux observations quelconques. La formule du noyau linéaire est la suivante -

k (x, x i ) = somme (x * x i )

À partir de la formule ci-dessus, nous pouvons voir que le produit entre deux vecteurs dit & est la somme de la multiplication de chaque paire de valeurs d'entrée.

Noyau polynomial

Il s'agit d'une forme plus généralisée de noyau linéaire et distingue l'espace d'entrée courbe ou non linéaire. Voici la formule du noyau polynomial -

K (x, xi) = 1 + somme (x * xi) ^ d

Ici, d est le degré de polynôme, que nous devons spécifier manuellement dans l'algorithme d'apprentissage.

Noyau de fonction de base radiale (RBF)

Le noyau RBF, principalement utilisé dans la classification SVM, cartographie l'espace d'entrée dans un espace dimensionnel indéfini. La formule suivante l'explique mathématiquement -

K (x, xi) = exp (-gamma * somme ((x - xi ^ 2))

Ici, le gamma va de 0 à 1. Nous devons le spécifier manuellement dans l'algorithme d'apprentissage. Une bonne valeur par défaut de gamma est 0,1.

Comme nous avons implémenté SVM pour les données linéairement séparables, nous pouvons l'implémenter en Python pour les données qui ne sont pas linéairement séparables. Cela peut être fait en utilisant des noyaux.

Exemple

Voici un exemple de création d'un classificateur SVM à l'aide de noyaux. Nous utiliserons le jeu de données iris de scikit-learn -

Nous allons commencer par importer les packages suivants -

import pandas as pd
import numpy as np
from sklearn import svm, datasets
import matplotlib.pyplot as plt

Maintenant, nous devons charger les données d'entrée -

iris = datasets.load_iris()

À partir de cet ensemble de données, nous prenons les deux premières caractéristiques comme suit -

X = iris.data[:, :2]
y = iris.target

Ensuite, nous allons tracer les limites SVM avec les données d'origine comme suit -

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 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))
X_plot = np.c_[xx.ravel(), yy.ravel()]

Maintenant, nous devons fournir la valeur du paramètre de régularisation comme suit -

C = 1.0

Ensuite, l'objet classificateur SVM peut être créé comme suit -

Svc_classifier = svm.SVC (noyau = 'linéaire', C = C) .fit (X, y)

Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('Support Vector Classifier with linear kernel')

Production

Text(0.5, 1.0, 'Support Vector Classifier with linear kernel')

Pour créer un classificateur SVM avec rbf noyau, nous pouvons changer le noyau en rbf comme suit -

Svc_classifier = svm.SVC(kernel='rbf', gamma =‘auto’,C=C).fit(X, y)
Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('Support Vector Classifier with rbf kernel')

Production

Text(0.5, 1.0, 'Support Vector Classifier with rbf kernel')

Nous mettons la valeur de gamma à «auto» mais vous pouvez également fournir sa valeur entre 0 et 1.

Avantages et inconvénients des classificateurs SVM

Avantages des classificateurs SVM

Les classificateurs SVM offrent une grande précision et fonctionnent bien avec un espace dimensionnel élevé. Les classificateurs SVM utilisent essentiellement un sous-ensemble de points d'entraînement, donc le résultat utilise très moins de mémoire.

Inconvénients des classificateurs SVM

Ils ont un temps de formation élevé et ne conviennent donc pas en pratique aux grands ensembles de données. Un autre inconvénient est que les classificateurs SVM ne fonctionnent pas bien avec des classes qui se chevauchent.