Machine à vecteurs de support SVM 1D avec python et scikit

Published: 26 août 2014

DMCA.com Protection Status

Exemple de comment appliquer une SVM pour des données à 1 dimension. Considérons le cas suivant: on dispose d'un échantillon de données [attachment:469] avec la première colonne la valeur et la deuxième colonne la classe (deux classes ici: 1 et 2) et on souhaite appliquer une SVM pour déterminer le seuil optimal pour séparer ces deux classes.

Machine à vecteurs de support SVM 1D avec python et scikit
Machine à vecteurs de support SVM 1D avec python et scikit

from sklearn import svm
from scipy import c_

import matplotlib.pyplot as plt
import pylab as pl
import numpy as np

sample_data = np.loadtxt('data.txt')

sample_data_shape = sample_data.shape
SampleSize = sample_data_shape[0]

num_bins = 30

min = np.amin(sample_data)
max = np.amax(sample_data)

res = ( max - min ) / num_bins

counts_01 = np.zeros(num_bins)
counts_02 = np.zeros(num_bins)

for i in range(SampleSize):
    bin = int( ( sample_data[i,0] - min ) / res )

    if sample_data[i,1] == 1:
        if bin == num_bins:
            counts_01[num_bins-1] = counts_01[num_bins-1] + 1 
        else:
            counts_01[bin] = counts_01[bin] + 1 
    else:
        if bin == num_bins:    
            counts_02[num_bins-1] = counts_02[num_bins-1] + 1 
        else:
            counts_02[bin] = counts_02[bin] + 1

fig = plt.figure()

ax = fig.add_subplot(111)

ind = np.arange(min,max,res)

width = res

rects1 = ax.bar(ind+width/2.0, counts_01, width/2.0, color=(0.65098041296005249, 0.80784314870834351, 0.89019608497619629, 1.0), label='Class 1')
rects2 = ax.bar(ind, counts_02, width/2.0, color=(0.69411766529083252, 0.3490196168422699, 0.15686275064945221, 1.0), label='Class 2')

ax.set_ylabel('Counts')

pl.legend()

#---------- SVM 1d ----------#

clf = svm.SVC(kernel='linear')

nullm = np.zeros((SampleSize))
values = c_[nullm,sample_data[:,0]]
clf.fit(values, sample_data[:,1])
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(min, max)
yy = a * xx - (clf.intercept_[0]) / w[1]
xx = [-(clf.intercept_[0]) / w[1],-(clf.intercept_[0]) / w[1]]
yy = [0,np.max(counts_01)+np.max(counts_01)*0.2]
pl.ylim(0,np.max(counts_01)+np.max(counts_01)*0.1)

pl.plot(xx, yy, 'r--')

plt.text(30,200,'SVM: '+str( round( -(clf.intercept_[0]) / w[1],2) ))

plt.savefig('svm_1d_exemple.png')
pl.show()

Recherches associées

Image

of