Il s'agit de l'enregistrement de la 84e "Création de la matrice de contexte de mots" de Traitement du langage 100 knock 2015.
Créez une matrice de 160 milliards d'éléments en 400 000 x 400 000. Généralement, s'il y a 160 milliards d'éléments, cela semble être une taille énorme, mais comme il s'agit d'une matrice clairsemée avec presque 0, même si la matrice est enregistrée sous forme de fichier, elle fait environ 7 Mo. Le paquet scipy
qui gère les matrices clairsemées est incroyable.
Lien | Remarques |
---|---|
084.Créer une matrice de contexte de mots.ipynb | Lien GitHub du programme de réponse |
100 coups de traitement du langage amateur:84 | Je vous suis toujours redevable de 100 coups de traitement linguistique |
100 langues de traitement knock version 2015(83,84) | J'y ai fait référence au chapitre 9. |
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 |
---|---|
pandas | 0.25.3 |
scipy | 1.4.1 |
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é.
Créez une matrice de contexte de mot $ X $ en utilisant la sortie de> 83. Cependant, chaque élément $ X_ {tc} $ de la matrice $ X $ est défini comme suit.
-Si $ f (t, c) ≥10 $, alors $ X_ {tc} = $ PPMI ($ t $, $ c $) $ = $ max {log $ \ frac {N × f (t, c) } {f (t, ∗) × f (∗, c)} $, 0} -Si $ f (t, c) <10 $, alors $ X_ {tc} = 0 $
Ici, PPMI ($ t $, $ c $) est une statistique appelée information mutuelle ponctuelle positive. Notez que le nombre de lignes et de colonnes de la matrice $ X $ est de l'ordre du million, et il est impossible de mettre tous les éléments de la matrice sur la mémoire principale. Heureusement, la plupart des éléments de la matrice $ X $ sont 0, il vous suffit donc d'écrire les éléments non nuls.
Par exemple, supposons que vous ayez créé le fichier suivant pour la phrase "Je suis un garçon" de la même manière que le coup précédent.
I am
I a
am I
am a
a am
a boy
boy am
boy a
Contrairement à ce qui précède, créez la matrice suivante en tant qu'image. Dans cet exemple, il s'agit d'une matrice clairsemée car il s'agit de 4 colonnes x 4 lignes, mais cette fois, il s'agit d'environ 400 000 colonnes x 400 000 lignes, il s'agit donc d'une matrice clairsemée dans un état squishy.
I | am | a | boy | |
---|---|---|---|---|
I | 1 | 1 | ||
am | 1 | 1 | ||
a | 1 | 1 | ||
boy | 1 | 1 |
La matrice ci-dessus définit simplement l'élément de la matrice sur 1, mais définissez ici les valeurs suivantes. Concernant PPMI, [Article "Pointwise Mutual Information (PMI)"](https://camberbridge.github.io/2016/07/08/%E8%87%AA%E5%B7 % B1% E7% 9B% B8% E4% BA% 92% E6% 83% 85% E5% A0% B1% E9% 87% 8F-Pointwise-Mutual-Information-PMI-% E3% 81% AB% E3% 81% A4% E3% 81% 84% E3% 81% A6 /) est facile à comprendre.
-Si $ f (t, c) ≥10 $, alors $ X_ {tc} = $ PPMI ($ t $, $ c $) $ = $ max {log $ \ frac {N × f (t, c) } {f (t, ∗) × f (∗, c)} $, 0} -Si $ f (t, c) <10 $, alors $ X_ {tc} = 0 $
import math
import pandas as pd
from scipy import sparse, io
#Lire le nombre de cooccurrences du mot t et du mot de contexte c et supprimer les combinaisons de nombres de cooccurrences de 9 ou moins
def read_tc():
group_tc = pd.read_pickle('./083_group_tc.zip')
return group_tc[group_tc > 9]
group_tc = read_tc()
group_t = pd.read_pickle('./083_group_t.zip')
group_c = pd.read_pickle('./083_group_c.zip')
matrix_x = sparse.lil_matrix((len(group_t), len(group_c)))
for ind ,v in group_tc.iteritems():
ppmi = max(math.log((68000317 * v) / (group_t[ind[0]] * group_c[ind[1]])), 0)
matrix_x[group_t.index.get_loc(ind[0]), group_c.index.get_loc(ind[1])] = ppmi
#Vérifier la matrice clairsemée
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())
io.savemat('084.matrix_x.mat', {'x': matrix_x})
J'utilise la fonction pandas''read_picklepour lire le fichier enregistré lors du dernier coup. Vous pouvez simplement lire le format zip tel quel. Cependant, le temps de traitement est ajouté par la quantité de décompression (cela prend environ 13 secondes pour toute la fonction). Après avoir lu, je jette des disques avec moins de 10 cooccurrences. Je ne voulais pas garder le fichier entier en mémoire avant qu'il ne soit jeté, j'ai donc créé la fonction
read_tc`.
#Lire le nombre de cooccurrences du mot t et du mot de contexte c et supprimer les combinaisons de nombres de cooccurrences de 9 ou moins
def read_tc():
group_tc = pd.read_pickle('./083_group_tc.zip')
return group_tc[group_tc > 9]
Les 2 fichiers restants sont lus tels quels car ils ne sont pas tronqués X fois ou moins.
group_t = pd.read_pickle('./083_group_t.zip')
group_c = pd.read_pickle('./083_group_c.zip')
Ici, nous utilisons scipy pour créer une variable de matrice clairsemée matrix_x
. Multipliez le nombre de mots cibles et de mots contextuels. Il existe plusieurs types de gestion des matrices creuses, mais comme l'entrée utilise un format appelé lil, la matrice est créée avec la fonction lil_matrix
.
matrix_x = sparse.lil_matrix((len(group_t), len(group_c)))
Ce qui suit est la partie principale de ce coup. Calculez le PPMI et définissez-le sur une matrice creuse. La partie marquée «68000317» définit la valeur obtenue par le coup précédent.
for ind ,v in group_tc.iteritems():
ppmi = max(math.log((68000317 * v) / (group_t[ind[0]] * group_c[ind[1]])), 0)
matrix_x[group_t.index.get_loc(ind[0]), group_c.index.get_loc(ind[1])] = ppmi
Développez la formule de calcul PPMI ci-dessus en vous référant à Article "100 Language Processing Knock 2015 Edition Chapter 9 Revisited (1)" Je l'ai essayé avec la formule, mais cela ne s'est pas accéléré, alors je l'ai rejeté (LOG_N
a été calculé à l'avance). C'est plutôt lent (est-ce que mon chemin est faux?).
ppmi = max(LOG_N + math.log(v) - math.log ( group_t[ind[0]] ) - math.log( group_c[ind[1]] ), 0)
Vérifiez la matrice creuse créée.
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())
Les informations suivantes sont produites. La deuxième ligne est le nombre d'entrées saisies, mais il est de 400 000 x 400 000, soit 450 000 éléments sur 160 milliards d'éléments, vous pouvez donc voir que la densité est inférieure à 0,1%.
matrix_x Shape: (388836, 388836)
matrix_x Number of non-zero entries: 447875
matrix_x Format: lil
Enfin économisez. L'extension est "mat" et semble être un format qui peut être utilisé avec MATLAB / Octave. C'est celui utilisé dans les exercices du célèbre cours d'introduction en ligne à l'apprentissage automatique de Coursera. Si vous êtes intéressé, veuillez vous référer au "Cours d'introduction en ligne à l'apprentissage automatique Coursera Tora no Maki (recommandé pour les adultes qui travaillent)".
io.savemat('084.matrix_x.mat', {'x': matrix_x})
La mémoire utilisée pour chaque variable était comme ça.
variable | Mémoire | Taille du fichier compressé |
---|---|---|
group_c | 40MB | 3MB |
group_t | 40MB | 3MB |
group_tc | 64MB | 104MB |
La mémoire utilisée est vérifiée en insérant le code suivant. Il s'agit d'un copier-coller de Article "[Rechercher et supprimer des variables consommatrices de mémoire sur Jupyter (IPython)]".
print("{}{: >25}{}{: >10}{}".format('|','Variable Name','|','Memory','|'))
print(" ------------------------------------ ")
for var_name in dir():
if not var_name.startswith("_") and sys.getsizeof(eval(var_name)) > 10000: #Arrangez seulement ici
print("{}{: >25}{}{: >10}{}".format('|',var_name,'|',sys.getsizeof(eval(var_name)),'|'))
Recommended Posts