6

我一直在做一个关于句子相似度的项目。我知道它已经在 SO 中被问过很多次,但我只是想知道我的问题是否可以通过我使用的方法来解决,或者我应该改变解决问题的方法。粗略地说,系统应该拆分一篇文章的所有句子,并在提供给系统的其他文章中找到相似的句子。

我正在使用带有 tf-idf 权重的余弦相似度,这就是我的做法。

1-首先,我将所有文章分成句子,然后为每个句子生成三元组并对它们进行排序(我应该吗?)。

2-我计算三元组的 tf-idf 权重并为所有句子创建向量。

3-我计算原始句子和要比较的句子的点积和大小。然后计算余弦相似度。

但是,该系统没有按我预期的那样工作。说到这里,我心里有几个问题。

据我了解 tf-idf 权重,我想它们对于查找类似的“文档”更有用。由于我正在研究句子,因此我通过更改 tf 和 idf 定义公式的一些变量来稍微修改了算法(而不是我试图提出基于句子的定义的文档)。

tf = 句子中 trigram 出现的次数 / 句子中所有 trigram 的数量

idf = 所有文章中所有句子的数量/出现 trigram 的句子数量

你认为对这个问题使用这样的定义可以吗?

另一个是我在计算余弦相似度时看到多次提到归一化。我猜这很重要,因为三元向量的大小可能不同(在我的情况下它们很少)。如果一个三元向量是 x 的大小,另一个是 x+1,那么我将第一个向量视为 x+1 的大小,最后一个值为 0。这就是归一化的意思吗?如果没有,我该如何进行标准化?

除了这些,如果我选择了错误的算法,还有什么可以用于此类问题(最好使用 n-gram 方法)?

先感谢您。

4

1 回答 1

6

我不确定您为什么要对每个句子的三元组进行排序。在计算余弦相似度时,您需要关心的是两个句子中是否出现相同的三元组以及出现的频率。从概念上讲,您在所有可能的三元组中定义了一个固定且通用的顺序。请记住,所有句子的顺序必须相同。如果可能的三元组的数量为 N,那么对于每个句子,您都会获得一个维度为 N 的向量。如果某个三元组不存在,则将向量中的相应值设置为零。您实际上并不需要存储零,但在定义点积时必须注意它们。

话虽如此,三元组并不是一个好的选择,因为匹配的机会要少得多。对于高 k,你会从 k 个连续单词的袋子中获得更好的结果,而不是 k-gram。请注意,袋子内的顺序无关紧要,它是一组。您正在使用 k=3 k-gram,但这似乎偏高,尤其是对于句子。从 1 开始,要么下降到双克,要么使用不同长度的袋子。最好同时使用。

我相信你已经注意到不使用精确三元组的句子在你的方法中的相似度为 0。K-bag 词组会在一定程度上缓解这种情况,但不能完全解决。因为现在你需要句子来分享实际的单词。两个句子可能相似,但不使用相同的词。有几种方法可以解决这个问题。使用 LSI(潜在语义索引)或单词聚类并使用聚类标签来定义余弦相似度。

为了计算向量 x 和 y 之间的余弦相似度,您需要计算点积并除以 x 和 y 的范数。向量 x 的 2 范数可以计算为分量平方和的平方根。但是,您还应该尝试您的算法,而无需进行任何标准化进行比较。通常它工作得很好,因为在计算术语频率 (tf) 时,您已经在考虑句子的相对大小。

希望这可以帮助。

于 2010-10-27T20:27:52.520 回答