如何以最佳方式处理word2vec的vocab中没有的单词

2024-04-27 21:03:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大约1000万个句子的列表,每个句子最多包含70个单词。在

我对每个单词运行gensim word2vec,然后计算每个句子的简单平均值。问题是我使用min_count=1000,所以很多单词不在vocab中。在

为了解决这个问题,我将vocab数组(包含大约10000个单词)与每个句子相交,如果这个交集中至少还有一个元素,它将返回它的简单平均值,否则,它将返回一个零向量。在

问题是,当我在整个数据集上运行平均值时,计算每个平均值都要花费很长的时间,即使是拆分为多个线程,我希望得到一个运行速度更快的更好的解决方案。在

我在ec2r4.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()

如果你有什么不同的算法或技术的建议,有相同的目的,句子嵌入,并能解决我的问题,我很乐意阅读。在


Tags: getcountnpsentencesword2vecmin单词sentence
2条回答

你可以用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

通常Doc2Vec文本向量的有用性与单词向量的平均值非常相似(或者在调整时,会更好一些)。(毕竟,算法非常相似,处理相同数据的相同形式,并且创建的模型大小大致相同。)如果出现较大的下降,则可能是您的Doc2Vec过程中出现了错误。在

正如@AnnaKrogager指出的,FastText可以通过使用单词片段合成猜测向量来处理词汇表外的单词。(这要求语言中的单词有这样的共享根。)向量可能不是很好,但通常比完全忽略未知单词,或者使用所有零向量或随机插入向量要好。在

在进程之间进行拆分是否有助于运行时?因为在向子进程和从子进程发送批处理的过程中会有大量开销,而Python中的子进程可能会导致内存需求的膨胀,而且这种开销甚至可能是虚拟内存交换都会超过并行性的任何其他好处。在

相关问题 更多 >