более быстрый способ чтения Word2vec TXT в Python - PullRequest
0 голосов
/ 17 января 2019

У меня есть стандартный вывод word2vec, который представляет собой файл .txt, отформатированный следующим образом:

[number of words] [dimension (300)]
word1 [300 float numbers separated by spaces]
word2 ...

Теперь я хочу прочитать не более M представлений слов из этого файла.Простым способом является зацикливание первых M+1 строк в файле и сохранение векторов M в массиве numpy.Но это очень медленно, есть ли более быстрый путь?

1 Ответ

0 голосов
/ 17 января 2019

Что значит "супер медленный"? По сравнению с чем?

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

Библиотека gensim в Python включает классы для работы с слово-векторами в этом формате. И его подпрограммы включают необязательный аргумент limit для чтения только определенного числа векторов с начала файла. Например, это будет считывать 1-ю 1000 из файла с именем vectors.txt:

word_vecs = KeyedVectors.load_word2vec_format('word-vectors.txt', 
                                              binary=False,
                                              limit=1000)

Я никогда не замечал, что это очень медленная операция, даже когда загружается что-то вроде набора 3 ГБ + векторов слов, выпущенного Google. (Если это кажется слишком медленным, возможно, у вас недостаточно ОЗУ, а попытка загрузки зависит от подкачки виртуальной памяти - что вам никогда не захочется использовать при такой структуре данных с произвольным доступом.)

Если вы затем сохраните векторы в собственном формате gensim через .save(), и если составные массивы numpy достаточно велики, чтобы их можно было сохранить в виде отдельных файлов, то у вас будет возможность использовать gensim родной .load() с необязательным аргументом mmap='r'. Это полностью пропустит любой синтаксический анализ необработанных массивов на диске, просто отобразит их в памяти в адресуемом пространстве - и .load() завершится очень быстро. Затем при доступе к диапазонам массива они будут выгружаться в оперативную память. Вы по-прежнему платите за чтение всех данных с диска, но постепенно, по мере необходимости, а не в виде большого пакета данных.

Например ...

word_vecs.save('word-vectors.gensim')

... потом позже ...

word_vecs2 = KeyedVectors.load('word_vectors.gensim', mmap='r')

(для нативной опции 'limit' нет .load().)

...