--Classez les données d'images numériques manuscrites par SVM
La source est ici.
Importez la bibliothèque de tests croisés "cross_validation". Les données utilisent des chiffres manuscrits.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn import svm, datasets, cross_validation
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
Les méthodes suivantes sont disponibles pour les tests croisés. --kFold (n, k): divise n échantillons de données en k lots. Utilisez un lot pour les tests et le lot restant (k-1) pour la formation. Modifiez l'ensemble de données utilisé pour le test et répétez le test k fois. --StratifiedKFold (y, k): diviser les données en k morceaux tout en préservant le rapport d'étiquettes dans l'ensemble de données divisé. --LeaveOneOut (n): Equivalent au cas de kFold avec k = n. Lorsque le nombre d'échantillons de données est petit. --LeaveOneLabelOut (labels): divise les données selon une étiquette donnée. Par exemple, lorsqu'il s'agit de données annuelles, lors de la réalisation de tests en les divisant en données annuelles.
Cette fois, j'utiliserai le KFold le plus simple. Le nombre de divisions était de 4. Comme je l'ai remarqué plus tard, dans KFold, si vous définissez la variable «huffle = true», il semble que l'ordre des données sera trié automatiquement.
np.random.seed(0) #Paramètre de départ aléatoire, il n'est pas nécessaire que ce soit 0
indices = np.random.permutation(len(X_digits))
X_digits = X_digits[indices] #Trier au hasard l'ordre des données
y_digits = y_digits[indices]
n_fold = 4 #Nombre de tests croisés
k_fold = cross_validation.KFold(n=len(X_digits),n_folds = n_fold)
# k_fold = cross_validation.KFold(n=len(X_digits),n_folds = n_fold, shuffle=true)
#Si tel est le cas, les quatre premières lignes ne sont pas nécessaires.
Modifiez l'hyperparamètre C pour voir comment la valeur d'évaluation du modèle change. C est un paramètre qui détermine le nombre de faux positifs autorisés. Le noyau SVM était un noyau gaussien. Référence: article précédent "Reconnaître les nombres manuscrits avec SVM"
C_list = np.logspace(-8, 2, 11) # C
score = np.zeros((len(C_list),3))
tmp_train, tmp_test = list(), list()
# score_train, score_test = list(), list()
i = 0
for C in C_list:
svc = svm.SVC(C=C, kernel='rbf', gamma=0.001)
for train, test in k_fold:
svc.fit(X_digits[train], y_digits[train])
tmp_train.append(svc.score(X_digits[train],y_digits[train]))
tmp_test.append(svc.score(X_digits[test],y_digits[test]))
score[i,0] = C
score[i,1] = sum(tmp_train) / len(tmp_train)
score[i,2] = sum(tmp_test) / len(tmp_test)
del tmp_train[:]
del tmp_test[:]
i = i + 1
Il est plus facile d'écrire si vous regardez simplement la valeur d'évaluation du test. Vous pouvez également spécifier le nombre de processeurs utilisés dans la variable n_jobs. -1 utilise tous les processeurs.
cross_validation.cross_val_score(svc, X_digits, y_digits, cv=k_fold, n_jobs=-1)
La valeur d'évaluation est sortie par tableau.
array([ 0.98888889, 0.99109131, 0.99331849, 0.9844098 ])
Avec C comme axe horizontal, tracez la valeur d'évaluation pendant la formation et la valeur d'évaluation pendant le test. Si C est petit, la précision ne s'améliorera pas, probablement parce qu'un jugement erroné est trop autorisé.
xmin, xmax = score[:,0].min(), score[:,0].max()
ymin, ymax = score[:,1:2].min()-0.1, score[:,1:2].max()+0.1
plt.semilogx(score[:,0], score[:,1], c = "r", label = "train")
plt.semilogx(score[:,0], score[:,2], c = "b", label = "test")
plt.axis([xmin,xmax,ymin,ymax])
plt.legend(loc='upper left')
plt.xlabel('C')
plt.ylabel('score')
plt.show
Ensuite, fixez C à 100 et changez le gamma pour la même expérience. Plus le gamma est grand, plus les limites de classification sont complexes.
g_list = np.logspace(-8, 2, 11) # C
score = np.zeros((len(g_list),3))
tmp_train, tmp_test = list(), list()
i = 0
for gamma in g_list:
svc = svm.SVC(C=100, gamma=gamma, kernel='rbf')
for train, test in k_fold:
svc.fit(X_digits[train], y_digits[train])
tmp_train.append(svc.score(X_digits[train],y_digits[train]))
tmp_test.append(svc.score(X_digits[test],y_digits[test]))
score[i,0] = gamma
score[i,1] = sum(tmp_train) / len(tmp_train)
score[i,2] = sum(tmp_test) / len(tmp_test)
del tmp_train[:]
del tmp_test[:]
i = i + 1
Voici les résultats. À mesure que le gamma augmente, la précision pendant la formation et la précision pendant les tests augmentent, mais à partir d'environ 0,001, la précision pendant la formation ne change pas, mais la précision pendant les tests diminue. Il semble que le surapprentissage se produit en raison d'une trop grande complexité. Il s'avère que la définition des variables est importante.
Recommended Posts