【问题标题】:Gensim most similar word to vectorGensim 与向量最相似的词
【发布时间】:2020-11-23 18:48:18
【问题描述】:

我在 Gensim 中使用来自维基百科的预训练词向量 "glove-wiki-gigaword-100"。正如this example documentation 所示,您可以使用

查询给定单词或一组单词最相似的单词
model_gigaword.wv.most_similar(positive=['dirty','grimy'],topn=10)

但是,我想查询与给定向量最相似的词,指定为数组(与预训练模型中的词向量格式相同)。例如,在预训练模型中添加或减去两个词向量的结果,如

vec = model_gigaword['king']-model_gigaword['man']

输出:(对于vec

array([-0.696     , -1.26119   , -0.49109   ,  0.91179   ,  0.23077281,
       -0.18835002, -0.65568995, -0.29686698, -0.60074997, -1.35762   ,
       -0.11816999,  0.01779997, -0.74096   ,  0.21192   , -0.407071  ,
       -1.04871   , -0.480674  , -0.95541   , -0.06046999,  0.20678002,
       -1.1516    , -0.98955095,  0.44508   ,  0.32682198, -0.03306001,
       -0.31138003,  0.87721   ,  0.34279   ,  0.78621   , -0.297459  ,
        0.529243  , -0.07398   ,  0.551844  ,  0.54218   , -0.39394   ,
        0.96368   ,  0.22518003,  0.05197001, -0.912573  , -0.718755  ,
        0.08056   ,  0.421177  , -0.34256   , -0.71294   , -0.25391   ,
       -0.65362   , -0.31369498,  0.216278  ,  0.41873002, -0.21784998,
        0.21340999,  0.480393  ,  0.47077006, -1.00272   ,  0.16624999,
       -0.07340002,  0.09219003, -0.02021003, -0.58403   , -0.47306   ,
        0.05066001, -0.64416003,  0.80061007,  0.224344  , -0.20483994,
       -0.33785298, -1.24589   ,  0.08900005, -0.08385998, -0.195515  ,
        0.08500999, -0.55749   ,  0.19473001, -0.0751    , -0.61184   ,
       -0.08018   , -0.34303   ,  1.03759   , -0.36085004,  0.93508005,
       -0.00997001, -0.57282   ,  0.33101702,  0.271261  ,  0.47389007,
        1.1219599 , -0.00199997, -1.609     ,  0.57377803, -0.17023998,
       -0.22913098, -0.33818996, -0.367797  ,  0.367965  , -1.08955   ,
       -0.664806  ,  0.05213001,  0.40829998,  0.125692  , -0.44967002],
      dtype=float32)

如何获得与vec 最相似的词?

【问题讨论】:

  • 我已将答案更新为更简单的解决方案。

标签: python nlp gensim word2vec


【解决方案1】:

你可以直接和model_gigaword.wv.most_similar一起使用

your_word_vector = np.array([-0.696, -1.26119, -0.49109, 0.91179, 0.23077281,
       -0.18835002, -0.65568995, -0.29686698, -0.60074997, -1.35762   ,
       -0.11816999,  0.01779997, -0.74096   ,  0.21192   , -0.407071  ,
       -1.04871   , -0.480674  , -0.95541   , -0.06046999,  0.20678002,
       -1.1516    , -0.98955095,  0.44508   ,  0.32682198, -0.03306001,
       -0.31138003,  0.87721   ,  0.34279   ,  0.78621   , -0.297459  ,
        0.529243  , -0.07398   ,  0.551844  ,  0.54218   , -0.39394   ,
        0.96368   ,  0.22518003,  0.05197001, -0.912573  , -0.718755  ,
        0.08056   ,  0.421177  , -0.34256   , -0.71294   , -0.25391   ,
       -0.65362   , -0.31369498,  0.216278  ,  0.41873002, -0.21784998,
        0.21340999,  0.480393  ,  0.47077006, -1.00272   ,  0.16624999,
       -0.07340002,  0.09219003, -0.02021003, -0.58403   , -0.47306   ,
        0.05066001, -0.64416003,  0.80061007,  0.224344  , -0.20483994,
       -0.33785298, -1.24589   ,  0.08900005, -0.08385998, -0.195515  ,
        0.08500999, -0.55749   ,  0.19473001, -0.0751    , -0.61184   ,
       -0.08018   , -0.34303   ,  1.03759   , -0.36085004,  0.93508005,
       -0.00997001, -0.57282   ,  0.33101702,  0.271261  ,  0.47389007,
        1.1219599 , -0.00199997, -1.609     ,  0.57377803, -0.17023998,
       -0.22913098, -0.33818996, -0.367797  ,  0.367965  , -1.08955   ,
       -0.664806  ,  0.05213001,  0.40829998,  0.125692  , -0.44967002])

model_gigaword.wv.most_similar(positive=[your_word_vector], topn=10)
[('vajiravudh', 0.7130449414253235),
 ('prajadhipok', 0.6764554381370544),
 ('andrianampoinimerina', 0.6474215984344482),
 ('jeongjo', 0.6449092626571655),
 ('taejong', 0.6352322697639465),
 ('rehoboam', 0.6319528818130493),
 ('injo', 0.6317901611328125),
 ('gojong', 0.6302404999732971),
 ('seonjo', 0.6272163391113281),
 ('elessar', 0.6250109672546387)]

正如预期的那样,这些结果几乎是垃圾。阅读下面的原因。


但有一点很重要。我看到您正在尝试在词向量的欧几里德空间中找到与差异向量相似的词。 kingman 之间的差异导致向量与 queenwoman 之间的差异相似,这意味着差异向量的长度和方向编码了 2 个相应单词对之间的上下文差异。

该向量的字面位置可能是垃圾,因为通过在欧几里得空间中检查它,您会将其锚定在原点上。上面的两个差分向量(King->Man 和 Queen->Woman)分别锚定在 'King' 和 'Queen' 上。

你应该有的直觉是 A->B 和 C->D 可能有相似的向量连接它们,即使 A、B 和 C、D 可能排列在欧几里得空间的完全独立的部分中,如果它们有相似的它们之间的语境差异。这就是经过适当训练的 word2vec 中的向量空间正在编码的内容。

【讨论】:

  • 谢谢,你能用代码澄清一下吗?如果您有 import gensim.downloader as api 然后 model_gigaword = api.load("glove-wiki-gigaword-100") 的 gensim,您可以轻松加载模型。我的疑问是(1)如何以最佳方式从模型到(words, dims)矩阵(实际上,有 400,000 多个词和 100 个维度),(2)如何像 Gensim 一样快速执行点积确实(我认为使用 numpy/scipy)
  • 检查我更新的答案,原来有一个更简单的方法。如果这对你有用,请告诉我。
  • 啊,谢谢,这真的很清楚。我的实际用例是查询类似vector['queen'] + vector['king']-vector['man']的东西,它应该产生一个接近vector['woman']的向量。然后通过相似性搜索,我会提取“女人”作为热门歌曲(或其中之一)。你认为余弦相似度(我相信 most_similar 正在使用)最适合这个吗?正如你所暗示的,我有一种感觉,欧几里得距离可能更相关
  • 我相信余弦相似度会给你更好的结果,因为 word2vec 就像你看到的那样,在方向上编码上下文。方向相似且长度相似的向量往往在上下文/语义上相似。同时,word2vec 空间中的欧几里得距离仍然有意义,但我认为余弦相似度是比较向量的更好衡量标准。
  • 另外,如果您认为它可以解决您的问题,请标记该问题。这将有助于 SO 上的其他人寻找类似的查询。
猜你喜欢
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 2018-08-14
  • 2019-07-02
  • 2020-08-14
  • 2019-08-24
  • 2020-08-17
  • 1970-01-01
相关资源
最近更新 更多