【问题标题】:Cosine similarity between any two sentences is giving 0.99 always任何两个句子之间的余弦相似度总是给出 0.99
【发布时间】:2017-03-28 18:27:12
【问题描述】:

我下载了 stackoverflow 转储(这是一个 10GB 文件)并在转储上运行 word2vec 以获得编程术语的矢量表示(我正在做的项目需要它)。以下是代码:

from gensim.models import Word2Vec
from xml.dom.minidom import parse, parseString

titles, bodies = [], []
xmldoc = parse('test.xml') //this is the dump 
reflist = xmldoc.getElementsByTagName('row')
for i in range(len(reflist)):
    bitref = reflist[i]
    if 'Title' in bitref.attributes.keys():
        title = bitref.attributes['Title'].value
        titles.append([i for i in title.split()])
    if 'Body' in bitref.attributes.keys():
        body = bitref.attributes['Body'].value
        bodies.append([i for i in body.split()])

dimension = 8
sentences = titles + bodies
model = Word2Vec(sentences, size=dimension, iter=100)
model.save('snippet_1.model')

现在,为了计算一对句子之间的余弦相似度,我执行以下操作:

from gensim.models import Word2Vec
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

model = Word2Vec.load('snippet_1.model')
dimension = 8
snippet = 'some text'
snippet_vector = np.zeros((1, dimension))
for word in snippet:
    if word in model.wv.vocab:
        vecvalue = model[word].reshape(1, dimension)
        snippet_vector = np.add(snippet_vector, vecvalue)

link_text = 'some other text'
link_vector = np.zeros((1, dimension))
for word in link_text:
    if word in model.wv.vocab:
        vecvalue = model[word].reshape(1, dimension)
        link_vector = np.add(link_vector, vecvalue)

print(cosine_similarity(snippet_vector, link_vector))

我正在计算句子中每个单词的词嵌入总和,以获得整个句子的一些表示。我对两个句子都这样做,然后计算它们之间的余弦相似度。

现在,问题是我给出的任何一对句子的余弦相似度都在 0.99 左右。有什么我做错了吗?有什么更好的方法建议吗?

【问题讨论】:

  • 使用这个问题中讨论的 Word2Vec 模型对象的 n_similarity 可能会更好:stackoverflow.com/questions/26010645/…
  • 可能为时已晚,但是当使用相似度进行比较时,几乎所有单词的 word2vec 都得到了相同的结果。然后我注意到用于训练 word2vec 的语料库的大小对于学习下划线向量权重的模型来说太小了。当我增加语料库的大小时,模型开始获得更好的结果。我猜想 word2vec 需要最少数量的文档才能开始表现良好。

标签: word2vec cosine-similarity


【解决方案1】:

在计算它们的余弦相似度之前,您是否检查过您的 snippet_vectorlink_vector 是有意义的向量?

我怀疑它们只是零向量,或者类似地不多样化,因为您的 for word in snippet:for word in link_text: 循环没有标记文本。因此,它们只会遍历每个字符串中的 characters,这些字符串要么不会作为单词出现在您的模型中,要么可能会在您的文本之间完全匹配。 (即使使用标记化,文本的向量总和也只会因一个不同单词的向量值而有所不同,'other'。)

【讨论】:

  • 是的,我检查了向量。有几个常见的关键字。无论如何,在我增加“iter”参数后,结果有所改善。我想我可以通过进一步增加它来获得更好的结果。但是运行代码需要很多天。
  • 好的,但如果你的代码如问题所示,你的for word in snippet:循环将有word循环值's''o''m''e', ' ''w''o''r''d' - 不是 'some''word'。另外,100 次迭代非常高,尤其是对于大型数据集。 (较大的数据集通常可以通过 较少 次迭代来解决,因为单词在许多上下文中重复。)对于大型数据集,您还可以将 negativesample(甚至可能是 window)减少到加快速度而损失很小。同时,向量大小为 8 是如此之小,我怀疑这些向量是否有用。
  • 如果您的机器有 4 个或更多内核,您还可以通过增加 workers 参数来获得加速。 (最多 8 个内核,值得一试,并观察日志输出,看看哪个值可使每秒字数吞吐量最大化。)
猜你喜欢
  • 2020-04-21
  • 2018-09-27
  • 2020-10-28
  • 2011-02-01
  • 2015-07-21
  • 1970-01-01
  • 2021-10-07
  • 2017-09-07
  • 2022-06-14
相关资源
最近更新 更多