Gensim word2vec WMD 相似度字典
Gensim word2vec WMD similarity dictionary
我在 100 万个摘要数据集(20 亿个单词)上使用 word2vec。为了找到最相似的文档,我使用 gensim.similarities.WmdSimilarity
class。当尝试使用 wmd_similarity_index[query]
检索最佳匹配时,计算将大部分时间用于构建字典。这是一段日志:
2017-08-25 09:45:39,441 : INFO : built Dictionary(127 unique tokens: ['empirical', 'model', 'estimating', 'vertical', 'concentration']...) from 2 documents (total 175 corpus positions)
2017-08-25 09:45:39,445 : INFO : adding document #0 to Dictionary(0 unique tokens: [])
这部分是什么?它取决于查询吗?有没有办法一次性完成这些计算?
编辑: 我的代码中的训练和评分阶段:
训练并保存到磁盘:
w2v_size = 300
word2vec = gensim.models.Word2Vec(texts, size=w2v_size, window=9, min_count=5, workers=1, sg=1, hs=1, iter=20) # sg=1 means skip gram is used
word2vec.save(utils.paths.PATH_DATA_GENSIM_WORD2VEC)
corpus_w2v_wmd_index = gensim.similarities.WmdSimilarity(texts, word2vec.wv)
corpus_w2v_wmd_index.save(utils.paths.PATH_DATA_GENSIM_CORPUS_WORD2VEC_WMD_INDEX)
加载和评分:
w2v = gensim.models.Word2Vec.load(utils.paths.PATH_DATA_GENSIM_WORD2VEC)
words = [t for t in proc_text if t in w2v.wv]
corpus_w2v_wmd_index = gensim.similarities.docsim.Similarity.load(utils.paths.PATH_DATA_GENSIM_CORPUS_WORD2VEC_WMD_INDEX)
scores_w2v = np.array(corpus_w2v_wmd_index[words])
"Word Mover's Distance" 计算相对昂贵——对于每个成对的文档比较,它会搜索一个最佳的 'shifting' 语义位置,并且这种移动本身取决于所有文档之间的成对简单距离每个比较文档的单词。
也就是说,它所涉及的计算量远远超过两个高维向量之间的简单余弦距离,并且两个文档越长,所涉及的计算量就越大。
在知道查询的词之前,texts
语料库中没有多少可以预先计算的。 (每个成对计算都取决于查询的单词,以及它们与每个语料库文档单词的简单距离。)
也就是说,gensim WmdSimilarity
class 还没有做一些优化。
最初的 WMD 论文描述了一种更快的计算,可以帮助消除那些不可能出现在与 WMD 最相似的前 N 个结果中的语料库文本。从理论上讲,gensim WmdSimilarity
也可以实现此优化,并提供更快的结果,至少在使用 num_best
参数初始化 WmdSimilarity
时是这样。 (没有它,每个查询 returns 都是 WMD 相似度分数,所以这个优化不会有帮助。)
此外,目前 WmdSimilarity
class 只是为每个查询到语料库文档对调用 KeyedVectors.wmdistance(doc1, doc2)
,作为原始文本。因此,每次都会重新计算从所有 doc1
个词到 doc2
个词的成对简单距离,即使许多对在整个语料库中重复。 (也就是说,如果 'apple' 在查询中并且 'orange' 在每个语料库文档中,它仍然会重复计算 'apple' 到 'orange' 的距离。)
因此,对临时值进行一些缓存可能有助于提高性能。例如,对于 1000 个单词的查询和所有语料库文档中 100,000 个单词的词汇,((1000 * 100,000) / 2)
5000 万个成对单词距离可以使用 200MB 预先计算一次,然后由所有后续 WMD 计算共享。要添加此优化,需要 WmdSimilarity.get_similarities()
和 KeyedVectors.wmdistance()
.
的合作重构
最后,Word2Vec/Doc2Vec 应用程序不一定需要停止词删除或词干提取或从中受益。但由于 WMD 计算的开销随着文档和词汇量的增加而增加,任何缩小有效文档大小的方法都有助于提高性能。因此,在大型文档集上使用 WMD 时,丢弃低价值词或合并相似词的各种方法可能值得考虑。
我在 100 万个摘要数据集(20 亿个单词)上使用 word2vec。为了找到最相似的文档,我使用 gensim.similarities.WmdSimilarity
class。当尝试使用 wmd_similarity_index[query]
检索最佳匹配时,计算将大部分时间用于构建字典。这是一段日志:
2017-08-25 09:45:39,441 : INFO : built Dictionary(127 unique tokens: ['empirical', 'model', 'estimating', 'vertical', 'concentration']...) from 2 documents (total 175 corpus positions)
2017-08-25 09:45:39,445 : INFO : adding document #0 to Dictionary(0 unique tokens: [])
这部分是什么?它取决于查询吗?有没有办法一次性完成这些计算?
编辑: 我的代码中的训练和评分阶段:
训练并保存到磁盘:
w2v_size = 300
word2vec = gensim.models.Word2Vec(texts, size=w2v_size, window=9, min_count=5, workers=1, sg=1, hs=1, iter=20) # sg=1 means skip gram is used
word2vec.save(utils.paths.PATH_DATA_GENSIM_WORD2VEC)
corpus_w2v_wmd_index = gensim.similarities.WmdSimilarity(texts, word2vec.wv)
corpus_w2v_wmd_index.save(utils.paths.PATH_DATA_GENSIM_CORPUS_WORD2VEC_WMD_INDEX)
加载和评分:
w2v = gensim.models.Word2Vec.load(utils.paths.PATH_DATA_GENSIM_WORD2VEC)
words = [t for t in proc_text if t in w2v.wv]
corpus_w2v_wmd_index = gensim.similarities.docsim.Similarity.load(utils.paths.PATH_DATA_GENSIM_CORPUS_WORD2VEC_WMD_INDEX)
scores_w2v = np.array(corpus_w2v_wmd_index[words])
"Word Mover's Distance" 计算相对昂贵——对于每个成对的文档比较,它会搜索一个最佳的 'shifting' 语义位置,并且这种移动本身取决于所有文档之间的成对简单距离每个比较文档的单词。
也就是说,它所涉及的计算量远远超过两个高维向量之间的简单余弦距离,并且两个文档越长,所涉及的计算量就越大。
在知道查询的词之前,texts
语料库中没有多少可以预先计算的。 (每个成对计算都取决于查询的单词,以及它们与每个语料库文档单词的简单距离。)
也就是说,gensim WmdSimilarity
class 还没有做一些优化。
最初的 WMD 论文描述了一种更快的计算,可以帮助消除那些不可能出现在与 WMD 最相似的前 N 个结果中的语料库文本。从理论上讲,gensim WmdSimilarity
也可以实现此优化,并提供更快的结果,至少在使用 num_best
参数初始化 WmdSimilarity
时是这样。 (没有它,每个查询 returns 都是 WMD 相似度分数,所以这个优化不会有帮助。)
此外,目前 WmdSimilarity
class 只是为每个查询到语料库文档对调用 KeyedVectors.wmdistance(doc1, doc2)
,作为原始文本。因此,每次都会重新计算从所有 doc1
个词到 doc2
个词的成对简单距离,即使许多对在整个语料库中重复。 (也就是说,如果 'apple' 在查询中并且 'orange' 在每个语料库文档中,它仍然会重复计算 'apple' 到 'orange' 的距离。)
因此,对临时值进行一些缓存可能有助于提高性能。例如,对于 1000 个单词的查询和所有语料库文档中 100,000 个单词的词汇,((1000 * 100,000) / 2)
5000 万个成对单词距离可以使用 200MB 预先计算一次,然后由所有后续 WMD 计算共享。要添加此优化,需要 WmdSimilarity.get_similarities()
和 KeyedVectors.wmdistance()
.
最后,Word2Vec/Doc2Vec 应用程序不一定需要停止词删除或词干提取或从中受益。但由于 WMD 计算的开销随着文档和词汇量的增加而增加,任何缩小有效文档大小的方法都有助于提高性能。因此,在大型文档集上使用 WMD 时,丢弃低价值词或合并相似词的各种方法可能值得考虑。