我通过在索引时指定 TermVector 来使用 Lucene 索引文档集合。然后我通过读取索引并计算每个文档的 TF-IDF 得分向量来检索术语及其频率。然后,使用 TF-IDF 向量,我使用维基百科的余弦相似度方程计算文档之间的成对余弦相似度。
这是我的问题:假设我在这个集合中有两个相同的文档“A”和“B”(A 和 B 有 200 多个句子)。如果我计算 A 和 B 之间的成对余弦相似度,它会给我余弦值=1,这是完全可以的。但是,如果我从文档“B”中删除一个句子,它会给我这两个文档之间大约 0.85 的余弦相似度值。这些文档几乎相似,但余弦值不相似。我知道问题出在我使用的方程式上。
有没有更好的方法/方程可以用来计算文档之间的余弦相似度?
已编辑
这就是我计算余弦相似度的方式,doc1[]
并且doc2[]
是对应文档的 TF-IDF 向量。向量只包含scores
但不包含words
private double cosineSimBetweenTwoDocs(float doc1[], float doc2[]) {
double temp;
int doc1Len = doc1.length;
int doc2Len = doc2.length;
float numerator = 0;
float temSumDoc1 = 0;
float temSumDoc2 = 0;
double equlideanNormOfDoc1 = 0;
double equlideanNormOfDoc2 = 0;
if (doc1Len > doc2Len) {
for (int i = 0; i < doc2Len; i++) {
numerator += doc1[i] * doc2[i];
temSumDoc1 += doc1[i] * doc1[i];
temSumDoc2 += doc2[i] * doc2[i];
}
equlideanNormOfDoc1=Math.sqrt(temSumDoc1);
equlideanNormOfDoc2=Math.sqrt(temSumDoc2);
} else {
for (int i = 0; i < doc1Len; i++) {
numerator += doc1[i] * doc2[i];
temSumDoc1 += doc1[i] * doc1[i];
temSumDoc2 += doc2[i] * doc2[i];
}
equlideanNormOfDoc1=Math.sqrt(temSumDoc1);
equlideanNormOfDoc2=Math.sqrt(temSumDoc2);
}
temp = numerator / (equlideanNormOfDoc1 * equlideanNormOfDoc2);
return temp;
}