在python中加载预训练的手套矢量

Sam*_*ame 30 nlp vector python-2.7

我从互联网上下载了预训练的手套矢量文件.它是一个.txt文件.我无法加载和访问它.使用gensim很容易加载和访问单词向量二进制文件,但是当它是文本文件格式时我不知道该怎么做.

提前致谢

Kar*_*kan 61

手套模型文件在一个词 - 矢量格式.您可以打开文本文件来验证这一点.这是一小段代码,可用于加载预训练的手套文件:

import numpy as np
def loadGloveModel(gloveFile):
    print("Loading Glove Model")
    f = open(gloveFile,'r')
    model = {}
    for line in f:
        splitLine = line.split()
        word = splitLine[0]
        embedding = np.array([float(val) for val in splitLine[1:]])
        model[word] = embedding
    print("Done.",len(model)," words loaded!")
    return model
Run Code Online (Sandbox Code Playgroud)

然后,您只需使用模型变量即可访问单词向量.

print model['hello']

  • 我想知道是否有更快的方法来做到这一点.我正在使用类似于上面的代码,但处理整个60亿个令牌嵌入需要大约27个小时.有关如何更快地完成此任务的任何想法? (4认同)
  • @jchook 添加 `f = open(gloveFile,'r', encoding='utf-8')` 来读取手套文件,它将起作用 (3认同)

Pet*_*ter 46

使用pandas可以更快地完成它:

import pandas as pd
import csv

words = pd.read_table(glove_data_file, sep=" ", index_col=0, header=None, quoting=csv.QUOTE_NONE)
Run Code Online (Sandbox Code Playgroud)

然后得到一个单词的向量:

def vec(w):
  return words.loc[w].as_matrix()
Run Code Online (Sandbox Code Playgroud)

并找到最接近向量的单词:

words_matrix = words.as_matrix()

def find_closest_word(v):
  diff = words_matrix - v
  delta = np.sum(diff * diff, axis=1)
  i = np.argmin(delta)
  return words.iloc[i].name
Run Code Online (Sandbox Code Playgroud)

  • 虽然,加载模型的时间减少了近一半,但访问时间增加了1000倍.loc对抗dict访问.我认为,我个人更喜欢较低的访问时间,因为这会影响培训时间.由于模型制作是单次努力,因此最好将时间投入到那里并一劳永逸地保存.如果我错了,请纠正我. (4认同)
  • 不推荐使用read_table。使用具有相同参数的`read_csv`。 (4认同)
  • 你应该在`read_table`中使用更多的参数:`na_values = None,keep_default_na = False`.否则,它会将许多有效字符串(例如'null','NA'等)视为"nan"浮点值. (2认同)

小智 28

我建议使用gensim来做所有事情.您可以阅读该文件,并且还可以在此优秀软件包上实施许多方法.

假设您使用C++程序生成了GloVe向量,并且您的"-save-file"参数是"向量".手套可执行文件将生成两个文件,"vectors.bin"和"vectors.txt".

使用glove2word2vec将文本格式的GloVe向量转换为word2vec文本格式:

from gensim.scripts.glove2word2vec import glove2word2vec
glove2word2vec(glove_input_file="vectors.txt", word2vec_output_file="gensim_glove_vectors.txt")
Run Code Online (Sandbox Code Playgroud)

最后,使用KeyedVectors将word2vec txt读入gensim模型:

from gensim.models.keyedvectors import KeyedVectors
glove_model = KeyedVectors.load_word2vec_format("gensim_glove_vectors.txt", binary=False)
Run Code Online (Sandbox Code Playgroud)

现在您可以根据需要使用gensim word2vec方法(例如,相似度).


Ind*_*dra 9

我更快地找到了这种方法。

import pandas as pd

df = pd.read_csv('glove.840B.300d.txt', sep=" ", quoting=3, header=None, index_col=0)
glove = {key: val.values for key, val in df.T.items()}
Run Code Online (Sandbox Code Playgroud)

保存字典:

import pickle
with open('glove.840B.300d.pkl', 'wb') as fp:
    pickle.dump(glove, fp)
Run Code Online (Sandbox Code Playgroud)


Abh*_*ara 5

如果您想要的只是嵌入矩阵,那么这是一个衬板

np.loadtxt(path, usecols=range(1, dim+1), comments=None)

在哪里path是您下载的GloVe文件的路径,并且dim是单词嵌入的尺寸。

如果您同时需要单词和相应的向量,则可以

glove = np.loadtxt(path, dtype='str', comments=None)

并将单词和向量分开如下

words = glove[:, 0]
vectors = glove[:, 1:].astype('float')
Run Code Online (Sandbox Code Playgroud)


u_b*_*u_b 5

从文本文件加载单词嵌入(在我的例子中是glove.42B.300d嵌入)需要一点时间(在我的机器上为147.2 秒)。

有帮助的是首先将文本文件转换为两个新文件:一个仅包含单词的文本文件(例如embeddings.vocab)和一个包含作为 numpy 结构的嵌入向量的二进制文件(例如embeddings.npy)。

转换后,我只需4.96 秒即可将相同的嵌入加载到内存中。这种方法最终会得到与从文本文件加载它完全相同的字典。它的访问时间同样高效,不需要任何额外的框架,但加载时间要快得多。

使用此代码,您可以将嵌入文本文件转换为两个新文件:

def convert_to_binary(embedding_path):
    f = codecs.open(embedding_path + ".txt", 'r', encoding='utf-8')
    wv = []

    with codecs.open(embedding_path + ".vocab", "w", encoding='utf-8') as vocab_write:
        count = 0
        for line in f:
            splitlines = line.split()
            vocab_write.write(splitlines[0].strip())
            vocab_write.write("\n")
            wv.append([float(val) for val in splitlines[1:]])
        count += 1

    np.save(embedding_path + ".npy", np.array(wv))
Run Code Online (Sandbox Code Playgroud)

通过这种方法,您可以将其有效地加载到内存中:

def load_word_emb_binary(embedding_file_name_w_o_suffix):
    print("Loading binary word embedding from {0}.vocab and {0}.npy".format(embedding_file_name_w_o_suffix))

    with codecs.open(embedding_file_name_w_o_suffix + '.vocab', 'r', 'utf-8') as f_in:
        index2word = [line.strip() for line in f_in]

    wv = np.load(embedding_file_name_w_o_suffix + '.npy')
    word_embedding_map = {}
    for i, w in enumerate(index2word):
        word_embedding_map[w] = wv[i]

    return word_embedding_map
Run Code Online (Sandbox Code Playgroud)

免责声明:此代码无耻地从https://blog.ekbana.com/loading-glove-pre-trained-word-embedding-model-from-text-file-faster-5d3e8f2b8455窃取。但它可能对这个线程有帮助。