Une série qui implémente les tâches de la classe d'apprentissage automatique de Coursera (professeur Andrew Ng) en Python. Dans ex6, la classification est effectuée à l'aide de la machine à vecteurs de support (SVM).
Le premier est un SVM linéaire (sans noyau). Dans scikit-learn, l'interface des modèles d'apprentissage automatique est unifiée, et n'importe quel modèle peut être instancié puis entraîné avec model.fit (X, y)
. La syntaxe est la même qu'il s'agisse de régression linéaire, de régression logistique ou de SVM. SVM utilise la classe sklearn.svm.SVC ()
.
Cliquez-ici pour le code.
Comme d'habitude, utilisez scipy.scio.loadmat
pour charger les données au format Matlab et effectuer la formation.
import numpy as np
import matplotlib.pyplot as plt
import scipy.io as scio
from sklearn import svm
# scipy.io.loadmat()Lire les données Matlab en utilisant
data = scio.loadmat('ex6data1.mat')
X = data['X']
y = data['y'].ravel()
pos = (y==1) # numpy bool index
neg = (y==0) # numpy bool index
plt.scatter(X[pos,0], X[pos,1], marker='+', c='k')
plt.scatter(X[neg,0], X[neg,1], marker='o', c='y')
#SVM linéaire
model = svm.SVC(C=1.0, kernel='linear')
model.fit(X, y)
#Tracez une frontière de décision
px = np.linspace( np.min(X[:,0]), np.max(X[:,0]), 100)
w = model.coef_[0]
py = - (w[0]*px + model.intercept_[0]) / w[1]
plt.plot(px,py)
plt.show()
Cliquez ici pour les résultats.
Maintenant, en fonction de la tâche, ajustez le paramètre de régularisation SVM C
pour voir le changement de comportement. Cliquez ici pour le résultat avec C = 100.0
.
L'augmentation de «C» affaiblit la régularisation. Pour cette raison, la limite de décision a changé de sorte que les valeurs aberrantes de gauche sont également classées correctement. C'est un peu surajustement (surapprentissage), et on peut dire que la classification de la forme la plus naturelle est lorsque C = 1.0
est défini plus tôt.
Dans la tâche suivante, nous classerons un autre ensemble de données, difficile à séparer par une ligne droite, avec le noyau gaussien SVM.
Puisque le noyau gaussien est utilisé, définissez kernel = 'rbf'
dans le paramètre de svm.SVC
.
import numpy as np
import matplotlib.pyplot as plt
import scipy.io as scio
from sklearn import svm
# scipy.io.loadmat()Lire les données Matlab en utilisant
data = scio.loadmat('ex6data2.mat')
X = data['X']
y = data['y'].ravel()
pos = (y==1) # numpy bool index
neg = (y==0) # numpy bool index
plt.scatter(X[pos,0], X[pos,1], marker='+', c='k')
plt.scatter(X[neg,0], X[neg,1], marker='o', c='y')
#Noyau gaussien(RBF)SVM
model = svm.SVC(C=1.0, gamma=50.0, kernel='rbf', probability=True)
model.fit(X, y)
# Decision Boundary(Limite de décision)Comploter
px = np.arange(0, 1, 0.01)
py = np.arange(0, 1, 0.01)
PX, PY = np.meshgrid(px, py) # PX,Chaque PY est une matrice 100x100
XX = np.c_[PX.ravel(), PY.ravel()] #XX est une matrice de 10000x2
Z = model.predict_proba(XX)[:,1] #Prédite par le modèle SVM. y=La probabilité de 1 est dans la deuxième colonne du résultat, alors supprimez-la. Z est un vecteur de dimension 10000
Z = Z.reshape(PX.shape) #Convertir Z en matrice 100x100
plt.contour(PX, PY, Z, levels=[0.5], linewidths=3) # Z=0.La ligne de contour de 5 devient la limite de décision
plt.xlim(0.0,1.0)
plt.ylim(0.4,1.0)
plt.show()
Le tracé résultant ressemble à ceci, et vous pouvez voir que même les données qui deviennent la limite de décision des formes complexes peuvent être classées proprement.
Le point cette fois est sur «gamma» du noyau RBF, qui est l'un des paramètres de SVM. À Coursera, le noyau gaussien
gamma
est passé en paramètre à sklearn.svm.SVC ()
. En comparant les deux équations, cela correspond à $ \ gamma = \ frac {1} {2 \ sigma ^ 2} $. Dans l'exemple de Coursera, $ \ sigma = 0,1 $ a été défini, nous définissons donc $ \ gamma = 50 $ en conséquence.
C
et σComme nous l'avons vu, le noyau gaussien SVM nécessite l'ajustement des paramètres C
et $ \ sigma $.
―― «C» est la force de la régularisation. Plus C est petit, plus il devient régulier (= il ne correspond pas aux données d'entraînement, la performance de généralisation devient plus forte), et plus C il est grand, moins il devient régulier (= il correspond aux données d'entraînement, cela devient un surentraînement).
Sur la base de cette caractéristique, nous ajusterons les deux paramètres.
Ainsi, dans la tâche suivante, nous entraînerons le nouvel ensemble de données avec différentes combinaisons de C
et $ \ sigma $, et adopterons l'ensemble de paramètres avec le pourcentage le plus élevé de réponses correctes dans la classification. Nous allons essayer 8 types de valeurs de 0,01, 0,03, 0,1, 0,3, 1, 3, 10, 30 comme valeurs de C
et $ \ sigma $, nous allons donc nous entraîner 8x8 = 64 fois.
Cliquez-ici pour le code.
import numpy as np
import matplotlib.pyplot as plt
import scipy.io as scio
from sklearn import svm
# scipy.io.loadmat()Lire les données Matlab en utilisant
data = scio.loadmat('ex6data3.mat')
X = data['X']
y = data['y'].ravel()
Xval = data['Xval']
yval = data['yval'].ravel()
c_values = np.array([0.01, 0.03, 0.1, 0.3, 1.0, 3.0, 10.0, 30.0])
gamma_values = 1/ (2* c_values**2)
#Noyau gaussien avec différents C et gamma(RBF)Apprenez SVM
scores = np.zeros([8,8])
for i_c in range(0,8):
for i_g in range(0,8):
model = svm.SVC(C=c_values[i_c], gamma=gamma_values[i_g], kernel='rbf')
model.fit(X, y)
#Calculer le score dans les données de test croisé
scores[i_c, i_g] = model.score(Xval, yval)
#C avec le score le plus élevé,Demandez gamma
max_idx = np.unravel_index(np.argmax(scores), scores.shape)
#C maximum,Apprenez à nouveau SVM avec gamma
model = svm.SVC(C=c_values[max_idx[0]], gamma=gamma_values[max_idx[1]], kernel='rbf', probability=True)
model.fit(X, y)
#Tracer les données de test croisé
pos = (yval==1) # numpy bool index
neg = (yval==0) # numpy bool index
plt.scatter(Xval[pos,0], Xval[pos,1], marker='+', c='k')
plt.scatter(Xval[neg,0], Xval[neg,1], marker='o', c='y')
# Decision Boundary(Limite de décision)Comploter
px = np.arange(-0.6, 0.25, 0.01)
py = np.arange(-0.8, 0.6, 0.01)
PX, PY = np.meshgrid(px, py) # PX,Chaque PY est une matrice 100x100
XX = np.c_[PX.ravel(), PY.ravel()] #XX est une matrice de 10000x2
Z = model.predict_proba(XX)[:,1] #Prédite par le modèle SVM. y=La probabilité de 1 est dans la deuxième colonne du résultat, alors supprimez-la. Z est un vecteur de dimension 10000
Z = Z.reshape(PX.shape) #Convertir Z en matrice 100x100
plt.contour(PX, PY, Z, levels=[0.5], linewidths=3) # Z=0.La ligne de contour de 5 devient la limite de décision
plt.show()
À la suite de la vérification avec les données de test croisé, «C = 1,0, gamma = 0,1» a les performances les plus élevées, et la limite de décision du classificateur est la suivante.
Note
--Comment trouver l'index de la valeur maximale à partir du tableau bidimensionnel numpy ʻA->
np.unravel_index (np.argmax (A), A.shape)` Un taple avec un index est renvoyé en conséquence.
Le Dr Andrew a publié les directives suivantes sur l'utilisation appropriée de la régression logistique, du SVM linéaire et du SVM du noyau gaussien. Si m = nombre d'échantillons (données d'apprentissage) et n = nombre d'entités
--Si n est grand (~ 10000) et m est petit (~ 1000), alors régression logistique ou SVM linéaire (-> car le nombre d'échantillons n'est pas assez grand pour créer une frontière de décision non linéaire complexe) --Si n est petit (1 ~ 1000) et m est modéré (~ 50000), noyau gaussien SVM --Si n est petit (1 à 1000) et m est très grand (1 million environ), ajoutez une fonction et une régression logistique ou SVM linéaire (car la SVM gaussienne est lente lorsque m est grand)
La seconde moitié de ex6 (filtre anti-spam utilisant SVM) se fera séparément.
Recommended Posts