我有一个大约 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()如果您对具有相同句子嵌入目的并可以解决我的问题的不同算法或技术有任何建议,我很乐意阅读它。
2 回答
PIPIONE
TA贡献1829条经验 获得超9个赞
您可以使用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
ITMISS
TA贡献1871条经验 获得超8个赞
Doc2Vec
与普通的平均词向量相比,通常文本向量的有用性非常相似(或者在调整后更好一些)。(毕竟,算法非常相似,处理相同数据的相同形式,并且创建的模型大小大致相同。)如果出现大幅下降,则您的Doc2Vec
过程可能存在错误。
正如@AnnaKrogager 指出的那样,FastText 可以通过使用单词片段合成猜测向量来处理词汇外的单词。(这需要单词具有这种共享词根的语言。)向量可能不是很好,但通常比完全忽略未知单词或使用全零向量或随机插入向量要好。
在进程之间拆分它是否有助于运行时?因为向子进程和从子进程发送批处理工作有很多开销,而 Python 中的子进程会导致内存需求激增——而且这种开销甚至虚拟内存交换都可能超过并行性的任何其他好处.
添加回答
举报
0/150
提交
取消