Ich kann GoogleNews-Vectors-negative300.bin.gz von der Word2vec - Site herunterladen. Die .bin-Datei (etwa 3,4 GB) ist ein binäres Format, das für mich nicht nützlich ist. Tomas Mikolov versichert uns dass "Es sollte ziemlich einfach sein, das Binärformat in ein Textformat zu konvertieren (obwohl dies mehr Speicherplatz benötigt). Überprüfen Sie den Code im Entfernungswerkzeug. " Leider verstehe ich nicht genügend C, um http://Word2vec.googlecode.com/svn/trunk/distance.c zu verstehen.
Angeblich kann gensim dies auch tun, aber bei allen Tutorials, die ich gefunden habe, scheint es sich um das Konvertieren von aus - Text zu handeln, nicht umgekehrt.
Kann jemand Änderungen am C-Code oder Anweisungen für gensim zum Ausgeben von Text vorschlagen?
In der Word2vec-Toolkit-Mailingliste hat Thomas Mensink eine answer in Form eines kleinen C-Programms bereitgestellt, das eine .bin-Datei in Text konvertiert. Dies ist eine Modifikation der Datei distance.c. Ich ersetzte die ursprüngliche distance.c durch den folgenden Code von Thomas und baute Word2vec neu (make clean; make) und benannte die kompilierte Distanz in readbin um. Dann erstellt ./readbin vector.bin
eine Textversion von vector.bin.
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.Apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
const long long max_size = 2000; // max length of strings
const long long N = 40; // number of closest words that will be shown
const long long max_w = 50; // max length of vocabulary entries
int main(int argc, char **argv) {
FILE *f;
char file_name[max_size];
float len;
long long words, size, a, b;
char ch;
float *M;
char *vocab;
if (argc < 2) {
printf("Usage: ./distance <FILE>\nwhere FILE contains Word projections in the BINARY FORMAT\n");
return 0;
}
strcpy(file_name, argv[1]);
f = fopen(file_name, "rb");
if (f == NULL) {
printf("Input file not found\n");
return -1;
}
fscanf(f, "%lld", &words);
fscanf(f, "%lld", &size);
vocab = (char *)malloc((long long)words * max_w * sizeof(char));
M = (float *)malloc((long long)words * (long long)size * sizeof(float));
if (M == NULL) {
printf("Cannot allocate memory: %lld MB %lld %lld\n", (long long)words * size * sizeof(float) / 1048576, words, size);
return -1;
}
for (b = 0; b < words; b++) {
fscanf(f, "%s%c", &vocab[b * max_w], &ch);
for (a = 0; a < size; a++) fread(&M[a + b * size], sizeof(float), 1, f);
len = 0;
for (a = 0; a < size; a++) len += M[a + b * size] * M[a + b * size];
len = sqrt(len);
for (a = 0; a < size; a++) M[a + b * size] /= len;
}
fclose(f);
//Code added by Thomas Mensink
//output the vectors of the binary format in text
printf("%lld %lld #File: %s\n",words,size,file_name);
for (a = 0; a < words; a++){
printf("%s ",&vocab[a * max_w]);
for (b = 0; b< size; b++){ printf("%f ",M[a*size + b]); }
printf("\b\b\n");
}
return 0;
}
Ich habe das "\ b\b" aus der printf
entfernt.
Übrigens enthielt die resultierende Textdatei immer noch das Textwort Word und einige unnötige Leerzeichen, die ich für einige numerische Berechnungen nicht wollte. Mit Bash-Befehlen entfernte ich die erste Textspalte und das nachfolgende Leerzeichen aus jeder Zeile.
cut --complement -d ' ' -f 1 GoogleNews-vectors-negative300.txt > GoogleNews-vectors-negative300_tuples-only.txt
sed 's/ $//' GoogleNews-vectors-negative300_tuples-only.txt
Ich benutze diesen Code, um das binäre Modell zu laden, und speichere es dann in einer Textdatei.
from gensim.models.keyedvectors import KeyedVectors
model = KeyedVectors.load_Word2vec_format('path/to/GoogleNews-vectors-negative300.bin', binary=True)
model.save_Word2vec_format('path/to/GoogleNews-vectors-negative300.txt', binary=False)
Hinweis:
Der obige Code ist für die new -Version von gensim. Für die vorherige -Version habe ich diesen Code verwendet.:
from gensim.models import Word2vec
model = Word2vec.Word2Vec.load_Word2vec_format('path/to/GoogleNews-vectors-negative300.bin', binary=True)
model.save_Word2vec_format('path/to/GoogleNews-vectors-negative300.txt', binary=False)
das Format ist ein IEEE 754-Binär-Gleitkommaformat mit einfacher Genauigkeit: binary32 http://en.wikipedia.org/wiki/Single-precision_floating-point_format Sie verwenden Little-Endian.
Lassen Sie uns ein Beispiel machen:
Die nächste Zeile enthält zuerst das Vokab Word und dann (300 * 4 Byte Float-Wert, 4 Byte für jede Dimension):
getByte till byte==32 (space). (60 47 115 62 32 => <\s>[space])
dann repräsentiert jedes 4 Byte eine Float-Nummer
nächstes 4 Byte: 0 0 bis 108 58 => 0,001129150390625.
Sie können den Wikipedia-Link überprüfen, um zu sehen, wie, lassen Sie mich dies als Beispiel tun:
(Little-Endian -> umgekehrte Reihenfolge) 00111010 10010100 00000000 00000000
value = sign * exp * pre
Sie können die Binärdatei in Word2vec laden und die Textversion dann wie folgt speichern:
from gensim.models import Word2vec
model = Word2vec.Word2Vec.load_Word2vec_format('Path/to/GoogleNews-vectors-negative300.bin', binary=True)
model.save("file.txt")
`
Ich verwende gensim, um mit GoogleNews-Vectors-negative300.bin zu arbeiten, und füge beim Laden des Modells ein binary = True
-Flag hinzu.
from gensim import Word2vec
model = Word2vec.Word2Vec.load_Word2vec_format('Path/to/GoogleNews-vectors-negative300.bin', binary=True)
Scheint gut zu funktionieren.
Ich hatte ein ähnliches Problem, ich wollte bin/non-bin (gensim) Modelle als CSV ausgeben.
hier ist der Code, der das auf Python macht, es setzt voraus, dass Sie gensim installiert haben:
convertvec ist ein kleines Tool zum Konvertieren von Vektoren zwischen verschiedenen Formaten für die Word2vec-Bibliothek.
Vektoren von binärem in einfachen Text konvertieren:
./convertvec bin2txt input.bin output.txt
Vektoren vom Klartext in den Binärcode konvertieren:
./convertvec txt2bin input.txt output.bin
Wenn Sie den Fehler erhalten:
ImportError: No module named models.Word2vec
dann, weil es ein API-Update gab. Das wird funktionieren:
from gensim.models.keyedvectors import KeyedVectors
model = KeyedVectors.load_Word2vec_format('./GoogleNews-vectors-negative300.bin', binary=True)
model.save_Word2vec_format('./GoogleNews-vectors-negative300.txt', binary=False)
Hier ist der Code, den ich verwende:
import codecs
from gensim.models import Word2Vec
def main():
path_to_model = 'GoogleNews-vectors-negative300.bin'
output_file = 'GoogleNews-vectors-negative300_test.txt'
export_to_file(path_to_model, output_file)
def export_to_file(path_to_model, output_file):
output = codecs.open(output_file, 'w' , 'utf-8')
model = Word2Vec.load_Word2vec_format(path_to_model, binary=True)
print('done loading Word2Vec')
vocab = model.vocab
for mid in vocab:
#print(model[mid])
#print(mid)
vector = list()
for dimension in model[mid]:
vector.append(str(dimension))
#line = { "mid": mid, "vector": vector }
vector_str = ",".join(vector)
line = mid + "\t" + vector_str
#line = json.dumps(line)
output.write(line + "\n")
output.close()
if __== "__main__":
main()
#cProfile.run('main()') # if you want to do some profiling
Nur ein kurzes Update, da es jetzt einfacher geht.
Wenn Sie Word2vec
aus https://github.com/dav/Word2vec verwenden, gibt es eine zusätzliche Option namens -binary
, die 1
zur Erzeugung einer Binärdatei oder 0
zur Erstellung einer Textdatei akzeptiert. Dieses Beispiel stammt aus demo-Word.sh
im Repo:
time ./Word2vec -train text8 -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -binary 0 -iter 15