gensim 是如何快速找到最相似的单词的?
How does gensim manage to find the most similar words so fast?
假设我们训练了一个包含超过 100 万个单词的模型。为了找到最相似的单词,我们需要计算测试单词的嵌入与所有 100 万个单词的嵌入之间的距离,然后找到最近的单词。看来Gensim计算结果的速度非常快。虽然当我想计算最相似时,我的函数非常慢:
def euclidean_most_similars (model, word, topn = 10):
distances = {}
vec1 = model[word]
for item in model.wv.vocab:
if item!= node:
vec2 = model[item]
dist = np.linalg.norm(vec1 - vec2)
distances[(node, item)] = dist
sorted_distances = sorted(distances.items(), key=operator.itemgetter(1))
我想知道 Gensim 如何如此快速地计算出最接近的词,以及计算最相似词的有效方法是什么。
正如@g-anderson 评论的那样,可以查看 gensim
来源以了解它的确切作用。然而,gensim
实际上并没有使用任何它自己优化的 Cython 或编译的 C 代码作为其 most_similar()
方法的一部分——可以在以下位置查看:
相反,通过使用 numpy
/scipy
批量数组操作,这些库的高度优化代码将利用 CPU 原语和多线程来计算 所有 相关相似性比解释 Python 循环快得多。
(关键的主力是 numpy
dot
操作:一个调用创建一个包含所有相似点的有序数组——完全跳过循环和你的中间结果 dict
。但是 argsort
,也传递给 numpy
实现,也可能优于惯用的 sorted()
。)
假设我们训练了一个包含超过 100 万个单词的模型。为了找到最相似的单词,我们需要计算测试单词的嵌入与所有 100 万个单词的嵌入之间的距离,然后找到最近的单词。看来Gensim计算结果的速度非常快。虽然当我想计算最相似时,我的函数非常慢:
def euclidean_most_similars (model, word, topn = 10):
distances = {}
vec1 = model[word]
for item in model.wv.vocab:
if item!= node:
vec2 = model[item]
dist = np.linalg.norm(vec1 - vec2)
distances[(node, item)] = dist
sorted_distances = sorted(distances.items(), key=operator.itemgetter(1))
我想知道 Gensim 如何如此快速地计算出最接近的词,以及计算最相似词的有效方法是什么。
正如@g-anderson 评论的那样,可以查看 gensim
来源以了解它的确切作用。然而,gensim
实际上并没有使用任何它自己优化的 Cython 或编译的 C 代码作为其 most_similar()
方法的一部分——可以在以下位置查看:
相反,通过使用 numpy
/scipy
批量数组操作,这些库的高度优化代码将利用 CPU 原语和多线程来计算 所有 相关相似性比解释 Python 循环快得多。
(关键的主力是 numpy
dot
操作:一个调用创建一个包含所有相似点的有序数组——完全跳过循环和你的中间结果 dict
。但是 argsort
,也传递给 numpy
实现,也可能优于惯用的 sorted()
。)