log*_*sbb 4 python optimization numpy gensim word2vec
我有一个大约 1000 万个句子的列表,每个句子最多包含 70 个单词。
我在每个单词上运行 gensim word2vec,然后取每个句子的简单平均值。问题是我使用了 min_count=1000,所以很多词都没有出现在词汇表中。
为了解决这个问题,我将 vocab 数组(包含大约 10000 个单词)与每个句子相交,如果该交集中至少剩下一个元素,则返回其简单平均值,否则返回一个零向量。
问题是,当我在整个数据集上运行它时,计算每个平均值需要很长时间,即使拆分成多个线程,我想得到一个可以运行得更快的更好的解决方案。
我在 EC2 r4.4xlarge 实例上运行它。
我已经尝试切换到 doc2vec,它更快,但结果不如 word2vec 的简单平均值。
word2vec_aug_32x = Word2Vec(sentences=sentences,
min_count=1000,
size=32,
window=2,
workers=16,
sg=0)
vocab_arr = np.array(list(word2vec_aug_32x.wv.vocab.keys()))
def get_embedded_average(sentence):
sentence = np.intersect1d(sentence, vocab_arr)
if sentence.shape[0] > 0:
return np.mean(word2vec_aug_32x[sentence], axis=0).tolist()
else:
return np.zeros(32).tolist()
pool = multiprocessing.Pool(processes=16)
w2v_averages = np.asarray(pool.map(get_embedded_average, np.asarray(sentences)))
pool.close()
Run Code Online (Sandbox Code Playgroud)
如果您对具有相同句子嵌入目的并可以解决我的问题的不同算法或技术有任何建议,我很乐意阅读它。
您可以使用FastText而不是 Word2Vec。FastText 能够通过查看子词信息(字符 ngrams)来嵌入词汇外的词。Gensim还有一个FastText实现,非常好用:
from gensim.models import FastText
model = FastText(sentences=training_data, size=128, ...)
word = 'hello' # can be out of vocabulary
embedding = model[word] # fetches the word embedding
Run Code Online (Sandbox Code Playgroud)