Il s'agit de l'enregistrement de la 85e "Compression de dimension par analyse en composantes principales" de Traitement du langage 100 knock 2015. Compresse environ 400 000 dimensions à 300 dimensions. Cette fois, nous effectuons une décomposition en valeurs singulières au lieu d'une analyse en composantes principales. Si nous devions analyser les principaux composants avec scikit-learn, nous ne pourrions pas le faire avec une matrice clairsemée, alors nous avons compromis: "Les deux sont des réductions dimensionnelles!" L'analyse des composants principaux a été apprise lors de la 8e semaine du célèbre cours en ligne d'apprentissage automatique de Coursera. Si vous êtes intéressé par le cours, veuillez vous référer à l'article "Cours d'introduction à l'apprentissage automatique en ligne Tora no Maki (recommandé pour les adultes qui travaillent)".
Lien | Remarques |
---|---|
085.Compression dimensionnelle par analyse en composantes principales.ipynb | Lien GitHub du programme de réponse |
100 coups de traitement du langage amateur:85 | Je vous suis toujours redevable de 100 coups de traitement linguistique |
TruncatedSVD | Aide officielle pour SVD tronqué |
À propos de la relation entre PCA et SVD | Différence entre l'analyse en composantes principales et la décomposition en valeur singulière 1 |
Afficher la relation entre PCA et SVD | Différence entre l'analyse en composantes principales et la décomposition en valeurs singulières 2 |
type | version | Contenu |
---|---|---|
OS | Ubuntu18.04.01 LTS | Il fonctionne virtuellement |
pyenv | 1.2.15 | J'utilise pyenv car j'utilise parfois plusieurs environnements Python |
Python | 3.6.9 | python3 sur pyenv.6.J'utilise 9 3.7 ou 3.Il n'y a aucune raison profonde de ne pas utiliser la série 8 Les packages sont gérés à l'aide de venv |
Dans l'environnement ci-dessus, j'utilise les packages Python supplémentaires suivants. Installez simplement avec pip ordinaire.
type | version |
---|---|
matplotlib | 3.1.1 |
numpy | 1.17.4 |
pandas | 0.25.3 |
scipy | 1.4.1 |
scikit-learn | 0.21.3 |
enwiki-20150112-400-r10-105752.txt.bz2 Le texte de 105 752 articles est-il échantillonné au hasard au 1/10 des articles composés d'environ 400 mots ou plus parmi les articles de Wikipedia anglais au 12 janvier 2015, compressé au format bzip2. y a-t-il. En utilisant ce texte comme corpus, je souhaite apprendre un vecteur (expression distribuée) qui exprime le sens d'un mot. Dans la première moitié du chapitre 9, le processus d'apprentissage du vecteur de mot est mis en œuvre en le divisant en plusieurs processus en appliquant l'analyse en composantes principales à la matrice de cooccurrence de contexte de mot créée à partir du corpus. Dans la seconde moitié du chapitre 9, le vecteur de mots (300 dimensions) obtenu par apprentissage est utilisé pour calculer la similitude des mots et analyser (analogique).
Notez que si le problème 83 est implémenté de manière obéissante, une grande quantité (environ 7 Go) de stockage principal sera nécessaire. Si vous manquez de mémoire, concevez un processus ou un corpus d'échantillonnage 1/100 enwiki-20150112-400-r100-10576.txt.bz2 Utilisez /nlp100/data/enwiki-20150112-400-r100-10576.txt.bz2).
Cette fois * "Corpus d'échantillonnage 1/100 [enwiki-20150112-400-r100-10576.txt.bz2](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/enwiki-20150112-" 400-r100-10576.txt.bz2) "* est utilisé.
Appliquez l'analyse en composantes principales à la matrice de contexte de mot obtenue en> 84 et compressez le vecteur de signification du mot à 300 dimensions.
import matplotlib.pyplot as plt
import numpy as np
from scipy import io
from sklearn.decomposition import TruncatedSVD
matrix_x = io.loadmat('084.matrix_x.mat')['x']
#Confirmer la lecture
print('matrix_x Shape:', matrix_x.shape)
print('matrix_x Number of non-zero entries:', matrix_x.nnz)
print('matrix_x Format:', matrix_x.getformat())
#Compression de dimension
svd = TruncatedSVD(300)
matrix_x300 = svd.fit_transform(matrix_x)
print(type(matrix_x300))
print('matrix_x300 Shape:',matrix_x300.shape)
print('Explained Variance Ratio Sum:', svd.explained_variance_ratio_.sum())
ev_ratio = svd.explained_variance_ratio_
ev_ratio = np.hstack([0,ev_ratio.cumsum()])
plt.plot(ev_ratio)
plt.show()
np.savez_compressed('085.matrix_x300.npz', matrix_x300)
Chargez le fichier de format de tapis enregistré en frappant la dernière fois.
matrix_x = io.loadmat('084.matrix_x.mat')['x']
#Confirmer la lecture
print('matrix_x Shape:', matrix_x.shape)
print('matrix_x Number of non-zero entries:', matrix_x.nnz)
print('matrix_x Format:', matrix_x.getformat())
Dans la sortie ci-dessus, vous pouvez voir que les éléments Shape et non nul sont identiques à la dernière fois. Cependant, le format est «csc» même si je l'ai enregistré sous «lil». Est-ce une telle chose? Je vais continuer sans m'en soucier.
matrix_x Shape: (388836, 388836)
matrix_x Number of non-zero entries: 447875
matrix_x Format: csc
C'est la partie de compression de dimension principale de ce temps. Cependant, j'utilise juste la fonction TruncatedSVD
, donc je n'ai aucun problème. Cela a pris environ 8 minutes.
svd = TruncatedSVD(300)
matrix_x300 = svd.fit_transform(matrix_x)
print(type(matrix_x300))
print('matrix_x300 Shape:',matrix_x300.shape)
En vérifiant la valeur de retour, cela ressemble au format numpy.ndarray
. Il est vrai que la matrice dense est correcte, pas la matrice clairsemée, car elle est compressée dimensionnellement.
<class 'numpy.ndarray'>
matrix_x300 Shape: (388836, 300)
Voyons maintenant combien nous pouvons conserver la distribution. Je me réfère à l'article "Scikit-learn pour l'analyse des composantes principales (calcul du taux de cotisation cumulé)".
print('Explained Variance Ratio Sum:', svd.explained_variance_ratio_.sum())
ev_ratio = svd.explained_variance_ratio_
ev_ratio = np.hstack([0,ev_ratio.cumsum()])
plt.plot(ev_ratio)
plt.show()
Environ 30%. Faible···. Vaut-il mieux augmenter le nombre de dimensions? ["Il est souhaitable de dépasser 99%, mais il semble que 95% ou 90% peut être le seuil."](Https://qiita.com/FukuharaYohei/items/7a71be58818719cdf73c#232-choosing -le-nombre-de-composants-principaux) J'ai appris ...
Explained Variance Ratio Sum: 0.31949196039604355
Il s'agit d'un graphique en lignes de pliage qui accumule le taux de rétention de dispersion pour chaque composant principal.
Pour alléger le fichier, il est compressé et sauvegardé avec la fonction save_compressed
. Pourtant, la taille du fichier est de 118 Mo. La taille du fichier enregistré dans la matrice clairsemée précédente était de 7 Mo, donc même s'il était compressé dimensionnellement, il gonflait en raison de la matrice dense. À propos, l'utilisation de la mémoire avant l'enregistrement de la compression est de 933 Mo, il semble donc qu'elle soit beaucoup plus réduite par la compression. Cependant, en revanche, le temps qui a pris 9 secondes est passé à 36.
Concernant la sauvegarde, je me suis référé à l'article «Comparez la différence de taille de fichier en fonction de la méthode de sérialisation du tableau numpy».
np.savez_compressed('085.matrix_x300.npz', matrix_x300)
J'ai cherché à savoir si «l'analyse des composants principaux» pouvait être effectuée comme décrit dans la mission. Le goulot d'étranglement est de savoir si des matrices éparses peuvent être utilisées comme entrée. Stackoverflow's "Exécution de l'ACP sur une grande matrice clairsemée à l'aide de sklearn" Il était écrit que c'était impossible. [MRG] Implement randomized PCA # 12841 semble implémenter une fonction pour entrer une matrice clairsemée, mais elle reste ouverte. ・ ・ ・ Je pensais qu'il serait possible d'apprendre petit à petit avec la quantité de mémoire qui peut être surmontée dans une file d'attente dense, mais même si cela pouvait être fait, cela prendrait énormément de temps, alors j'ai abandonné ...
J'ai senti que le taux de rétention de dispersion d'environ 30% était faible, j'ai donc augmenté la dimension. Au début, je l'ai fait en 1000 dimensions, mais une erreur s'est produite en raison d'une mémoire insuffisante ... Avec 600 dimensions, cela ne s'est pas terminé même après 30 minutes, et c'était gênant, alors je me suis arrêté à mi-chemin. Il a fallu 18 minutes pour 450 dimensions. Le taux de rétention de dispersion à ce moment était de 38%, ce qui est considérablement plus élevé. Cela ressemble à ceci lorsqu'on le compare.
dimension | temps de traitement | Valeur de retour(matrix_x300)Mémoire | taille du fichier |
---|---|---|---|
300 dimensions | 8 minutes | 0.9GB | 118MB |
450 dimensions | 18 minutes | 1.40GB | 178MB |
Recommended Posts