Dies ist die Aufzeichnung der 84. "Erstellung einer Wortkontextmatrix" von Language Processing 100 Knock 2015. Erstellen Sie eine Matrix mit 160 Milliarden Elementen in 400.000 x 400.000. Wenn es 160 Milliarden Elemente gibt, scheint es im Allgemeinen eine große Größe zu sein, aber da es sich um eine spärliche Matrix mit fast 0 handelt, sind es ungefähr 7 MB, selbst wenn die Matrix als Datei gespeichert ist. Das "scipy" -Paket, das spärliche Matrizen verarbeitet, ist erstaunlich.
Verknüpfung | Bemerkungen |
---|---|
084.Erstellen einer Wortkontextmatrix.ipynb | Antwortprogramm GitHub Link |
100 Klicks Amateur-Sprachverarbeitung:84 | Ich bin Ihnen immer zu Dank verpflichtet, wenn ich auf 100 Sprachverarbeitung klopfe |
100 Sprachverarbeitung klopfen 2015 Version(83,84) | Ich habe in Kapitel 9 darauf hingewiesen. |
Art | Ausführung | Inhalt |
---|---|---|
OS | Ubuntu18.04.01 LTS | Es läuft virtuell |
pyenv | 1.2.15 | Ich benutze pyenv, weil ich manchmal mehrere Python-Umgebungen benutze |
Python | 3.6.9 | python3 auf pyenv.6.Ich benutze 9 3.7 oder 3.Es gibt keinen tiefen Grund, keine 8er-Serie zu verwenden Pakete werden mit venv verwaltet |
In der obigen Umgebung verwende ich die folgenden zusätzlichen Python-Pakete. Einfach mit normalem Pip installieren.
Art | Ausführung |
---|---|
pandas | 0.25.3 |
scipy | 1.4.1 |
enwiki-20150112-400-r10-105752.txt.bz2 Ist der Text von 105.752 Artikeln zufällig 1/10 aus den Artikeln ausgewählt, die zum 12. Januar 2015 aus etwa 400 Wörtern oder mehr der englischen Wikipedia-Artikel bestehen und im bzip2-Format komprimiert sind. Gibt es. Mit diesem Text als Korpus möchte ich einen Vektor (verteilten Ausdruck) lernen, der die Bedeutung eines Wortes ausdrückt. In der ersten Hälfte von Kapitel 9 wird der Prozess des Lernens des Wortvektors implementiert, indem er in mehrere Prozesse unterteilt wird, indem die Hauptkomponentenanalyse auf die aus dem Korpus erstellte Matrix für das gleichzeitige Auftreten von Wortkontexten angewendet wird. In der zweiten Hälfte von Kapitel 9 wird der durch Lernen erhaltene Wortvektor (300 Dimensionen) verwendet, um die Ähnlichkeit von Wörtern zu berechnen und zu analysieren (analog).
Beachten Sie, dass bei gehorsamer Implementierung von Problem 83 eine große Menge (ca. 7 GB) Hauptspeicher erforderlich ist. Wenn Ihnen der Speicher ausgeht, erstellen Sie einen Prozess oder ein 1/100 Stichproben-Korpus enwiki-20150112-400-r100-10576.txt.bz2. Verwenden Sie /nlp100/data/enwiki-20150112-400-r100-10576.txt.bz2).
Diesmal * 1/100 Stichprobenkorpus enwiki-20150112-400-r100-10576.txt.bz2 400-r100-10576.txt.bz2) ”* wird verwendet.
Erstellen Sie eine Wortkontextmatrix $ X $ mit der Ausgabe von> 83. Jedes Element $ X_ {tc} $ der Matrix $ X $ ist jedoch wie folgt definiert.
-Wenn $ f (t, c) ≥ 10 $ ist, dann ist $ X_ {tc} = $ PPMI ($ t $, $ c $) $ = $ max {log $ \ frac {N × f (t, c) } {f (t, ∗) × f (∗, c)} $, 0} -Wenn $ f (t, c) <10 $, dann ist $ X_ {tc} = 0 $
Hier ist PPMI ($ t $, $ c $) eine Statistik namens Positive Pointwise Mutual Information. Beachten Sie, dass die Anzahl der Zeilen und Spalten der Matrix $ X $ in der Größenordnung von Millionen liegt und es unmöglich ist, alle Elemente der Matrix im Hauptspeicher abzulegen. Glücklicherweise sind die meisten Elemente in der Matrix $ X $ 0, sodass Sie nur die Nicht-Null-Elemente ausschreiben müssen.
Angenommen, Sie haben die folgende Datei für den Satz "Ich bin ein Junge" auf dieselbe Weise wie beim vorherigen Klopfen erstellt.
I am
I a
am I
am a
a am
a boy
boy am
boy a
Erstellen Sie im Gegensatz zu oben die folgende Matrix als Bild. In diesem Beispiel handelt es sich um eine Matrix mit geringer Dichte, da es sich um 4 Spalten x 4 Zeilen handelt. Diesmal handelt es sich jedoch um ungefähr 400.000 Spalten x 400.000 Zeilen. Es handelt sich also um eine Matrix mit geringer Dichte in einem matschigen Zustand.
I | am | a | boy | |
---|---|---|---|---|
I | 1 | 1 | ||
am | 1 | 1 | ||
a | 1 | 1 | ||
boy | 1 | 1 |
Die obige Matrix setzt einfach das Element der Matrix auf 1, setzt aber hier die folgenden Werte. In Bezug auf PPMI [Artikel "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 /) ist leicht zu verstehen.
-Wenn $ f (t, c) ≥ 10 $ ist, dann ist $ X_ {tc} = $ PPMI ($ t $, $ c $) $ = $ max {log $ \ frac {N × f (t, c) } {f (t, ∗) × f (∗, c)} $, 0} -Wenn $ f (t, c) <10 $, dann ist $ X_ {tc} = 0 $
import math
import pandas as pd
from scipy import sparse, io
#Lesen Sie die Anzahl der gleichzeitigen Vorkommen von Wort t und Kontextwort c ab und entfernen Sie Kombinationen von gleichzeitigen Vorkommen von 9 oder weniger
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
#Überprüfen Sie die dünne Matrix
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})
Ich verwende die Funktion pandas'read_pickle`, um die beim letzten Klopfen gespeicherte Datei zu lesen. Sie können das Zip-Format einfach so lesen, wie es ist. Die Verarbeitungszeit wird jedoch durch den Grad der Dekomprimierung addiert (es dauert ungefähr 13 Sekunden für die gesamte Funktion). Nach dem Lesen werfe ich Aufzeichnungen mit weniger als 10 gleichzeitigen Vorkommen weg. Ich wollte nicht die gesamte Datei im Speicher behalten, bevor sie weggeworfen wurde, also habe ich die Funktion "read_tc" erstellt.
#Lesen Sie die Anzahl der gleichzeitigen Vorkommen von Wort t und Kontextwort c ab und entfernen Sie Kombinationen von gleichzeitigen Vorkommen von 9 oder weniger
def read_tc():
group_tc = pd.read_pickle('./083_group_tc.zip')
return group_tc[group_tc > 9]
Die verbleibenden 2 Dateien werden so gelesen, wie sie sind, da sie nicht X-mal oder weniger abgeschnitten werden.
group_t = pd.read_pickle('./083_group_t.zip')
group_c = pd.read_pickle('./083_group_c.zip')
Hier verwenden wir scipy, um eine dünn besetzte Matrixvariable matrix_x
zu erstellen. Multiplizieren Sie die Anzahl der Zielwörter und Kontextwörter. Es gibt verschiedene Arten der Behandlung von Matrizen mit geringer Dichte. Da die Eingabe jedoch ein Format namens lil verwendet, wird die Matrix mit der Funktion lil_matrix
erstellt.
matrix_x = sparse.lil_matrix((len(group_t), len(group_c)))
Das Folgende ist der Hauptteil dieses Klopfens. Berechnen Sie den PPMI und setzen Sie ihn auf eine dünne Matrix. Der mit "68000317" gekennzeichnete Teil legt den Wert fest, der durch das vorherige Klopfen erhalten wurde.
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
Erweitern Sie die obige PPMI-Berechnungsformel unter Bezugnahme auf Artikel "100 Language Processing Knock 2015 Edition, Kapitel 9, überarbeitet (1)". Ich habe es mit der Formel versucht, aber es wurde nicht schneller, also habe ich es abgelehnt (LOG_N
wurde im Voraus berechnet). Es ist ziemlich langsam (Ist mein Weg falsch?).
ppmi = max(LOG_N + math.log(v) - math.log ( group_t[ind[0]] ) - math.log( group_c[ind[1]] ), 0)
Überprüfen Sie die erstellte Sparse-Matrix.
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())
Die folgenden Informationen werden ausgegeben. Die zweite Zeile gibt die Anzahl der eingegebenen Einträge an, ist jedoch 400.000 x 400.000, was 450.000 Elementen von 160 Milliarden Elementen entspricht. Sie können also sehen, dass die Dichte weniger als 0,1% beträgt.
matrix_x Shape: (388836, 388836)
matrix_x Number of non-zero entries: 447875
matrix_x Format: lil
Zum Schluss speichern. Die Erweiterung ist "mat" und es scheint ein Format zu sein, das mit MATLAB / Octave verwendet werden kann. Dies ist diejenige, die in den Übungen des berühmten Coursera-Einführungskurses für maschinelles Lernen verwendet wird. Wenn Sie interessiert sind, lesen Sie bitte "Coursera Machine Learning Online-Einführungskurs Tora no Maki (empfohlen für berufstätige Erwachsene)".
io.savemat('084.matrix_x.mat', {'x': matrix_x})
Der für jede Variable verwendete Speicher war wie folgt.
Variable | Erinnerung | Komprimierte Dateigröße |
---|---|---|
group_c | 40MB | 3MB |
group_t | 40MB | 3MB |
group_tc | 64MB | 104MB |
Der verwendete Speicher wird durch Einfügen des folgenden Codes überprüft. Es ist ein Kopieren und Einfügen aus Artikel "[Suchen und Löschen speicherintensiver Variablen auf 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: #Nur hier arrangieren
print("{}{: >25}{}{: >10}{}".format('|',var_name,'|',sys.getsizeof(eval(var_name)),'|'))