[PYTHON] J'ai essayé de classer les nombres de mnist par apprentissage non supervisé [PCA, t-SNE, k-means]

introduction

L'apprentissage non supervisé est généralement moins précis que l'apprentissage supervisé, mais au prix de nombreux avantages. Plus précisément, en tant que scène où l'apprentissage non supervisé est utile

** - Données dont le modèle n'est pas bien compris --Données variant dans le temps --Données non étiquetées **

Etc.

Dans l'apprentissage non supervisé, vous apprenez la structure derrière les données à partir des données elles-mêmes. Cela vous permet de tirer parti de plus de données non étiquetées, ce qui peut ouvrir la voie à de nouvelles applications.

Dans cet article, je présenterai un exemple d'implémentation ** de classification des données mnist par apprentissage non supervisé. La méthode utilise l'analyse en composantes principales et la méthode t-SNE, k-means. Dans l'article suivant, je voudrais contester la classification à l'aide de l'encodeur automatique.

Que faire dans cet article

** - Classer les données mnist par apprentissage non supervisé --Mise en œuvre et évaluation de la classification par la méthode PCA + k-means

Importer la bibliothèque

python


import random
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import confusion_matrix
from sklearn.manifold import TSNE

Préparation des données

python


mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
#Normalisation
train_images = (train_images - train_images.min()) / (train_images.max() - train_images.min())
test_images = (test_images - test_images.min()) / (test_images.max() - test_images.min())

train_images.shape,test_images.shape

Je vais le visualiser pour le moment. Ce sont des chiffres familiers.

python


#Visualisation aléatoire
fig, ax = plt.subplots(4,5,figsize=[8,6])
ax_f = ax.flatten()
for ax_i in ax_f:
    idx = random.choice(range(train_images.shape[0]))
    ax_i.imshow(train_images[idx,:,:])
    ax_i.grid(False)
    ax_i.tick_params(labelbottom=False,labelleft=False)

image.png

Classification des images par analyse en composantes principales

Les données de mnist sont 28 * 28 = 784 dimensions. Il semble que la méthode k-means puisse être appliquée telle quelle, mais elle est efficace pour ** réduire les dimensions avant de classer. Ce faisant, il est possible de réduire la quantité de calcul.

** L'analyse des composants principaux (ACP) est utilisée comme méthode de réduction des dimensions. Ensuite, la méthode des k-means est appliquée aux données dont les dimensions ont été réduites par PCA pour classer les données. ** **

Effectuer une analyse des composants principaux

python


df_train = pd.DataFrame(train_images.reshape(train_images.shape[0],28*28))

pca = PCA()
pca.fit(df_train)
feature = pca.transform(df_train)

#Visualisation en deux dimensions
plt.scatter(feature[:,0],feature[:,1],alpha=0.8,c=train_labels)

Voici le résultat de la visualisation avec le premier composant et le deuxième composant du composant principal. Il est codé en couleur par 10 groupes de 0 à 9. On dirait qu'ils peuvent être catégorisés d'une manière ou d'une autre, mais ... il y a de nombreuses parties qui se chevauchent. image.png

Ensuite, réfléchissons au nombre de composants à appliquer k-means. Par conséquent, le taux de cotisation de chaque composante est visualisé.

python


#Changement du taux de cotisation
ev_ratio = pca.explained_variance_ratio_
ev_ratio = np.hstack([0,ev_ratio.cumsum()])

df_ratio = pd.DataFrame({"components":range(len(ev_ratio)), "ratio":ev_ratio})

plt.plot(ev_ratio)
plt.xlabel("components")
plt.ylabel("explained variance ratio")
plt.xlim([0,50])

plt.scatter(range(len(ev_ratio)),ev_ratio)

En regardant les résultats, nous pouvons voir que 90% ou plus des données peuvent être restaurées jusqu'au 100e composant. Comme vous pouvez le voir à partir de diverses expériences, 10 composants suffisaient lors de la classification. (J'ai expérimenté la méthode d'évaluation décrite ci-dessous) À partir de là, classons en appliquant la méthode k-means en utilisant jusqu'au 10e composant. Plus le nombre de dimensions est petit, plus le nombre de calculs est petit, il est donc préférable d'avoir un nombre plus petit.

Classification par la méthode des k-moyennes

Tout d'abord, appliquez la méthode des k-moyennes. Nous savons qu'il y a 10 groupes, alors classons-les d'abord en 10.

python


KM = KMeans(n_clusters = 10)
result = KM.fit(feature[:,:9])

Évaluation des résultats de classification

Tout d'abord, le résultat de la classification est affiché sous forme de matrice de confusion.

python


df_eval = pd.DataFrame(confusion_matrix(train_labels,result.labels_))
df_eval.columns = df_eval.idxmax()
df_eval = df_eval.sort_index(axis=1)

df_eval

L'étiquette de réponse correcte, qui était la plus fréquemment classée dans la grappe, a été utilisée comme étiquette prédictive. Par exemple, si le cluster n ° 0 contient 100 0, 20 1 et 10 4, cela prédit 0.

En regardant les résultats, vous pouvez voir qu'il y a deux clusters qui devraient être 0 et un qui devrait être 1. En d'autres termes, on considère qu'il était difficile de classer en 10 nombres ** par l'analyse en composantes principales et la méthode des k-moyennes **. image.png

Maintenant, réfléchissons au ** nombre de clusters qu'il est préférable de classer **. Évidemment, s'il y a de nombreux clusters, il y en aura de nombreux similaires dans le cluster, mais ce sera difficile à interpréter. En revanche, s'il est petit, il est facile à interpréter, mais le cluster contiendra diverses données.

Donc, ** le nombre de clusters est petit, mais il vaut mieux classer avec des données similaires autant que possible **. Étant donné que nous connaissons les données de réponse correctes ici, nous aimerions trouver le nombre de groupes qui a le plus grand nombre d'étiquettes de réponse correcte, avec les étiquettes de réponse les plus correctes comme étiquettes de réponse correctes.

Par conséquent, l'indice d'évaluation est ** le nombre d'étiquettes correctes / le nombre total **.

python


#Recherchez le nombre de clusters avec le plus grand nombre de données dans le cluster comme étiquette correcte.
eval_acc_list=[]

for i in range(5,15):
    KM = KMeans(n_clusters = i)
    result = KM.fit(feature[:,:9])
    df_eval = pd.DataFrame(confusion_matrix(train_labels,result.labels_))
    eval_acc = df_eval.max().sum()/df_eval.sum().sum()
    eval_acc_list.append(eval_acc)

plt.plot(range(5,15),eval_acc_list)
plt.xlabel("The number of cluster")
plt.ylabel("accuracy")

C'est le résultat lorsque le nombre de clusters passe de 5 à 15. À mesure que le nombre de grappes augmente, l'homogénéité augmente et la précision augmente. ** Ce qui est le mieux dépend de l'objectif, mais environ 10 groupes semblent être bons compte tenu de l'interprétabilité. ** **

En d'autres termes, il était difficile de le diviser en 10 étiquettes avec le PCA seul. Alors, ensuite, je voudrais combiner une méthode appelée t-SNE.

Classification par PCA + t-SNE

Exécution de t-SNE

** Il était difficile de classer en 10 avec le PCA seul, donc je vais essayer de classer en combinant PCA et t-SNE. ** ** t-SNE est une méthode dont le principe semble difficile (je ne le comprends pas bien). Je mettrai le site avec des explications détaillées dans la référence.

Étant donné que t-SNE est une méthode qui prend beaucoup de temps de calcul, elle classe 10000 éléments de données à 10 dimensions réduites par PCA. Lorsqu'il est visualisé, je pense que cela peut être classé comme un sentiment juste.

python


tsne = TSNE(n_components=2).fit_transform(feature[:10000,:9])
#Visualisation
for i in range(10):
  idx = np.where(train_labels[:10000]==i)
  plt.scatter(tsne[idx,0],tsne[idx,1],label=i)
plt.legend(loc='upper left',bbox_to_anchor=(1.05,1))

image.png

Classification et évaluation par k-means

Ensuite, classez par la méthode des k-moyennes et affichez la matrice de confusion.

python


#Classer tsne par kmeans
KM = KMeans(n_clusters = 10)
result = KM.fit(tsne)

df_eval = pd.DataFrame(confusion_matrix(train_labels[:10000],result.labels_))
df_eval.columns = df_eval.idxmax()
df_eval = df_eval.sort_index(axis=1)

df_eval

image.png

** Comme cela peut arriver, il est bien divisé en 10 étiquettes. C'était bon. ** ** En regardant ce tableau, vous pouvez voir que «4» et «9» sont souvent mal classés. Même si vous regardez le diagramme de dispersion qui visualise réellement les résultats du t-SNE, 4 et 9 sont proches l'un de l'autre.

Vous pouvez voir que 4 et 9 apprennent à être similaires dans cette méthode d'apprentissage. Je ne sais pas pourquoi ils pensent qu'ils sont similaires, mais c'est intéressant.

Enfin, évaluez la précision de chaque nombre de grappes. Lorsque le nombre de clusters est de 10, la précision est de 0,6. Le résultat est un peu plus élevé que lorsque seul le PCA est utilisé.

python


#Recherchez le nombre de clusters avec le plus grand nombre de données dans le cluster comme étiquette correcte.
eval_acc_list=[]

for i in range(5,15):
    KM = KMeans(n_clusters = i)
    result = KM.fit(feature[:,:9])
    df_eval = pd.DataFrame(confusion_matrix(train_labels,result.labels_))
    eval_acc = df_eval.max().sum()/df_eval.sum().sum()
    eval_acc_list.append(eval_acc)

plt.plot(range(5,15),eval_acc_list)
plt.xlabel("The number of cluster")
plt.ylabel("accuracy")

image.png

À la fin

En utilisant mnist comme thème, nous avons implémenté la réduction et la visualisation de dimension par PCA et t-SNE, et la classification et l'évaluation par k-means. Les données non étiquetées sont abondantes dans le monde, donc cela semble être une méthode très utile.

Si vous le trouvez utile, il serait encourageant d'utiliser LGTM, etc.

Références

Livre: ["Apprendre sans professeur par python"](url https://www.amazon.co.jp/Python%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81 % E3% 82% 8B% E6% 95% 99% E5% B8% AB% E3% 81% AA% E3% 81% 97% E5% AD% A6% E7% BF% 92-% E2% 80% 95% E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92% E3% 81% AE% E5% 8F% AF% E8% 83% BD% E6% 80% A7% E3% 82% 92% E5% BA% 83% E3% 81% 92% E3% 82% 8B% E3% 83% A9% E3% 83% 99% E3% 83% AB% E3% 81% AA% E3% 81% 97% E3% 83% 87% E3% 83% BC% E3% 82% BF% E3% 81% AE% E5% 88% A9% E7% 94% A8-Ankur-Patel / dp / 4873119103)

Introduction de la méthode de compression dimensionnelle utilisant t-SNE https://blog.albert2005.co.jp/2015/12/02/tsne/

Comprendre t-SNE et améliorer la visualisation https://qiita.com/g-k/items/120f1cf85ff2ceae4aba

Recommended Posts

J'ai essayé de classer les nombres de mnist par apprentissage non supervisé [PCA, t-SNE, k-means]
Classer les numéros mnist par keras sans apprentissage par l'enseignant [Auto Encoder Edition]
J'ai essayé de classer MNIST par GNN (avec PyTorch géométrique)
J'ai essayé de classer Oba Hanana et Otani Emiri par apprentissage profond
J'ai essayé de classer les boules de dragon par adaline
J'ai essayé de classer Hanana Oba et Emiri Otani par apprentissage profond (partie 2)
J'ai essayé d'implémenter la détection d'anomalies par apprentissage de structure clairsemée
Mayungo's Python Learning Episode 3: J'ai essayé d'imprimer des nombres
J'ai essayé de classer les accords de guitare en temps réel en utilisant l'apprentissage automatique
J'ai essayé de programmer la bulle de tri par langue
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé d'obtenir une image en grattant
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
J'ai essayé de prédire l'évolution de la quantité de neige pendant 2 ans par apprentissage automatique
[Keras] J'ai essayé de résoudre le problème de classification des zones de type beignet par apprentissage automatique [Étude]
J'ai essayé de prédire les courses de chevaux en faisant tout, de la collecte de données à l'apprentissage en profondeur
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
Classer les articles avec des balises spécifiées par Qiita par apprentissage non supervisé
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé le deep learning
J'ai essayé de déboguer.
J'ai essayé de vérifier la classification yin et yang des membres hololive par apprentissage automatique
J'ai essayé de classer les joueurs de Shogi Takami 7e Dan et Masuda 6e Dan par CNN [Pour les débutants CNN]
J'ai essayé d'accélérer la création vidéo en traitant en parallèle
[Introduction à la simulation] J'ai essayé de jouer en simulant une infection corona ♬
[Django] J'ai essayé d'implémenter des restrictions d'accès par héritage de classe.
[Introduction à Pandas] J'ai essayé d'augmenter les données d'échange par interpolation de données ♬
J'ai essayé l'apprentissage automatique pour convertir des phrases en style XX
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
[TF] J'ai essayé de visualiser le résultat de l'apprentissage en utilisant Tensorboard
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
J'ai essayé de classer la musique en majeur / mineur sur Neural Network
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
J'ai essayé d'écrire dans un modèle de langage profondément appris
J'étais frustré par Kaggle, alors j'ai essayé de trouver une bonne propriété locative en grattant et en apprentissage automatique
J'ai essayé HR Tech pour développer un moteur de recherche expert par apprentissage automatique des informations de réunion en interne
Python Learning Episode 4 de Mayungo: J'ai essayé de voir ce qui se passe lorsque les nombres sont traités comme des lettres
J'ai essayé d'organiser SVM.
Classer les données par la méthode k-means
J'ai essayé d'implémenter PCANet
J'ai essayé de réintroduire Linux
J'ai essayé de présenter Pylint
J'ai essayé de résumer SparseMatrix
jupyter je l'ai touché
J'ai essayé d'implémenter StarGAN (1)
J'ai essayé de visualiser les signets volant vers Slack avec Doc2Vec et PCA
[Introduction à la simulation] J'ai essayé de jouer en simulant une infection corona ♬ Partie 2
J'ai essayé de faire la reconnaissance de caractères manuscrits de Kana Partie 1/3 D'abord à partir de MNIST
J'ai essayé de visualiser l'ensemble de données de préférence de boisson par décomposition tenseur.
J'ai essayé de créer une liste de nombres premiers avec python
J'ai essayé d'implémenter la classification des phrases par Self Attention avec PyTorch
J'ai essayé de résumer les commandes utilisées par les ingénieurs débutants aujourd'hui
J'ai fait apprendre à RNN la vague de péché et j'ai essayé de prédire
J'ai essayé de visualiser Boeing de la performance du violon par estimation de pose
J'ai essayé de résoudre le problème de planification des équipes par diverses méthodes
[Apprentissage automatique] J'ai essayé de faire quelque chose comme passer des images
Une méthode simple pour obtenir le taux de réponse correct de MNIST de 97% ou plus en apprenant sans enseignant (sans apprentissage par transfert)