Travaux Pratique sur SVM

L’objectif de cette section de travaux pratiques est de montrer l’utilisation des machines à vecteurs de support (Support Vector Machines, SVM)
pour les problèmes de classification linéaires en python avec Scikit-learn. Pour la documentation de cette bibliothèque visitez : Scikit-learn -SVM

 

Tutorial 2

Auteur: BEN LAHMAR El Habib

Nous traitions un échantillon avec n = 10 observations, p = 2 descripteurs x = (x1, x2) et une variable cible y. Nous l’avons réorganisé comme suit dans le fichier « data_svm.txt ».

 

In [1]:
#package pandas pour la manipulation des données
import pandas
In [6]:
#chargement du fichier texte dans une structure data.frame de Pandas
df = pandas.read_table("data_svm.txt",sep="\t",header=0,index_col=0)
print(df.shape)
 
(10, 3)
In [7]:
#création de deux sous-data.frame correspondants aux individus y=+1 (p) et y=-1 (n)
dfpos = df[df['y']=='p']
dfneg = df[df['y']=='n']
 

Pour la visualisation on vas utiliser une fonction ad-hoc

In [9]:
#fonction pour graphique nuage de points
#entrées : data.frame avec l’ensemble des individus
# data.frame relatifs aux individus positifs et négatifs
def myscatter(df,dfpos,dfneg):
 #nuage de points « blanc » pour définir les dimensions du graphique
 plt.scatter(df.iloc[:,0],df.iloc[:,1],color="white")
 #annotate - positive instances
 for i in dfpos.index:
     plt.annotate(i,xy=(df.loc[i,'x1'],df.loc[i,'x2']),xytext=(-3,-3),textcoords='offset points',color='red')

 #annotate - negative instances
 for i in dfneg.index:
     plt.annotate(i,xy=(df.loc[i,'x1'],df.loc[i,'x2']),xytext=(-3,-3),textcoords='offset points',color='blue')
 return None
#fin de la fonction
 

Visualisation

In [11]:
#importation de la librairie pour les graphiques
import matplotlib.pyplot as plt
#représentation graphique
myscatter(df,dfpos,dfneg)
plt.show()
 
In [12]:
#importation de la classe SVC
from sklearn.svm import SVC
#instanciation de l’objet : noyau linéaire
svm = SVC(kernel='linear')
In [13]:
#apprentissage
svm.fit(df.as_matrix()[:,0:2],df.as_matrix()[:,2])
Out[13]:
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
In [26]:
#voici les données d'apprentissage
df.as_matrix()[:,0:2]
Out[26]:
array([[5, 1],
       [7, 1],
       [9, 4],
       [12, 7],
       [13, 6],
       [1, 3],
       [2, 1],
       [4, 5],
       [6, 9],
       [8, 7]], dtype=object)
 

Maintenant si on veux voir le nombre de points supports et leurs numéros

In [27]:
#les classes n et p
df.as_matrix()[:,2]
Out[27]:
array(['p', 'p', 'p', 'p', 'p', 'n', 'n', 'n', 'n', 'n'], dtype=object)
In [14]:
#nombre de points supports…
print(svm.support_.shape)
#... et leurs numéros
print(df.index[svm.support_])
 
(3,)
Int64Index([2, 5, 6], dtype='int64', name='i')
 

Les poids i des points supports sont également disponibles

In [15]:
#weigth of the support vectors
print(svm.dual_coef_)
 
[[-0.33325096 -0.11109464  0.44434559]]
 

Il nous reste à les représenter dans un graphique en utilisant leurs coordonnées

In [16]:
#coordonnées des points supports c1 pour x1, c2 pour x2
c1 = svm.support_vectors_[:,0]
c2 = svm.support_vectors_[:,1]
#mise en évidence des points supports dans la représentation des points
myscatter(df,dfpos,dfneg)
plt.scatter(c1,c2,s=200,facecolors='none',edgecolors='black')
plt.show()
 
 

Représentation des frontières

L’objet svm fournit automatiquement les coefficients de la droite de séparation lorsque le noyau est linéaire.

In [17]:
#coefficients sont
print(svm.coef_)

#constante 
print(svm.intercept_)
 
[[ 0.66646897 -0.66656782]]
[-1.66597472]
In [18]:
#coordonnées des points pour tracer les droites frontières et « marges »
import numpy as np
xf = np.array([3,12])
yf = -svm.coef_[0][0]/svm.coef_[0][1]*xf-svm.intercept_/svm.coef_[0][1]
xb = np.array([4.5,12])
yb = -svm.coef_[0][0]/svm.coef_[0][1]*xb-(svm.intercept_-1.0)/svm.coef_[0][1]
xh = np.array([2,11])
yh = -svm.coef_[0][0]/svm.coef_[0][1]*xh-(svm.intercept_+1.0)/svm.coef_[0][1]
In [19]:
#représentation graphique
myscatter(df,dfpos,dfneg)
plt.scatter(c1,c2,s=200,facecolors='none',edgecolors='black')
plt.plot(xf,yf,c='green')
plt.plot(xb,yb,c='gray')
plt.plot(xh,yh,c='gray')
plt.show()
 
 

Auteur: BEN LAHMAR El Habib