[Python] J'ai expliqué en détail la théorie et l'implémentation de la machine à vecteurs de support (SVM).

introduction

Cette fois, je vais résumer la théorie sur la machine à vecteurs de support, qui est l'un des algorithmes d'apprentissage automatique.

Je vous serais reconnaissant si vous pouviez vous entendre avec moi.

Soutenir la théorie de la machine vectorielle

Résumons d'abord la théorie des machines à vecteurs de support.

Marge dure et marge souple

La machine à vecteurs de support (svm) est l'un des algorithmes d'apprentissage automatique souvent utilisés dans le domaine de l'analyse de données en raison de ses performances de généralisation et de son large éventail de domaines d'application.

Il est principalement utilisé pour les problèmes de classification binaire basés sur l'idée de maximiser les marges. Elle peut également être appliquée à des problèmes de classification et de régression multi-classes.

Il a la faiblesse de ne pas convenir aux grands ensembles de données en raison de son coût de calcul élevé par rapport à d'autres algorithmes d'apprentissage automatique.

La marge qui suppose des données linéairement séparables (divisées en deux par une ligne droite) est appelée `` marge ferme '', et la marge qui permet une discrimination erronée sur la base de données séparables non linéairement est appelée marge souple. Je vais.

J'ai écrit que la séparabilité linéaire peut être divisée en deux par une ligne droite, mais comme ce n'est que pour les données bidimensionnelles, je généralise le concept de séparabilité linéaire à un ensemble sur un espace à n dimensions. La capacité de se séparer dans un superplan de dimension n-1 est définie comme séparable linéairement.

Lorsque des données sur un plan bidimensionnel peuvent être classées par une ligne unidimensionnelle, on dit qu'elles sont linéairement séparables. De plus, lorsque les données dans l'espace tridimensionnel peuvent être classées par le plan bidimensionnel, on peut dire que la séparation linéaire est possible.

De cette manière, le plan dimensionnel n-1 (pas strictement un plan) qui classifie les données dimensionnelles n est appelé le "superplan séparé", et la distance entre le superplan séparé et les données les plus proches du superplan séparé. Est appelé la «marge», et le but de cet algorithme est de maximiser cette marge.

De plus, les données les plus proches du "superplan séparé" sont appelées le "vecteur de support". Illustré ci-dessous.

image.png

Il est intuitivement clair que vous pouvez augmenter la précision en créant un «superplan» qui maximise la «marge» indiquée sur la figure.

Cette fois, les données sont représentées en deux dimensions à des fins d'illustration, mais pensez aux données dans un espace à n dimensions comme étant divisées par un superplan à n-1 dimensions.

Dans l'espace vectoriel numérique à deux dimensions, la ligne droite qui divise les deux données peut être exprimée comme $ ax + by + c = 0 $ comme indiqué dans la figure ci-dessus, et les paramètres $ a, b, c $ sont ajustés. Ce faisant, vous pouvez représenter toutes les lignes droites.

Équation de superplan dans un espace vectoriel numérique à n dimensions

Cette fois, nous supposons un superplan sur l'espace vectoriel numérique à n dimensions, donc la formule pour ce superplan est donnée par la formule suivante. Considérons maintenant le cas où il y a un total de N données.

W^TX_i + b = 0 \quad (i = 1, 2, 3, ...N)

Utilisons maintenant cette équation d'hyperplan pour dériver l'équation utilisée pour optimiser la marge dure (un problème linéairement séparable).

Dérivation de la formule d'optimisation de la marge dure

Le calcul de la partie de $ W ^ TX_i + b = 0 $ donne $ w_1x_1 + w_2x_2 + ... w_nx_n + b = 0 $, qui est une équation en ligne droite à deux dimensions $ ax + by + c = 0 $ Vous pouvez comprendre intuitivement qu'il s'agit d'une équation de superplan qui s'étend à n dimensions.

Considérant que les données triangulaires de la figure appartiennent à l'ensemble de $ K_1 $ et que les données en étoile de la figure appartiennent à l'ensemble de $ K_2 $, nous pouvons voir que l'équation suivante est satisfaite.

W^TX_i + b > 0 \quad (X_i \in K_1)\\
W^TX_i + b < 0 \quad (X_i \in K_2)

Introduisez la variable d'étiquette t pour représenter cette expression ensemble.

Soit $ t_i = 1 $ lorsque la i-ème donnée $ x_i $ appartient à la classe 1 et $ t_i = -1 $ lorsqu'elle appartient à la classe 2.

t_i = \left\{
\begin{array}{ll}
1 & (X_i \in K_1) \\
-1 & (X_i \in K_2)
\end{array}
\right.

En utilisant $ t_i $ défini de cette manière, l'expression conditionnelle peut être exprimée comme suit.

t_i(W^TX_i + b) > 0 \quad (i = 1, 2, 3, ...N)

De cette manière, l'expression conditionnelle pourrait être exprimée sur une ligne.

La marge est la distance entre un point dans un espace à n dimensions et un superplan, passons donc en revue la distance entre un point et une ligne droite. La distance entre un point bidimensionnel et une ligne droite est exprimée par la formule suivante, en supposant que le point est $ A (x_0, y_0) $ et la ligne droite est $ l: ax + by + c = 0 $.

d = \frac{|ax_0 + by_0 + c|}{\sqrt{a^2+b^2}}

La distance entre un point dans l'espace à n dimensions et le superplan est exprimée par la formule suivante.

d = \frac{|w_1x_1 + w_2x_2... + w_nx_n + b|}{\sqrt{w_1^2+w_2^2...+w_n^2}} = \frac{|W^TX_i + b|}{||w||}

Par conséquent, la condition pour maximiser la marge M à partir des équations ci-dessus est exprimée par l'équation suivante.

max_{w, b}M, \quad \frac{t_i(W^TX_i + b)}{||W||} \geq M  \quad (i = 1, 2, 3, ...N)

Je ne suis pas sûr, alors je vais l'expliquer.

Certaines donnéesX_aQuand tu as choisiX_aEt super avionW^TX + b=0La distance à$ \frac{t_i(W^TX_a + b)}{||W||}$Il est exprimé comme.

|W^TX_a + b|Avec la variable d'étiquette tt_i(W^TX_a + b)Il est exprimé comme.

Aussi,max_{w, b}MEst une variablew, bCela signifie maximiser M sous$\frac{t_i(W^TX_i + b)}{||W||} \geq M $La condition signifie que la distance entre le superplan et toutes les données doit être supérieure à la marge M.

Par conséquent, trouver M qui satisfait cette formule optimise la machine à vecteurs de support.

ici,$\frac{t_i(W^TX_i + b)}{||W||} \geq M $Divisez les deux côtés de par M et introduisez les conditions suivantes.

\frac{W}{M||W||} = \tilde{W}\\
\frac{b}{M||W||} = \tilde{b}

Ensuite, l'expression conditionnelle du problème d'optimisation est exprimée comme suit.

t_i(\tilde{W^T}X_i + \tilde{b}) \geq 1

La formule ci-dessus est valable pour toutes les données, mais $ X_i $ lorsque l'égalité est vraie est $ X_i $ pour les données les plus proches.

En d'autres termes, $ \ tilde {M} $, qui est une marge simplifiée M, est exprimé par la formule suivante.

\tilde{M} = \frac{t_i(\tilde{W^T}X_i + \tilde{b})}{||\tilde{W}||} = \frac{1}{||\tilde{W}||}

Avec cette transformation d'équation, le problème d'optimisation est le suivant.

max_{\tilde{W}, \tilde{b}}\frac{1}{||\tilde{W}||}, \quad t_i(\tilde{W^T}X_i + \tilde{b}) \geq 1 \quad (i = 1, 2, 3, ...N)

Cela devient assez difficile. Continuez.

La tilda a été attachée en raison de la transformation de la formule en cours de route, mais supprimons-la par souci de simplicité. Et\frac{1}{||\tilde{W}||}Pour la partie, cela signifie maximiser l'inverse de la norme, donc par souci de simplicité, convertissons la norme en un problème qui minimise le carré. La transformation de formule de cette partie est un petit coup de pouce. Pour simplifier les calculs ultérieurs\frac{1}{2}Je vais mettre.

min_{W, b}\frac{1}{2}||W||^2, \quad t_i(W^TX_i + b)\geq 1 \quad (i = 1, 2, 3, ...N)

Résoudre l'équation ci-dessus, c'est-à-diret_i(W^TX_i + b)\geq 1Sous condition\frac{1}{2}||W||^2Vous pouvez maximiser la marge en la minimisant. C'est la formule du problème d'optimisation lorsqu'il est séparable linéairement.

Cependant, cette condition ne peut résoudre que des problèmes séparables linéairement. Autrement dit, il ne peut être appliqué qu'aux marges dures.

Assouplissons les contraintes pour que cette formule puisse également être appliquée aux marges douces.

Dérivation de la formule d'optimisation de la marge souple

Desserrons la condition de contrainte $ t_i (W ^ TX_i + b) \ geq 1 $ dans la formule ci-dessus afin que nous puissions traiter le problème (marge souple) qui ne peut pas être séparé linéairement.

Illustré ci-dessous.

image.png

Considérons le problème de l'inséparabilité linéaire comme le montre cette figure. Comme indiqué par la flèche rouge sur la figure, les données sont entrées à l'intérieur de la marge.

Compte tenu de l'histoire jusqu'à présent, il est naturel que le vecteur de support (les données les plus proches du superplan) existe sur le superplan qui satisfait $ W ^ TX_i + b = 1 $.

Les données indiquées par la flèche rouge sur la figure ne satisfont pas $ t_i (W ^ TX_i + b) \ geq 1 $, mais elles peuvent satisfaire la condition $ t_i (W ^ TX_i + b) \ geq 0.5 $.

Par conséquent, relâchons la contrainte en introduisant la variable slug $ \ xi $. Il est défini comme suit.

t_i(W^TX_i + b)\geq 1 - \xi_i \\
\xi_i = max\Bigl\{0, M - \frac{t_i(W^TX_i + b)}{||W||}\Bigr\}

À partir de la formule ci-dessus, nous ne relâcherons la contrainte que si les données sont à l'intérieur de la marge.

Par conséquent, en introduisant cette variable slug, le problème d'optimisation des marges devient le suivant.

min_{W, \xi}\Bigl\{\frac{1}{2}||W||^2 + C\sum_{i=1}^{N} \xi_i\Bigr\} \condition de contrainte quad\quad
t_i(W^TX_i + b)\geq 1 - \xi_i\\
\xi_i = max\Bigl\{0, M - \frac{t_i(W^TX_i + b)}{||W||}\Bigr\}\\
i = 1, 2, 3, ... N

Essayer de maximiser la marge, c'est-à-dire\frac{1}{2}||W||^2Bien sûr, si vous minimisez, plus de données entreront dans la marge.C\sum_{i=1}^{N} \xi_iAugmentera. Par conséquent, ce problème d'optimisation est à minimiser tout en équilibrant les deux termes contradictoires.

C'est un hyperparamètre C, et nous l'ajusterons pour construire le modèle.

Avis jusqu'à présent

Jusqu'à présent, nous avons dérivé les équations du problème d'optimisation dans les marges dures et souples. Il est résumé ci-dessous.

Quand c'est une marge dure

min_{W, b}\frac{1}{2}||W||^2, \quad t_i(W^TX_i + b)\geq 1 \quad (i = 1, 2, 3, ...N)

Au moment de la marge douce

min_{W, \xi}\Bigl\{\frac{1}{2}||W||^2 + C\sum_{i=1}^{N} \xi_i\Bigr\} \quad \quad
t_i(W^TX_i + b)\geq 1 - \xi_i\\
\xi_i = max\Bigl\{0, M - \frac{t_i(W^TX_i + b)}{||W||}\Bigr\}\\
i = 1, 2, 3, ... N

La marge souple a été utilisée pour les problèmes qui n'étaient pas séparables linéairement, et la marge rigide a été utilisée pour les problèmes qui étaient séparables linéairement.

Résoudre les problèmes d'optimisation

Pensons maintenant à résoudre le problème d'optimisation.

Lors de la résolution de ce problème d'optimisation, il est rare de résoudre directement l'équation ci-dessus.

La formule ci-dessus est appelée le "problème principal" du problème d'optimisation, mais dans de nombreux cas, au lieu de résoudre directement ce "problème principal", ce "problème principal" est appelé le "problème double" sous une autre forme. Nous allons résoudre le problème d'optimisation en le convertissant en formule et en résolvant la formule.

Utilisons maintenant la méthode du multiplicateur indéterminé de Lagrange pour résoudre ce problème d'optimisation.

Veuillez vous référer à l'article ici pour la méthode du multiplicateur indéterminé de Lagrange.

Veuillez noter que je ne le comprends pas entièrement, je pense donc que certaines parties manquent de rigueur. Je vais vous expliquer brièvement.

À propos de la méthode du multiplicateur indécis de Lagrange

La méthode du multiplicateur indéterminé de Lagrange est une méthode typique pour les problèmes d'optimisation contraints.

Considérons le cas où la fonction objectif $ f (X) $ est minimisée sous la condition de n contraintes d'inégalité $ g (X) _i \ leqq0, i = 1, 2, 3, ... n $.

Tout d'abord, définissez la fonction de Lagrange suivante.

L(X, α) = f(X) + \sum_{i=1}^{n}α_ig_i(X)

Ce problème d'optimisation contraint par l'inégalité aboutit au problème de trouver $ (\ tilde {X}, \ tilde {α}) $ qui satisfont les quatre conditions suivantes pour la fonction de Lagrange.

 \frac{\partial L(X, α)}{\partial X}=0\\
\frac{\partial L(X, α)}{\partial α_i} = g_i(X)\leqq 0, \quad (i=1, 2,... n)\\
0 \leqq α, \quad (i = 1,2, ...n)\\
α_ig_i(X) = 0, \quad (i = 1, 2,...n)

De cette manière, au lieu de résoudre directement le problème d'optimisation, il est possible de résoudre le problème d'optimisation en utilisant une autre équation en utilisant la méthode du multiplicateur indéterminé de Lagrange. Vous avez appelé cette autre formule le "double problème".

S'applique aux problèmes d'optimisation

Appliquons maintenant la méthode du multiplicateur indéterminé de Lagrange à l'équation de marge souple de la machine à vecteurs de support.

La fonction objectif est:

min_{W, \xi}\Bigl\{\frac{1}{2}||W||^2 + C\sum_{i=1}^{N} \xi_i\Bigr\} 

La contrainte d'inégalité est:

t_i(W^TX_i + b)\geq 1 - \xi_i \quad \xi_i \geq 0 \quad i = 1, 2,...N

Cette fois, toutes les n données ont deux contraintes d'inégalité, donc si les multiplicateurs de Lagrange sont α et β, la fonction de Lagrange sera la suivante.

L(W,b,\xi,α,β)=\frac{1}{2}||W||^2 + C\sum_{i=1}^{N} \xi_i-\sum_{i=1}^{N}α_i\bigl\{t_i(W^TX_i+b)-1+\xi_i\bigl\}-\sum_{i=1}^{N}β_i\xi_i

Lors de la résolution d'un problème d'optimisation, les conditions suivantes sont remplies:

\frac{\partial L(W,b,\xi,α,β)}{\partial W}= W - \sum_{i=1}^{N}α_it_iX_i=0\\
\frac{\partial L(W,b,\xi,α,β)}{\partial b}= -\sum_{i=1}^{N}α_it_i = 0\\
\frac{\partial L(W,b,\xi,α,β)}{\partial W} = C - α_i -β_i = 0

Voici un résumé de ces trois formules.

W =\sum_{i=1}^{N}α_it_iX_i\\
\sum_{i=1}^{N}α_it_i = 0\\
C = α_i + β_i 

En remplaçant ces trois formules dans la fonction de Lagrange et en faisant de notre mieux pour calculer, la formule avec seulement la variable α est comme indiqué ci-dessous.

\tilde{L}(α) = \sum_{i=1}^{N}α_i - \frac{1}{2}\sum_{i=1}^{N}\sum_{i=j}^{N}α_iα_jt_it_j{X_i}^TX_j

De plus, puisque α est égal ou supérieur à 0, le problème dual trouvera α qui satisfait les conditions suivantes.

max\Bigl\{{\tilde{L}(α) = \sum_{i=1}^{N}α_i - \frac{1}{2}\sum_{i=1}^{N}\sum_{i=j}^{N}α_iα_jt_it_j{X_i}^TX_j\Bigr\}}\\
\sum_{i=1}^{N}α_it_i = 0, \quad 0 \leqq α_i \leqq C, i = 1,2,...N

De cette manière, nous avons pu dériver la formule du double problème de la machine à vecteurs de support dans la marge souple.

Maintenant, résumons la méthode du noyau, qui est l'une des méthodes pour résoudre facilement ce double problème.

À propos de la méthode du noyau

Expliquons la méthode du noyau.

Regardons maintenant une citation de Wikipedia.

La méthode du noyau (méthode du noyau, anglais: méthode du noyau) est l'une des méthodes utilisées dans la reconnaissance de formes, et est utilisée en combinaison avec des algorithmes tels que la discrimination. Une méthode bien connue consiste à l'utiliser en combinaison avec une machine à vecteurs de support. Le but de la reconnaissance de formes est généralement de trouver et d'étudier la structure des données (par exemple les groupes, les classements, les composants principaux, les corrélations, les classifications). Pour atteindre cet objectif, la méthode du noyau mappe les données sur un espace d'entités de grande dimension. Chaque coordonnée de l'espace d'entités correspond à une entité de l'élément de données et l'ensemble de données est converti en un ensemble de points dans l'espace euclidien par mappage à l'espace d'entités (mappage d'entités). Diverses méthodes sont utilisées en combinaison avec la méthode du noyau lors de l'analyse de la structure des données dans l'espace des fonctionnalités. Une variété de mappages peuvent être utilisés comme mappages de caractéristiques (généralement des mappages non linéaires sont utilisés), et des structures de données variées en conséquence peuvent être trouvées.

Vous pouvez considérer la méthode du noyau comme une méthode de mappage et de séparation des données de faible dimension en données de haute dimension.

Strictement différent, mais une compréhension approximative convient ici.

Voyons maintenant pourquoi la méthode du noyau est utilisée dans les machines vectorielles de support.

Pourquoi prendre en charge les machines vectorielles utilisent la méthode du noyau

Prenons le cas de la classification des deux types de données suivants.

image.png

Dans le cas de telles données bidimensionnelles, il n'est pas possible de séparer deux types de données par une ligne droite unidimensionnelle.

Étendons ces données aux données multidimensionnelles pour traiter ce problème linéairement inséparable.

Plus précisément, lors du développement des données bidimensionnelles $ X = (x_1, x_2) $ en cinq dimensions, elles sont mappées via la fonction suivante.

ψ(X) = (x^2_1, x^2_2, x_1x_2, x_1, x_2)

De cette manière, l'extension de la dimension de données à une dimension supérieure est appelée «espace de caractéristiques de haute dimension», tandis que l'espace des premières données d'entrée est appelé «espace d'entrée».

Généralisons la formule ci-dessus. La fonction qui mappe les données dans l'espace d'entrée à n dimensions vers l'espace de caractéristiques à r dimensions supérieures est définie comme suit.

ψ(X) = (φ_1(X), φ_2(X), φ_3(X), ...φ_r(X))

Les fonctions telles que $ φ_1 (X) $ sont des fonctions qui combinent les données de la fonction d'origine et ajoutent des modifications.

Lorsque les données sont développées dans un espace de caractéristiques de grande dimension à l'aide d'une telle fonction, elles deviennent des données qui peuvent être séparées par un superplan de séparation à un certain stade. En d'autres termes, au final, si chaque donnée est étendue à une autre dimension, et s'il y a n données, elle peut être étendue à n dimensions, elle peut toujours être séparée par un superplan de séparation de n-1 dimension.

En d'autres termes, il se transforme en données linéairement séparables.

Après cela, en rétrocédant ce super plan séparé et en le convertissant en super plan séparé des données d'origine, la courbe qui sépare les données dans l'espace d'entrée (à proprement parler, la courbe est étendue à une dimension d'une dimension plus petite que l'espace d'entrée. Vous pouvez obtenir ce que vous avez fait).

Considérons maintenant l'équation du problème d'optimisation dans l'espace des fonctionnalités de haute dimension.

Avant de considérer la formule du problème d'optimisation de l'espace de caractéristiques de grande dimension, il s'agit d'un examen du problème d'optimisation de l'espace d'entrée.

Examen des problèmes d'optimisation de l'espace d'entrée

max\Bigl\{{\tilde{L}(α) = \sum_{i=1}^{N}α_i - \frac{1}{2}\sum_{i=1}^{N}\sum_{i=j}^{N}α_iα_jt_it_j{X_i}^TX_j\Bigr\}}\\
\sum_{i=1}^{N}α_it_i = 0, \quad 0 \leqq α_i \leqq C, i = 1,2,...N

Les données dans l'espace des fonctionnalités à haute dimension sont un mappage des données dans l'espace d'entrée $ X_i ^ T $, $ X_j $ 1 en utilisant la fonction $ ψ (X) $, donc le problème d'optimisation dans l'espace des fonctionnalités à haute dimension est le suivant. Sera.

max\Bigl\{{\tilde{L}(α) = \sum_{i=1}^{N}α_i - \frac{1}{2}\sum_{i=1}^{N}\sum_{i=j}^{N}α_iα_jt_it_j{ψ(X)_i}^Tψ(X)_j\Bigr\}}\\
\sum_{i=1}^{N}α_it_i = 0, \quad 0 \leqq α_i \leqq C, i = 1,2,...N

Vous pouvez voir que ce problème d'optimisation doit être résolu dans l'espace des fonctionnalités à haute dimension.

Utilisez la méthode du noyau

Les problèmes ici sont:

{ψ(X)_i}^Tψ(X)_j

Plus l'espace des fonctionnalités est élevé, plus la quantité de calcul dans ce terme sera ridicule.

Une méthode qui simplifie le calcul de cette partie est appelée une astuce du noyau.

Définissez la fonction du noyau comme suit:

K(X_i, X_j) = {ψ(X)_i}^Tψ(X)_j

C'est un peu délicat, mais vous pouvez utiliser cette fonction du noyau pour calculer le produit interne sans calculer directement $ ψ (X) $.

De cette façon, pour calculer le produit intérieur sans calculer directement $ ψ (X) $, il faut satisfaire certaines conditions, mais ~~ je ne comprends pas ~~ C'est difficile à expliquer, donc c'est utile Je publierai uniquement le site qui devient.

Théorème de Mercer [Noyau de valeur correcte](http://ibisforest.org/index.php?%E6%AD%A3%E5%AE%9A%E5%80%A4%E3%82%AB%E3%83%BC%E3 % 83% 8D% E3% 83% AB)

Cette méthode est très utile car $ ψ (X) $ n'apparaît que sous la forme d'un produit interne dans un problème dual.

Les trois fonctions du noyau suivantes sont utilisées.

Noyau gaussien

K(X_i, X_j) = exp\bigl\{-\frac{||X_i -X_j||^2}{2σ^2}\bigl\}

Noyau de polygone

K(X_i, X_j) = (X_i^TX_j + c)^d

`` Noyau Sigmaid ''

K(X_i, X_j) = tanh(bX_i^TX_j + c)

Regardons maintenant un exemple concret dans lequel le produit interne peut être facilement calculé par le noyau polymorphe.

Exemple spécifique de méthode du noyau

Considérez une fonction qui mappe un espace d'entrée bidimensionnel à un espace d'entités tridimensionnel, comme illustré ci-dessous.

ψ(X) = ψ(x_1, x_2) = (x_1^2, \sqrt{2}x_1x_2, x_2^2)

En utilisant cette fonction, les deux vecteurs bidimensionnels X et Y sont les suivants.

ψ(X) = ψ(x_1, x_2) = (x_1^2, \sqrt{2}x_1x_2, x_2^2)\\
ψ(Y) = ψ(y_1, y_2) = (y_1^2, \sqrt{2}y_1y_2, y_2^2)

Considérons le produit interne de ceux-ci.

\begin{align}
ψ(X)^Tψ(Y) & = (x_1^2, \sqrt{2}x_1x_2, x_2^2)^T(y_1^2, \sqrt{2}y_1y_2, y_2^2)\\
&=x_1^2y_1^2 + 2x_1y_1x_2y_2 + x_2^2y_2^2\\
&= (x_1y_1 + x_2y_2)^2\\
&=((x_1,x_2)^T(y_1,y_2))^2\\
&=(X^TY)^2

\end{align}

De cette façon, $ ψ (X) ^ Tψ (Y) $ peut être calculé en mettant au carré le produit intérieur du vecteur original sans calculer directement $ ψ (X) ^ Tψ (Y) $. Je vais.

Si vous voulez en savoir plus sur la méthode du noyau, veuillez vous référer à l'article ici.

Maintenant, résumons l'implémentation de la machine vectorielle de support.

Soutenir la mise en œuvre de la machine vectorielle

Problème de classification: marge dure

Nous allons implémenter svm qui sépare les données linéairement séparables.

Les données utilisées sont le jeu de données iris.

À propos du jeu de données iris

les données d'iris sont des données d'une variété de fleurs appelée iris.

Il existe 50 données sur chacune des trois variétés d'iris, «Setosa», «Virginica» et «Virginica», pour un total de 150 données.

Regardons réellement le contenu.

from sklearn.datasets import load_iris
import pandas as pd

iris = load_iris()
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)

print(iris_df.head())

sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) 0 5.1 3.5 1.4 0.2 1 4.9 3.0 1.4 0.2 2 4.7 3.2 1.3 0.2 3 4.6 3.1 1.5 0.2 4 5.0 3.6 1.4 0.2

Puisque chaque nom de colonne est stocké dans iris.feature_names, vous pouvez afficher les données ci-dessus en les passant à l'argument de Dataframe of pandas.

«Sepal Length» stocke la longueur du pétale, «Sepal Width» stocke la largeur du pétale, «Petal length» stocke la longueur du pétale et «Petal Width» stocke les données de largeur du pétale. Je suis.

Vous pouvez afficher l'étiquette de réponse correcte comme indiqué ci-dessous.

print(iris.target)

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

De cette manière, les variétés d'iris «setosa», «versicolor» et «virginica» sont fixées respectivement à 0, 1 et 2.

C'est la fin de l'explication des données d'iris.

la mise en oeuvre

Créons un ensemble de données avec le code suivant.

import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
import mglearn

iris = load_iris()
X = iris.data[:100, 2:]
Y = iris.target[:100]
print(X.shape)
print(Y.shape)

(100, 2) (100,)

Cette fois, nous classerons en utilisant les données de «longueur de pétale» et «largeur de pétale» de «setosa» et «versicolor».

Dessinez les données avec le code suivant.

mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.legend(['setosa', 'versicolor'], loc='best')
plt.show()

image.png

Le code de mglearn.discrete_scatter (X [:, 0], X [:, 1], Y) prend l'axe X comme premier argument, l'axe Y comme deuxième argument et l'étiquette de réponse correcte comme troisième argument, et scatter Faites un complot.

loc = 'best' ajuste la légende pour qu'elle ne gêne pas le graphique.

À partir des données ci-dessus, vous pouvez clairement voir qu'il peut être séparé par une ligne droite. C'est plutôt trop facile.

Créons un modèle avec le code suivant.

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, stratify=Y, random_state=0)
svm = LinearSVC()
svm.fit(X_train, Y_train)

La création du modèle elle-même se termine par ce code. C'est facile.

Illustrons à quoi ressemble le modèle avec le code ci-dessous.

plt.figure(figsize=(10, 6))
mglearn.plots.plot_2d_separator(svm, X)
mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(['setosa', 'versicolor'], loc='best')
plt.show()

image.png

Vous pouvez voir que les limites qui séparent les données sont créées.

La partie de mglearn.plots.plot_2d_separator (svm, X) est un peu déroutante, je vais donc l'expliquer. Vérifions le code de définition.

plot_2d_separator(classifier, X, fill=False, ax=None, eps=None, alpha=1,cm=cm2, linewidth=None, threshold=None,linestyle="solid"):

Il s'agit d'une fonction qui trace une ligne de démarcation lorsque vous passez le modèle de classification comme premier argument et les données d'origine comme deuxième argument.

Ceci conclut l'implémentation du modèle svm pour les problèmes linéairement séparables.

Problème de classification: marge souple

Cette fois, nous aborderons la question des marges souples.

import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
import mglearn

iris = load_iris()

X = iris.data[50:, 2:]
Y = iris.target[50:] - 1

mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.legend(['versicolor', 'virginica'], loc='best')
plt.show()

image.png

Maintenant, nous traçons les données pour la «longueur du pétale» et la «largeur du pétale» pour «versicolor» et «verginica».

C'est un problème impossible à séparer complètement linéairement.

Voici un examen de la formule de marge souple. Pour la dérivation, reportez-vous à l'article ici.

min_{W, \xi}\Bigl\{\frac{1}{2}||W||^2 + C\sum_{i=1}^{N} \xi_i\Bigr\} \quad \quad
t_i(W^TX_i + b)\geq 1 - \xi_i\\
\xi_i = max\Bigl\{0, M - \frac{t_i(W^TX_i + b)}{||W||}\Bigr\}\\
i = 1, 2, 3, ... N

Puisque les données pénètrent dans la marge, la limite a été assouplie par le terme $ C \ sum_ {i = 1} ^ {N} \ xi_i $.

La valeur de ce C est 1.0 par défaut dans skleaarn. Changeons ce nombre et voyons comment le chiffre change. Le code suivant définit une fonction qui trace les limites du modèle données aux arguments.

def make_separate(model):
    mglearn.plots.plot_2d_separator(svm, X)
    mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
    plt.xlabel('petal length')
    plt.ylabel('petal width')
    plt.legend(['setosa', 'versicolor'], loc='best')
    plt.show()

Dessinons la figure avec le code suivant. Soit «C = 0,1».

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, stratify=Y, random_state=0)
svm = LinearSVC(C=0.1)
svm.fit(X_train, Y_train)
make_separate(svm)
print(svm.score(X_test, Y_test))

0.96

image.png

Vient ensuite «C = 1.0».

svm = LinearSVC(C=1.0)
svm.fit(X_train, Y_train)
make_separate(svm)
print(svm.score(X_test, Y_test))

1.0

image.png

Vient ensuite «C = 100».

svm = LinearSVC(C=100)
svm.fit(X_train, Y_train)
make_separate(svm)
print(svm.score(X_test, Y_test))

1.0

image.png

Il est important de définir un C. Il semble bon de voir la situation tout en changeant diverses choses.

C'est la fin de la mise en œuvre de la marge douce.

Maintenant, résumons l'implémentation lorsque la méthode du noyau est utilisée et l'implémentation lorsqu'elle n'est pas utilisée.

Implémenté sans utiliser la méthode du noyau

Cette fois, nous classerons les problèmes qui ne peuvent pas être séparés linéairement sans utiliser la méthode du noyau.

Ici, la méthode qui n'utilise pas la fonction kernel est définie comme n'utilisant pas la méthode kernel.

Préparons les données avec le code suivant et illustrons-le.

import mglearn
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC

moons = make_moons(n_samples=300, noise=0.2, random_state=0)

X = moons[0]
Y = moons[1]
plt.figure(figsize=(12, 8))
mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.plot()
plt.show()

image.png

make_moons est une fonction qui crée des données en forme de lune bidimensionnelle.

Vous pouvez définir le nombre d'échantillons et de bruit.

Comme vous pouvez le voir sur la figure, il est clairement impossible de séparer linéairement.

Mappons les données de cet espace d'entrée aux données de l'espace des caractéristiques de dimension supérieure afin de transformer ces données séparables de manière non linéaire en données séparables linéairement.

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, stratify=Y, random_state=0)
poly = PolynomialFeatures(degree=2)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.fit_transform(X_test)

Avec cela, les données dans l'espace d'entrée peuvent être mappées à l'espace d'entités de grande dimension.

Vérifions quel type de données a été mappé.

print(poly.get_feature_names())
print(X_train_poly.shape)

['1', 'x0', 'x1', 'x0^2', 'x0 x1', 'x1^2'] (225, 6)

De cette manière, l'espace d'entrée à deux dimensions est étendu à l'espace de caractéristiques à six dimensions.

Standardisez les données avec le code suivant.

scaler = StandardScaler()
X_train_poly_scaled = scaler.fit_transform(X_train_poly)
X_test_poly_scaled = scaler.fit_transform(X_test_poly)

La normalisation des données consiste à soustraire la moyenne de toutes les données, puis à diviser par l'écart type pour définir la moyenne des données à 0 et la variance à 1.

Je l'ai écrit dans un article facile à comprendre ici, alors veuillez vous y référer.

Maintenant, implémentons et évaluons le modèle avec le code suivant.

lin_svm = LinearSVC()
lin_svm.fit(X_train_poly_scaled, Y_train)
print(lin_svm.score(X_test_poly_scaled, Y_test))

0.84

C'est un peu bas. Mappons-le à une dimension supérieure.

Cependant, le processus de mappage à une dimension supérieure et de standardisation est gênant, alors utilisons quelque chose appelé Pipeline.

poly_scaler_svm = Pipeline([
    ('poly', PolynomialFeatures(degree=3)),
    ('scaler', StandardScaler()),
    ('svm', LinearSVC())
])
poly_scaler_svm.fit(X_train, Y_train)
print(poly_scaler_svm.score(X_test, Y_test))

0.9733333333333334

De cette manière, «Pipeline» peut être utilisé pour simplifier la tâche de mappage des données à une dimension supérieure, de les standardiser et de les mettre dans le modèle svm. En définissant degree = 3, il est mappé à un espace d'entités de dimension supérieure.

La précision est plutôt bonne. Il est assez efficace lorsqu'il est mappé à une dimension supérieure.

Ensuite, dessinons ce chiffre. Ci-dessous le code.

_x0 = np.linspace(-1.5, 2.7, 100)
_x1 = np.linspace(-1.5, 1.5, 100)
x0, x1 = np.meshgrid(_x0, _x1)
X = np.hstack((x0.ravel().reshape(-1, 1), x1.ravel().reshape(-1, 1)))
y_decision = model.decision_function(X).reshape(x0.shape)
plt.contourf(x0, x1, y_decision, levels=[y_decision.min(), 0, y_decision.max()], alpha=0.3)
plt.figure(figsize=(12, 8))
mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.show()

image.png

Vous pouvez voir que les lignes sont assez propres. Expliquons le code.

_x0 = np.linspace(-1.5, 2.7, 100)
_x1 = np.linspace(-1.5, 1.5, 100)
x0, x1 = np.meshgrid(_x0, _x1)

Les points de grille sont créés avec le code ici. Veuillez vous référer à l'article ici pour une compréhension facile.

np.linspace crée un tableau numpy en spécifiant le point de départ dans le premier argument, le point de fin dans le deuxième argument et le nombre de points dans le troisième argument. En le passant à np.meshgrid, nous créons des points de grille 100x100.

X = np.hstack((x0.ravel().reshape(-1, 1), x1.ravel().reshape(-1, 1)))

Après avoir converti un tableau 100x100 en tableau unidimensionnel avec (x0.ravel (), convertissez-le en une matrice bidimensionnelle 10000x1 avec reshape (-1, 1) etnp.hstack Par, ils sont connectés dans la direction horizontale de axis = 1, c'est-à-dire que X est une matrice de 10000 × 2.

y_decision = model.decision_function(X).reshape(x0.shape)
plt.contourf(x0, x1, y_decision, levels=[y_decision.min(), 0, y_decision.max()], alpha=0.3)

La distance entre 10000 points de grille et le superplan séparé est calculée par model.decision_function (X) et convertie en données 100 × 100.

plt.contourf est une fonction qui illustre les lignes de contour, et vous pouvez spécifier dans niveaux où changer la couleur.

Ceci termine l'implémentation qui n'utilise pas la méthode du noyau.

Implémentation à l'aide de la méthode du noyau

Implémentons-le en utilisant la méthode du noyau.

Préparons les données. Jusqu'ici la même chose.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC

moons = make_moons(n_samples=300, noise=0.2, random_state=0)

X = moons[0]
Y = moons[1]

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, stratify=Y, random_state=0)

Implémentons le modèle avec le code suivant.

karnel_svm = Pipeline([
    ('scaler', StandardScaler()),
    ('svm', SVC(kernel='poly', degree=3, coef0=1))
])

karnel_svm.fitX_train, Y_train()

En spécifiant poly dans l'argument karnel de SVC, vous pouvez spécifier le noyau polymorphe, et en spécifiant degree = 3, vous pouvez envisager de mapper jusqu'à trois dimensions.

Vous venez de créer un modèle. Ensuite, illustrons ce modèle. Je refais la même chose, mais c'est un problème, alors je vais en faire une fonction.

def plot_decision_function(model):
    _x0 = np.linspace(-1.7, 2.7, 100)
    _x1 = np.linspace(-1.5, 1.7, 100)
    x0, x1 = np.meshgrid(_x0, _x1)
    X = np.hstack((x0.ravel().reshape(-1, 1), x1.ravel().reshape(-1, 1)))
    y_decision = model.decision_function(X).reshape(x0.shape)
    plt.contourf(x0, x1, y_decision, levels=[y_decision.min(), 0, y_decision.max()], alpha=0.3)

def plot_dataset(x, y):
    plt.plot(x[:, 0][y == 0], x[:, 1][y == 0], 'bo', ms=15)
    plt.plot(x[:, 0][y == 1], x[:, 1][y == 1], 'r^', ms=15)
    plt.xlabel('$x_1$', fontsize=20)
    plt.ylabel('$x_2$', fontsize=20, rotation=0)

plt.figure(figsize=(12, 8))
plot_decision_function(karnel_svm)
plot_dataset(X, Y)
plt.show()

image.png

J'aurais pu le tracer avec mglearn, mais cette fois je l'ai tracé avec plt.plot. Ceux avec «Y = 0» sont dessinés avec des cercles bleus, et ceux avec «Y = 1» sont dessinés avec des triangles rouges.

Comme vous pouvez le voir, le même résultat est retourné avec ou sans la méthode kernel. Cependant, il est beaucoup plus facile de calculer en interne en utilisant la méthode du noyau, donc je pense qu'il est préférable d'utiliser la méthode du noyau autant que possible.

Veuillez consulter l'article ici pour savoir comment le rendre plus facile.

À la fin

Merci d'être resté avec nous jusqu'à présent.

C'était un très long article. Merci beaucoup d'avoir lu jusqu'ici.

Je vous remercie pour votre travail acharné.

Recommended Posts

[Python] J'ai expliqué en détail la théorie et l'implémentation de la machine à vecteurs de support (SVM).
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de l'arbre de décision
Calcul de la machine à vecteurs de support (SVM) (en utilisant cvxopt)
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
Créez un environnement python pour apprendre la théorie et la mise en œuvre de l'apprentissage profond
J'ai vérifié les versions de Blender et Python
[Python] Trier les pommes et les poires à partir des valeurs de pixels à l’aide d’une machine à vecteurs de support (SVM)
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
Je veux connaître la nature de Python et pip
J'ai considéré la méthode d'apprentissage automatique et son langage d'implémentation à partir des informations de balise de Qiita
L'histoire de Python et l'histoire de NaN
Apprentissage automatique ① Résumé SVM (Support Vector Machine)
J'ai comparé la vitesse de Hash avec Topaz, Ruby et Python
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
Vérification de la théorie selon laquelle "Python et Swift sont assez similaires"
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Implémentation ~
Notez que je comprends l'algorithme du classificateur Naive Bayes. Et je l'ai écrit en Python.
J'ai remplacé le calcul numérique de Python par Rust et comparé la vitesse
Je ne connaissais pas les bases de Python
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
Le modèle de projet Python auquel je pense.
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
J'ai écrit FizzBuzz en python en utilisant la machine à vecteurs de support (bibliothèque LIVSVM).
J'ai comparé la vitesse de l'écho du framework web en langage go et du flask du framework web python
J'ai comparé la vitesse des expressions régulières en Ruby, Python et Perl (version 2013)
[Python] Comparaison de la théorie de l'analyse des composants principaux et de l'implémentation par Python (PCA, Kernel PCA, 2DPCA)
Résumé des différences entre PHP et Python
La réponse de "1/2" est différente entre python2 et 3
Pourquoi l'implémentation Python d'ISUCON 5 a utilisé Bottle
Spécification de la plage des tableaux ruby et python
Comparez la vitesse d'ajout et de carte Python
Essayez Progate Free Edition [Python I]
Implémentation de l'arbre TRIE avec Python et LOUDS
J'ai touché certaines des nouvelles fonctionnalités de Python 3.8 ①
[Entretien de codage] Implémentation de la machine cryptographique Enigma (Python)
Résumé relatif aux E / S de python et fortran
J'ai lu et implémenté les variantes de UKR
Prise en compte des forces et faiblesses de Python
Explication de la distance d'édition et de l'implémentation en Python
[Python] Déterminez le type d'iris avec SVM
Construisez un serveur API pour vérifier le fonctionnement de l'implémentation frontale avec python3 et Flask
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
[Apprentissage automatique] "Détection d'anomalies et détection de changement" Dessinons la figure du chapitre 1 en Python.
J'ai comparé la vitesse de la référence du python dans la liste et la référence de l'inclusion du dictionnaire faite à partir de la liste dans.
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
[Recette du formateur] J'ai touché le flacon du framework Python.
Le processus d'installation d'Atom et de l'exécution de Python
Python - Explication et résumé de l'utilisation des 24 meilleurs packages
J'ai suivi la mise en place de la commande du (première moitié)
Visualisez la gamme d'insertions internes et externes avec python
Implémentation python de la classe de régression linéaire bayésienne
À propos des tests dans la mise en œuvre de modèles d'apprentissage automatique
Référence et modification de la limite supérieure récursive Python
J'ai vérifié le système d'exploitation et le shell par défaut de docker-machine
J'ai suivi la mise en place de la commande du (seconde moitié)
J'ai touché Bergeronnette (3). Enquête et mise en place de messages pop-up.
Résumé du flux de base de l'apprentissage automatique avec Python
Un mémorandum sur la mise en œuvre des recommandations en Python