在总词汇的子集上使用 gensim most_similar 函数
Using gensim most_similar function on a subset of total vocab
我正在尝试通过以下方式使用 gensim word2vec most_similar
函数:
wv_from_bin.most_similar(positive=["word_a", "word_b"])
所以基本上,我有多个查询词,我想 return 最相似的输出,但来自有限集。即如果 vocab 是 2000 个单词,那么我想 return 最相似的一组说 100 个单词,而不是全部 2000 个。
例如
Vocab:
word_a, word_b, word_c, word_d, word_e ... words_z
Finite set:
word_d, word_e, word_f
most_similar 整个词汇
wv_from_bin.most_similar(positive=["word_a", "word_b"])
output = ['word_d', 'word_f', 'word_g', 'word_x'...]
期望输出
finite_set = ['word_d', 'word_e', 'word_f']
wv_from_bin.most_similar(positive=["word_a", "word_b"], finite_set) <-- some way of passing the finite set
output = ['word_d', 'word_f']
根据您的具体使用模式,您有几种选择。
如果您想将结果限制在 KeyedVectors
实例中 连续范围 的单词中,一些可选参数可以提供帮助。
大多数情况下,人们希望将结果限制在最频繁 的词中。这些通常是带有 best-trained word-vectors 的那些。 (当你深入研究 less-frequent 个单词时,少数训练示例往往会使它们的向量更加特殊 - 无论是作为算法一部分的随机化,还是从任何方面来说,有限数量的示例都不能反映单词的在更广阔的世界中具有“真正的”普遍意义。)
使用整数值 N 的可选参数 restrict_vocab
会将结果限制为 KeyedVectors
中的前 N 个词(按照惯例,most-frequent 在训练数据中)。因此,例如,将 restrict_vocab=10000
添加到对具有 50000 个单词的 set-of-vectors 的调用中,只会重新调整前 10000 个已知单词中的 most-similar 个单词。由于上述影响,这些通常是最可靠和明智的结果 - 而来自 low-frequency 个词中 longer-tail 的附近词更有可能看起来有点不合适。
同样,您可以使用可选的 clip_start
和 clip_end
参数来将结果限制在任何其他连续范围内,而不是 restrict_vocab
。例如,将 clip_start=100, clip_end=1000
添加到 most_similar()
调用中只会从该范围内的 900 个单词中得到 return 结果(在通常情况下会忽略 100 个 most-common 单词)。如果您发现 most-frequent 词过于笼统,我想这可能会有用——尽管我没有注意到这是一个典型的问题。
基于底层 bulk-vector 库的工作方式,上述两个选项在整理 top-N 之前有效地计算 仅 所需的相似性,使用本机例程,无需任何额外努力即可实现良好的并行性。
如果您的单词在整个 KeyedVectors
中是不连续的组合,则 built-in 不支持限制结果。
您可以考虑的两个选项包括:
特别是如果您重复搜索完全相同的词子集,您可以尝试只用这些词创建一个新的 KeyedVectors
对象 - 然后每个 most_similar()
都针对那个单独的词set 正是您所需要的。请参阅 KeyedVectors
docs 中的构造函数 & add_vector()
或 add_vectors()
方法了解如何完成。
请求更大的结果集,然后过滤您想要的子集。例如,如果您提供 topn=len(wv_from_bin)
,您将返回 每个 个单词,排名。然后,您可以将它们过滤到您想要的子集。这会做额外的工作,但这可能不是问题,具体取决于您的模型大小和所需的吞吐量。例如:
finite_set = set(['word_d', 'word_e', 'word_f']) # set for efficient 'in'
all_candidates = wv_from_bin.most_similar(positive=["word_a", "word_b"],
topn=len(vw_from_bin))
filtered_results = [word_sim for word_sim in all_candidates if word_sim[0] in finite_set]
- 通过使用 所有 相似性,未排序,使用
topn=None
选项 - 但你仍然必须将这些子集化为你的 words-of-interest,然后自己排序。但是您仍然需要为所有单词支付所有 vector-similarity 计算的费用,这在典型的 large-vocabularies 中比排序更多。
如果您想要迭代您的子集并逐一计算相似性,请注意不能利用数学库的批量向量运算——它使用向量 CPU 运算大范围的基础数据——所以通常会慢很多。
最后,顺便说一句:如果你的词汇量确实只有 ~2000 个单词,那么你与 word2vec(和一般的密集嵌入 word-vectors)通常大放异彩的 data/words 相去甚远。除非获得更多数据,否则您可能会对结果感到失望。 (与此同时,如此小的词汇可能在有效训练 100、300 或更多的典型 word2vec 维度 (vector_size
) 时遇到问题。(使用较小的 vector_size
,当你的词汇较小且训练较少时数据,可以有点帮助。)
另一方面,如果您在 real-language 以外的其他领域,文本本身就具有有限的独特词汇——比如说 category-tags 或 product-names 或类似的——并且你有机会训练您自己的 word-vectors,您可能想尝试比通常的默认值范围更广的训练参数。某些 recommendation-type 应用程序可能受益于与 ns_exponent
默认值非常不同的值,并且如果源数据的 token-order 是任意的,而不是有意义的,则使用巨大的 window
或设置 shrink_windows=False
将弱化 immediate-neighbors.
我正在尝试通过以下方式使用 gensim word2vec most_similar
函数:
wv_from_bin.most_similar(positive=["word_a", "word_b"])
所以基本上,我有多个查询词,我想 return 最相似的输出,但来自有限集。即如果 vocab 是 2000 个单词,那么我想 return 最相似的一组说 100 个单词,而不是全部 2000 个。
例如
Vocab:
word_a, word_b, word_c, word_d, word_e ... words_z
Finite set:
word_d, word_e, word_f
most_similar 整个词汇
wv_from_bin.most_similar(positive=["word_a", "word_b"])
output = ['word_d', 'word_f', 'word_g', 'word_x'...]
期望输出
finite_set = ['word_d', 'word_e', 'word_f']
wv_from_bin.most_similar(positive=["word_a", "word_b"], finite_set) <-- some way of passing the finite set
output = ['word_d', 'word_f']
根据您的具体使用模式,您有几种选择。
如果您想将结果限制在 KeyedVectors
实例中 连续范围 的单词中,一些可选参数可以提供帮助。
大多数情况下,人们希望将结果限制在最频繁 的词中。这些通常是带有 best-trained word-vectors 的那些。 (当你深入研究 less-frequent 个单词时,少数训练示例往往会使它们的向量更加特殊 - 无论是作为算法一部分的随机化,还是从任何方面来说,有限数量的示例都不能反映单词的在更广阔的世界中具有“真正的”普遍意义。)
使用整数值 N 的可选参数 restrict_vocab
会将结果限制为 KeyedVectors
中的前 N 个词(按照惯例,most-frequent 在训练数据中)。因此,例如,将 restrict_vocab=10000
添加到对具有 50000 个单词的 set-of-vectors 的调用中,只会重新调整前 10000 个已知单词中的 most-similar 个单词。由于上述影响,这些通常是最可靠和明智的结果 - 而来自 low-frequency 个词中 longer-tail 的附近词更有可能看起来有点不合适。
同样,您可以使用可选的 clip_start
和 clip_end
参数来将结果限制在任何其他连续范围内,而不是 restrict_vocab
。例如,将 clip_start=100, clip_end=1000
添加到 most_similar()
调用中只会从该范围内的 900 个单词中得到 return 结果(在通常情况下会忽略 100 个 most-common 单词)。如果您发现 most-frequent 词过于笼统,我想这可能会有用——尽管我没有注意到这是一个典型的问题。
基于底层 bulk-vector 库的工作方式,上述两个选项在整理 top-N 之前有效地计算 仅 所需的相似性,使用本机例程,无需任何额外努力即可实现良好的并行性。
如果您的单词在整个 KeyedVectors
中是不连续的组合,则 built-in 不支持限制结果。
您可以考虑的两个选项包括:
特别是如果您重复搜索完全相同的词子集,您可以尝试只用这些词创建一个新的
KeyedVectors
对象 - 然后每个most_similar()
都针对那个单独的词set 正是您所需要的。请参阅KeyedVectors
docs 中的构造函数 &add_vector()
或add_vectors()
方法了解如何完成。请求更大的结果集,然后过滤您想要的子集。例如,如果您提供
topn=len(wv_from_bin)
,您将返回 每个 个单词,排名。然后,您可以将它们过滤到您想要的子集。这会做额外的工作,但这可能不是问题,具体取决于您的模型大小和所需的吞吐量。例如:
finite_set = set(['word_d', 'word_e', 'word_f']) # set for efficient 'in'
all_candidates = wv_from_bin.most_similar(positive=["word_a", "word_b"],
topn=len(vw_from_bin))
filtered_results = [word_sim for word_sim in all_candidates if word_sim[0] in finite_set]
- 通过使用 所有 相似性,未排序,使用
topn=None
选项 - 但你仍然必须将这些子集化为你的 words-of-interest,然后自己排序。但是您仍然需要为所有单词支付所有 vector-similarity 计算的费用,这在典型的 large-vocabularies 中比排序更多。
如果您想要迭代您的子集并逐一计算相似性,请注意不能利用数学库的批量向量运算——它使用向量 CPU 运算大范围的基础数据——所以通常会慢很多。
最后,顺便说一句:如果你的词汇量确实只有 ~2000 个单词,那么你与 word2vec(和一般的密集嵌入 word-vectors)通常大放异彩的 data/words 相去甚远。除非获得更多数据,否则您可能会对结果感到失望。 (与此同时,如此小的词汇可能在有效训练 100、300 或更多的典型 word2vec 维度 (vector_size
) 时遇到问题。(使用较小的 vector_size
,当你的词汇较小且训练较少时数据,可以有点帮助。)
另一方面,如果您在 real-language 以外的其他领域,文本本身就具有有限的独特词汇——比如说 category-tags 或 product-names 或类似的——并且你有机会训练您自己的 word-vectors,您可能想尝试比通常的默认值范围更广的训练参数。某些 recommendation-type 应用程序可能受益于与 ns_exponent
默认值非常不同的值,并且如果源数据的 token-order 是任意的,而不是有意义的,则使用巨大的 window
或设置 shrink_windows=False
将弱化 immediate-neighbors.