2014-12-05 3 views
41

С сайта word2vec я могу скачать GoogleNews-vectors-negative300.bin.gz. Файл .bin (около 3,4 ГБ) - это двоичный формат, который мне не пригодится. Томас Миколов assures us: «Для преобразования двоичного формата в текстовый формат должно быть довольно просто (хотя это займет больше места на диске). Проверьте код в инструменте расстояния, довольно просто читать двоичный файл». К сожалению, я не знаю достаточно C, чтобы понять http://word2vec.googlecode.com/svn/trunk/distance.c.Преобразование файла word2vec bin в текст

Предположительно gensim может это сделать, но все учебные пособия, которые я нашел, похоже, касаются преобразования из текста, а не в другую сторону.

Может кто-нибудь предложить изменения кода C или инструкции по генерации текста для gensim?

ответ

16

В списке рассылки word2vec-toolkit Thomas Mensink предоставил answer в виде небольшой программы на C, которая преобразует файл .bin в текст. Это модификация файла distance.c. Я заменил исходное расстояние.c на код Томаса ниже и перестроил word2vec (make clean, make) и переименовал скомпилированное расстояние в readbin. Затем ./readbin vector.bin создаст текстовую версию 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; 
} 

Я удалил "\ Ь \ Ъ" от printf.

Кстати, в результате текстового файла все еще содержалось текстовое слово и некоторые ненужные пробелы, которые я не хотел для некоторых численных расчетов. Я удалил начальный текстовый столбец и конечный пустую строку из каждой строки командами bash.

cut --complement -d ' ' -f 1 GoogleNews-vectors-negative300.txt > GoogleNews-vectors-negative300_tuples-only.txt 
sed 's/ $//' GoogleNews-vectors-negative300_tuples-only.txt 
+1

https://gist.github.com/unhammer/e56e26d7d2938ef40ebb вы также можете не читать все это в памяти – unhammer

2

Я использую gensim работать с GoogleNews-векторов-negative300.bin и я в том числе binary = True флаг при загрузке модели.

from gensim import word2vec 

model = word2vec.Word2Vec.load_word2vec_format('Path/to/GoogleNews-vectors-negative300.bin', binary=True) 

Кажется, что он работает нормально.

+0

Это должно быть принято отвечать, так как @Glenn упоминается с использованием 'gensim' в любом случае , – hlin117

2

У меня была аналогичная проблема, я хотел получить модели bin/non-bin (gensim) как CSV.

вот код, который делает это на питона, это предполагает, что вы gensim установили:

https://gist.github.com/dav009/10a742de43246210f3ba

7

формат IEEE 754 с одинарной точностью в двоичном формате с плавающей точкой: binary32 http://en.wikipedia.org/wiki/Single-precision_floating-point_format Они используют прямой порядок байтов.

Пусть сделать пример:

  • Первая линия Формат строки: "3000000 300 \ п" (vocabSize & vecSize, GetByte до байта == '\ п')
  • Следующая строка включает Vocab слово, а затем (300 * 4 байт значения с плавающей точкой, 4 байта для каждого размерности):

    getByte till byte==32 (space). (60 47 115 62 32 => <\s>[space]) 
    
  • то каждый следующий 4 байт будет представлять один номер с плавающей точкой

    следующий 4 байт: 0 0 -108 58 => 0,001129150390625.

Вы можете проверить ссылку википедии, чтобы увидеть, как, позвольте мне сделать это один, как, например:

(прямой порядок байтов -> в обратном порядке) 00111010 10010100 00000000 00000000

  • первый является знаковый бит => знак = 1 (else = -1)
  • следующий 8 бит => 117 => exp = 2^(117-127)
  • следующий 23 бит => pre = 0 * 2^(- 1) + 0 * 2^(- 2) + 1 * 2^(- 3) + 1 * 2^(- 5)

значение знака = * ехр * предварительно

4

Вы можете загрузить двоичный файл в word2vec, а затем сохранить текстовую версию так:

from gensim.models import word2vec 
model = word2vec.Word2Vec.load_word2vec_format('Path/to/GoogleNews-vectors-negative300.bin', binary=True) 
model.save("file.txt") 

`

1

Вот код Я использую:

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 __name__ == "__main__": 
    main() 
    #cProfile.run('main()') # if you want to do some profiling 
+0

В первой строке отсутствует «vocabSize vecSize \ n» – cgl

+0

@FranckDernoncourt привет, не могли бы вы проверить https://stackoverflow.com/questions/44736915/how-to-get-the-google-word2vec-vectors спасибо. – Rafael

51

Этот код используется для загрузки двоичной модели, затем сохраните модель текстовый файл,

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) 

Ссылки: API и nullege.

Примечание:

Над кодом для новой версии gensim. Для предыдущей версии, я использовал этот код:

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) 
+1

Эта работа отлично подходит для меня. – Ash

+1

gensim 2.0 больше не имеет метода 'load_word2vec_format' для' KeyedVectors', но это сработало для меня, когда я использовал 'gensim.models.Word2Vec.laod_word2vec_format' непосредственно с параметром binary = True/False – hobs

1

convertvec это небольшой инструмент для преобразования векторов между различными форматами для word2vec библиотеки.

Преобразование векторов из двоичного в виде простого текста:

./convertvec bin2txt input.bin выход.TXT

Преобразование векторов из простого текста в двоичный:

./convertvec txt2bin input.txt output.bin

0

Только быстрое обновление, как теперь есть более простой способ.

Если вы используете word2vec из https://github.com/dav/word2vec есть дополнительная опция называется -binary которые примут 1 генерировать двоичный файл или 0 для создания текстового файла. Этот пример взят из demo-word.sh в репо:

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

0

Если вы получаете ошибку:

ImportError: No module named models.word2vec 

то это потому, что там было обновление API. Это будет работать:

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) 
Смежные вопросы