[PYTHON] Introduction à l'apprentissage automatique avec scikit-learn - De l'acquisition de données à l'optimisation des paramètres

Aperçu

Prenons l'exemple ** "Identifions automatiquement le code postal manuscrit inscrit sur la carte postale" **.

Ceci est un article pour les débutants. Fondamentalement, il s'agit d'une collection de didacticiels et de documents scikit-learn, mais elle comprend également d'autres contenus. Nous utiliserons des chiffres pour l'ensemble de données et SVM (SVC pour être exact) pour la méthode d'apprentissage automatique.

Ensemble de données: chiffres

chiffres est un ensemble de données composé d'une étiquette numérique et de données d'image numérique. Vous apprendrez cette paire d'étiquettes et d'images plus tard. Puisque les données sont préparées à l'avance par scikit-learn, n'importe qui peut facilement l'essayer.

Lire les données

Vous pouvez charger les chiffres du jeu de données avec datasets.load_digits ().

from sklearn import datasets
from matplotlib import pyplot as plt
# from sklearn import datasets

digits = datasets.load_digits()

Afficher le contenu des données

Chaque image est une image de caractère manuscrite de 0 à 9. Ces images sont représentées par programme sous la forme d'un tableau à deux dimensions avec des valeurs comprises entre 0 et 255.

#Données du tableau d'image
print(digits.data)
[[  0.   0.   5. ...,   0.   0.   0.]
 [  0.   0.   0. ...,  10.   0.   0.]
 [  0.   0.   0. ...,  16.   9.   0.]
 ..., 
 [  0.   0.   1. ...,   6.   0.   0.]
 [  0.   0.   2. ...,  12.   0.   0.]
 [  0.   0.  10. ...,  12.   1.   0.]]

Il est difficile à comprendre même si vous regardez les données d'image sous forme de tableau, je voudrais donc l'afficher sous forme d'image.

Avant d'afficher l'image, vérifiez d'abord les données de l'étiquette. Comme indiqué ci-dessous, les étiquettes 0 à 9 sont correctement attribuées à l'avance.

#étiquette
print(digits.target)
[0 1 2 ..., 8 9 8]

En regardant le résultat ci-dessus, par exemple, la 0, 1, 2ème image du début reçoit l'étiquette 0, 1, 2 et la deuxième image de l'arrière reçoit l'étiquette 9. .. Vous pouvez utiliser matplotlib pour afficher ces images.

#Affichage de l'image
# number 0
plt.subplot(141), plt.imshow(digits.images[0], cmap = 'gray')
plt.title('number 0'), plt.xticks([]), plt.yticks([])

# number 1
plt.subplot(142), plt.imshow(digits.images[1], cmap = 'gray')
plt.title('numbert 1'), plt.xticks([]), plt.yticks([])

# number 2
plt.subplot(143), plt.imshow(digits.images[2], cmap = 'gray')
plt.title('numbert 2'), plt.xticks([]), plt.yticks([])

# number 9
plt.subplot(144), plt.imshow(digits.images[-2], cmap = 'gray')
plt.title('numbert 9'), plt.xticks([]), plt.yticks([])

plt.show()

output_7_0.png

De cette façon, vous pouvez voir que chaque image semble avoir la bonne étiquette.

Classification des images par SVM

Qu'est-ce que SVM

** SVM (Support Vector Machine) ** est l'une des méthodes d'apprentissage supervisé avec d'excellentes performances de reconnaissance. Fondamentalement, la classification à deux classes est basée sur la maximisation de la marge. Bien sûr, il peut également être appliqué à la classification multi-classes (en effectuant plusieurs fois une classification à deux classes).

Avec un SVM strict, si les données à classer se chevauchent (c'est-à-dire si toutes les données ne peuvent pas être complètement séparées), il n'est pas possible d'obtenir une limite de classification appropriée. En revanche, les SVM qui tolèrent les erreurs sont appelés ** SVM à marge souple **. En donnant une pénalité C aux erreurs de classification, il est possible de tracer une frontière de classification qui minimise les erreurs de classification même pour les données qui ne peuvent pas être complètement séparées.

Il est important de noter que plus la pénalité C est grande, plus l'erreur est grave et, en même temps, plus elle est susceptible de provoquer un ** surajustement **.

(Remarque) Le surentraînement signifie que le modèle d'entraînement s'intègre dans des fonctionnalités aléatoires spécifiques (sans rapport avec les fonctionnalités que vous souhaitez entraîner à l'origine) dans les données d'entraînement. En cas de surentraînement, les performances des données d'entraînement s'amélioreront, mais les résultats seront pires avec d'autres données. (Référence: Over-fit-Wikipedia)

SVM avec scikit-learn

En fait, scikit-learn a des types légèrement différents de SVM tels que SVC, NuSVC et LinearSVC. NuSVC et SVC sont des techniques très similaires, mais ils ont des ensembles de paramètres légèrement différents et sont représentés mathématiquement par des formulations différentes. LinearSVC est un SVM qui utilise un noyau linéaire, et aucun autre noyau ne peut être spécifié.

Cette fois, nous utiliserons SVC et appliquerons une marge douce. Tout ce que vous avez à faire est ** (1) de créer un classificateur et (2) de l'appliquer à vos données **.

(1) Création du classificateur

from sklearn import svm

# SVM
clf = svm.SVC(gamma=0.001, C=100.)
clf.fit(digits.data[:-10], digits.target[:-10])
SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

Bien que rarement spécifié ici, vous pouvez voir que le SVC a pas mal de paramètres (C, cache_size, class_weight, coef0, ...) comme indiqué ci-dessus. Ne vous inquiétez pas trop au début, les paramètres par défaut sont bons.

(2) Classification des images par classificateur

L'étiquette est en fait estimée à partir de l'image à l'aide du classificateur créé. Essayons avec les 10 dernières données que nous n'avons pas utilisées pour créer le modèle d'entraînement.

clf.predict(digits.data[-10:])
array([5, 4, 8, 8, 4, 9, 0, 8, 9, 8])

En regardant les données réelles,

print(digits.target[-10:])
[5 4 8 8 4 9 0 8 9 8]

Est en accord avec le résultat de l'estimation.

Cela confirme qu'une estimation approximativement correcte est possible à partir du modèle formé. Essayons différents paramètres.

Évaluation de l'exactitude des identificateurs

Indice d'évaluation des discriminateurs

Il existe plusieurs indices d'évaluation de la précision de classification du classificateur, mais il peut en principe être mesuré par les indices suivants.

Normalement, la précision du classificateur est souvent évaluée par la valeur F. Cependant, dans la pratique, il arrive souvent que l'accent soit mis sur le taux de précision ou le taux de rappel.

Conformité et rappel

Par exemple, envisagez une inspection des pièces en usine. Ce n'est pas un gros problème si vous classez par erreur une pièce qui n'est cassée nulle part comme "cassée (erreur)". Cependant, si une pièce cassée est classée à tort comme "non cassée (correcte)", cela peut entraîner des plaintes et des rappels, voire même mettre la vie en danger selon le produit. Dans de tels cas, la précision est plus importante que le rappel. Par exemple, dans «Taux de conformité 99% + taux de rappel 70%» et «Taux de conformité 80% + taux de rappel 99%», ce dernier a une valeur F plus élevée, mais le premier est extrêmement pratique. C'est possible. En revanche, lors d'une recherche dans une base de données, le taux de rappel est souvent plus important que le taux de précision. En effet, même si vous obtenez beaucoup de mauvais résultats de recherche, c'est bien mieux que beaucoup de données qui ne peuvent pas être trouvées par la recherche.

Optimisation des paramètres

Jusqu'à présent, les paramètres étaient en quelque sorte réglés sur des valeurs appropriées. Cependant, cela ne fournit souvent pas la précision de classification requise et, en pratique, l'optimisation des paramètres est essentielle. Alors, quels paramètres devraient être définis et comment devraient-ils être définis pour améliorer la précision de classification du classificateur? Vous pouvez régler manuellement les paramètres un par un, mais c'est très difficile. Il semble que l'on puisse savoir qu'une telle valeur est habituellement bonne selon l'ensemble de données et la méthode, mais elle ne peut pas être utilisée pour un ensemble de données inconnu. Par conséquent, une méthode appelée ** recherche de grille ** est souvent utilisée. En termes simples, le modèle est réellement entraîné lors de la modification des paramètres dans la plage de recherche et le paramètre avec la meilleure précision de résultat est recherché. De plus, la ** validation croisée ** est utilisée pour confirmer que le modèle d'apprentissage avec les paramètres obtenus ne provoque pas de surentraînement. Dans la méthode de vérification de k-intersection, les données sont d'abord divisées en k morceaux. C'est une méthode d'apprentissage avec k-1 d'entre eux et d'évaluation avec le reste, en répétant k fois (tout en changeant les données d'entraînement et les données de test) et en évaluant le modèle d'apprentissage avec la valeur moyenne. En faisant cela, vous pouvez évaluer les ** performances de généralisation ** du modèle d'entraînement.

(Remarque) Une bonne performance de généralisation est simplement la capacité du modèle d'apprentissage à identifier correctement les données inconnues. Rappelez-vous que si vous êtes surentraîné, vous pourrez identifier les données d'entraînement avec une grande précision, mais vous serez moins précis avec des données inconnues.

Avec scikit-learn, vous pouvez facilement effectuer une recherche de grille et une vérification d'intersection à l'aide de GridSearchCV (). Par exemple, vous pouvez spécifier les paramètres suivants:

Préparation

Avant d'effectuer l'optimisation des paramètres, convertissez le format des données lues.

from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.svm import SVC

#Chargement du jeu de données Digits
digits = datasets.load_digits()
print(len(digits.images))
print(digits.images.shape)
1797
(1797, 8, 8)
# To apply an classifier on this data, we need to flatten the image, to
# turn the data in a (samples, feature) matrix:
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))  # reshape(cols, rows)Convertir en colonne de lignes de lignes cols avec(Un des arguments-Calcul automatique si 1)
y = digits.target
print(X.shape)
print(y)
(1797, 64)
[0 1 2 ..., 8 9 8]

Recherche de grille et méthode de vérification des intersections

Le code ci-dessous peut sembler intimidant, mais ce que vous faites en réalité est simple.

Vous essayez simplement toutes les combinaisons des cas ci-dessus pour trouver le paramètre (meilleur \ _params \ _) qui maximise chaque précision et rappel. (Notez que gamma est un paramètre lorsque le noyau est rbf, donc il n'est pas pertinent lorsque le noyau est linéaire)

Après cela, les résultats de la recherche dans la grille sont affichés en détail et le rapport détaillé des résultats est affiché avec classification_report ().

#Divisez l'ensemble de données en données d'entraînement et données de test
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.5, random_state=0)

#Définissez les paramètres que vous souhaitez optimiser avec la validation croisée
tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],
                     'C': [1, 10, 100, 1000]},
                    {'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]

scores = ['precision', 'recall']

for score in scores:
    print("# Tuning hyper-parameters for %s" % score)
    print()

    #Recherche de grille et méthode de vérification des intersections
    clf = GridSearchCV(SVC(C=1), tuned_parameters, cv=5,
                       scoring='%s_weighted' % score)
    clf.fit(X_train, y_train)

    print("Best parameters set found on development set:")
    print()
    print(clf.best_params_)
    print()
    print("Grid scores on development set:")
    print()
    for params, mean_score, scores in clf.grid_scores_:
        print("%0.3f (+/-%0.03f) for %r"
              % (mean_score, scores.std() * 2, params))
    print()
    print("Detailed classification report:")
    print()
    print("The model is trained on the full development set.")
    print("The scores are computed on the full evaluation set.")
    print()
    y_true, y_pred = y_test, clf.predict(X_test)
    print(classification_report(y_true, y_pred))
    print()  
# Tuning hyper-parameters for precision

Best parameters set found on development set:

{'gamma': 0.001, 'kernel': 'rbf', 'C': 10}

Grid scores on development set:

0.987 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1}
0.959 (+/-0.030) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1}
0.988 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 10}
0.982 (+/-0.027) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 10}
0.988 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 100}
0.982 (+/-0.026) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 100}
0.988 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1000}
0.982 (+/-0.026) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1000}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 1}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 10}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 100}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 1000}

Detailed classification report:

The model is trained on the full development set.
The scores are computed on the full evaluation set.

             precision    recall  f1-score   support

          0       1.00      1.00      1.00        89
          1       0.97      1.00      0.98        90
          2       0.99      0.98      0.98        92
          3       1.00      0.99      0.99        93
          4       1.00      1.00      1.00        76
          5       0.99      0.98      0.99       108
          6       0.99      1.00      0.99        89
          7       0.99      1.00      0.99        78
          8       1.00      0.98      0.99        92
          9       0.99      0.99      0.99        92

avg / total       0.99      0.99      0.99       899


# Tuning hyper-parameters for recall

Best parameters set found on development set:

{'gamma': 0.001, 'kernel': 'rbf', 'C': 10}

Grid scores on development set:

0.986 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1}
0.958 (+/-0.029) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1}
0.987 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 10}
0.981 (+/-0.029) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 10}
0.987 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 100}
0.981 (+/-0.027) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 100}
0.987 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1000}
0.981 (+/-0.027) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1000}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 1}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 10}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 100}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 1000}

Detailed classification report:

The model is trained on the full development set.
The scores are computed on the full evaluation set.

             precision    recall  f1-score   support

          0       1.00      1.00      1.00        89
          1       0.97      1.00      0.98        90
          2       0.99      0.98      0.98        92
          3       1.00      0.99      0.99        93
          4       1.00      1.00      1.00        76
          5       0.99      0.98      0.99       108
          6       0.99      1.00      0.99        89
          7       0.99      1.00      0.99        78
          8       1.00      0.98      0.99        92
          9       0.99      0.99      0.99        92

avg / total       0.99      0.99      0.99       899

Maintenant, d'après le résultat de print (clf.best \ _params \ _), 'gamma': 0.001, 'kernel': 'rbf', 'C': 10 sont les meilleurs des deux points de vue précision / rappel. Je comprends ça. Vous avez maintenant optimisé les paramètres.

Si nécessaire, essayez d'optimiser avec un noyau différent ou par rapport à des méthodes d'apprentissage autres que SVM.

référence

[1]An introduction to machine learning with scikit-learn — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/tutorial/basic/tutorial.html#introduction [2]Parameter estimation using grid search with cross-validation — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/auto_examples/model_selection/grid_search_digits.html#example-model-selection-grid-search-digits-py [3]1.4. Support Vector Machines — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/modules/svm.html [4] F value-Machine learning "Toki no Mori Wiki" http://ibisforest.org/index.php?F%E5%80%A4 [5] Maître SVM! 8 points de contrôle-Qiita http://qiita.com/pika_shi/items/5e59bcf69e85fdd9edb2 [6] Optimisation des paramètres par recherche de grille de Scikit learn http://qiita.com/SE96UoC5AfUt7uY/items/c81f7cea72a44a7bfd3a [7] Introduction à l'optimisation bayésienne pour l'apprentissage automatique | Manatee de zone de livre technique https://book.mynavi.jp/manatee/detail/id=59393 [8]3.3. Model evaluation: quantifying the quality of predictions — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter [9] Overfit - Wikipédia https://ja.wikipedia.org/wiki/%E9%81%8E%E5%89%B0%E9%81%A9%E5%90%88

Recommended Posts

Introduction à l'apprentissage automatique avec scikit-learn - De l'acquisition de données à l'optimisation des paramètres
Introduction à l'apprentissage automatique
[Python] Introduction facile à l'apprentissage automatique avec python (SVM)
Une introduction à l'apprentissage automatique
Super introduction à l'apprentissage automatique
Apprentissage automatique dans Delemas (acquisition de données)
Présentation de la bibliothèque d'apprentissage automatique SHOGUN
Apprentissage automatique pour apprendre avec Nogisaka 46 et Keyakizaka 46 Partie 1 Introduction
Prétraitement dans l'apprentissage automatique 2 Acquisition de données
Comment collecter des données d'apprentissage automatique
[Introduction au style GAN] Apprentissage unique de l'animation avec votre propre machine ♬
Introduction à l'apprentissage automatique: fonctionnement du modèle
Sklearn de données déséquilibrées avec apprentissage automatique k-NN
Une introduction à OpenCV pour l'apprentissage automatique
Python: prétraitement en machine learning: acquisition de données
Une introduction à Python pour l'apprentissage automatique
[Introduction à l'apprentissage automatique] Jusqu'à ce que vous exécutiez l'exemple de code avec chainer
J'ai commencé l'apprentissage automatique avec Python (j'ai également commencé à publier sur Qiita) Préparation des données
[Super introduction à l'apprentissage automatique] Découvrez les didacticiels Pytorch
Une introduction à l'apprentissage automatique pour les développeurs de robots
[Introduction à StyleGAN2] Apprentissage indépendant avec 10 visages d'anime ♬
[Introduction à minimiser] Analyse des données avec le modèle SEIR ♬
[Super introduction à l'apprentissage automatique] Découvrez les didacticiels Pytorch
J'ai commencé l'apprentissage automatique avec le prétraitement des données Python
[Pour les débutants] Introduction à la vectorisation dans l'apprentissage automatique
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer Chapitres 11 et 12 Introduction à Pandas Matplotlib
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
Essayez de prédire le taux de change (FX) avec un apprentissage automatique non approfondi
Note de lecture: Introduction à l'analyse de données avec Python
Résumé du site pour apprendre l'apprentissage automatique avec une vidéo en anglais
Introduction à l'apprentissage automatique à partir de Simple Perceptron
L'apprentissage automatique appris avec Pokemon
Ensemble de données pour l'apprentissage automatique
[Mémorandum d'apprentissage] Introduction à vim
Oncle SE avec un cerveau endurci a essayé d'étudier l'apprentissage automatique
Apprentissage automatique avec Python! Préparation
Utilisation d'icrawler plus simple pour la collecte de données d'apprentissage automatique
Introduction à RDB avec sqlalchemy Ⅰ
Introduction à l'optimisation non linéaire (I)
20200329_Introduction à l'analyse de données avec Python 2nd Edition Personal Summary
Pour ceux qui souhaitent démarrer l'apprentissage automatique avec TensorFlow2
Démineur d'apprentissage automatique avec PyTorch
Introduction au Deep Learning ~ Règles d'apprentissage ~
Apprentissage automatique et optimisation mathématique
Commencer avec l'apprentissage automatique Python
Introduction à l'optimisation bayésienne
Apprentissage par renforcement profond 1 Introduction au renforcement de l'apprentissage
Essayez le machine learning à la légère avec Kaggle
Introduction au Deep Learning ~ Rétropropagation ~
[Introduction à Python] Comment obtenir des données avec la fonction listdir
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Introduction ~
À utiliser avec Cabocha pour générer automatiquement des données d'apprentissage "IOB2 tag corpus"
[Apprentissage automatique] Vérifiez les performances du classificateur à l'aide de données de caractères manuscrites
Introduction aux bases de Python de l'apprentissage automatique (apprentissage non supervisé / analyse principale)
Avant l'introduction à l'apprentissage automatique. ~ Technologie requise pour l'apprentissage automatique autre que l'apprentissage automatique ~
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer Chapitre 10 Introduction à Cupy
Introduction à l'analyse de données avec Python P32-P43 [ch02 3.US Baby Names 1880-2010]
Introduction à l'analyse de données par Python P17-P26 [ch02 1.usa.gov données de bit.ly]