[PYTHON] Calcul de la machine à vecteurs de support (SVM) (en utilisant cvxopt)

Bonjour. Pour le calcul de la machine à vecteurs de support (SVM), reportez-vous à la procédure (en utilisant cvxopt) dans Une percée sur l'intelligence artificielle "Soft Margin SVM". Si vous le suivez exactement, vous aurez l'impression d'avoir calculé vous-même la solution. Dans [^ 1] ci-dessous, la solution convergente du multiplicateur alpha de Lagrange, tabplot, etc. sont également tracées ( class × prediction == 1 ''). Mettez en surbrillance les données qui deviennent `. Prediction == 0 est la bordure).

$ ./svm.py
file = classification.txt (len=200)

cvxopt result status: optimal
delta = 5.684342e-14
class = ('-1', '+1') 
confusion matrix:
 [[96  7]
 [34 63]]

contour.png tabplot.png alpha.jpg

svm.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# support vector machine (SVM)Calculs de
# cvxopt.solvers.qp (Quadratic Programming)utilisation

from __future__ import print_function
import numpy as np
import cvxopt

Ccoeff = [30, 30]  # soft margin coefficients of class
SIGMA = 1.054  # for non-linear kernel
kname = 'gaussian'

#Noyau RBF gaussien
def gaussian_kernel(x,y):
    gamma = 1 / (2 * (SIGMA ** 2))
    return np.exp(-norm2(x-y) * gamma)

def kernel(x,y):
    return globals()[kname + '_kernel'](x,y)

def norm2(x):
    return np.dot(x, x)

#Trouvez l'alpha multiplicateur de Lagrange avec la programmation quadratique
def QP(dat, clas, Ccoeff):
    coeff = np.array([Ccoeff[x>0] for x in clas])
    N, Z = len(dat), zip(clas, dat)
    Q = cvxopt.matrix(np.array([[c*c_*kernel(d,d_) for c, d in Z] for c_, d_ in Z]))
    p = cvxopt.matrix(-np.ones(N))
    G = cvxopt.matrix(np.vstack((np.diag([-1.0]*N), np.identity(N))))
    h = cvxopt.matrix(np.hstack((np.zeros(N), coeff)))
    A = cvxopt.matrix(clas, (1,N))
    b = cvxopt.matrix(0.0)
    cvxopt.solvers.options['abstol'] = 1e-5
    cvxopt.solvers.options['reltol'] = 1e-10
    cvxopt.solvers.options['show_progress'] = False
    sol = cvxopt.solvers.qp(Q, p, G, h, A, b)
    alpha = np.array(sol['x']).reshape(N)
    print('cvxopt result status: %s' % sol['status'])
    print('delta = %e' % np.dot(alpha, clas))
    return alpha

#Trouvez l'index des vecteurs de support
def SV(dat, clas, Ccoeff, alpha):
    supportVectors = []
    edgeVectors = []
    c = [Ccoeff[x>0] for x in clas]
    infinitesimal = 1e-3 * min(Ccoeff)
    for i in range(len(alpha)):
        if alpha[i] > infinitesimal:
            supportVectors.append(i)
            if alpha[i] < c[i] - infinitesimal:
                edgeVectors.append(i)
    bias = average([clas[i] - prediction(dat[i], alpha, clas, dat, supportVectors) for i in edgeVectors])
    return supportVectors, edgeVectors, bias

def average(x):
    return sum(x)/len(x)

#Valeur prédite
def prediction(x, alpha, clas, dat, supportVectors, bias=0):
    p = [alpha[i] * clas[i] * kernel(x, dat[i]) for i in supportVectors]
    return sum(p) + bias

#Matrice de confusion du tableau de discrimination
def confusion_matrix(clas, predict):
    mat = np.zeros([2, 2], dtype=int)
    for c, p in zip(clas, predict):
        mat[c>0, p>0] += 1
    return mat

#Classification des données supervisée.txt (N = 200)
# http://research.microsoft.com/en-us/um/people/cmbishop/prml/webdatasets/classification.txt
def make_data():
    filename = 'classification.txt'
    dat_clas = np.genfromtxt(filename)
    dat, clas = dat_clas[:,0:2], dat_clas[:,2]
    clas = clas * 2 - 1.0  #Signal de l'enseignant-Convertir en 1 ou 1
    classname = ('-1', '+1')
    print('file = %s (len=%d)' % (filename, len(dat)))
    return dat, clas, classname


def main():
    dat, clas, classname = make_data()

    #Trouver la solution de SVM par la méthode de programmation quadratique
    alpha = QP(dat, clas, Ccoeff)
    supportVectors, edgeVectors, bias = SV(dat, clas, Ccoeff, alpha)

    #Valeur prédite, tableau de discrimination
    predict = [prediction(x, alpha, clas, dat, supportVectors, bias) for x in dat]
    print('class =', classname, '\n', confusion_matrix(clas, predict))

if __name__ == '__main__':
    main()

[^ 1]: C'est le même calcul que dans le chapitre 7 de PRML, mais j'estime que le diagramme de résultat du tracé dans ce livre est un peu lâche dans la convergence de la solution ou le calcul du contour.

Recommended Posts

Calcul de la machine à vecteurs de support (SVM) (en utilisant cvxopt)
Calcul du vecteur normal par convolution
Apprentissage automatique ① Résumé SVM (Support Vector Machine)
[Python] J'ai expliqué en détail la théorie et l'implémentation de la machine à vecteurs de support (SVM).
Machine Learning: Supervisé - Support Vector Machine
Algorithme d'apprentissage automatique (prise en charge de l'application de machine vectorielle)
<Course> Machine Learning Chapitre 7: Support Vector Machine
[Français] scikit-learn 0.18 Guide de l'utilisateur 1.4. Support Vector Machine
Support Vector Machine (pour les débutants) -Code Edition-
J'ai écrit FizzBuzz en python en utilisant la machine à vecteurs de support (bibliothèque LIVSVM).
Essayez d'utiliser le bloc-notes Jupyter à partir d'Azure Machine Learning
Raisonnement causal utilisant l'apprentissage automatique (organisation des méthodes de raisonnement causal)
Calcul de l'itinéraire le plus court selon la méthode de Monte Carlo
Calcul de la similitude entre les phrases à l'aide de Word2Vec (version simplifiée)
Dérivés appris en utilisant Python- (1) Calcul du taux de change à terme-