java余弦相似问题

java余弦相似问题,java,math,Java,Math,我开发了一些java程序来计算基于TF*IDF的余弦相似度。它工作得很好。但有一个问题( 例如: 若我有下面两个矩阵,并且我想计算余弦相似性,那个么它不起作用,因为行的长度不一样 doc 1 1 2 3 4 5 6 doc 2 1 2 3 4 5 6 7 8 5 2 4 9 若行和列的长度相同,那个么我的程序运行得很好,但若行和列的长度不相同,程序就不能运行 有什么提示吗?我不确定您的实现,但两个向量的值等于这些向量的标准化点积 两个矩阵的点积可以表示为a.b=aTb。因此,如果矩阵的长度不

我开发了一些java程序来计算基于TF*IDF的余弦相似度。它工作得很好。但有一个问题(

例如: 若我有下面两个矩阵,并且我想计算余弦相似性,那个么它不起作用,因为行的长度不一样

doc 1
1 2 3
4 5 6

doc 2
1 2 3 4 5 6
7 8 5 2 4 9
若行和列的长度相同,那个么我的程序运行得很好,但若行和列的长度不相同,程序就不能运行


有什么提示吗?

我不确定您的实现,但两个向量的值等于这些向量的标准化点积

两个矩阵的点积可以表示为a.b=aTb。因此,如果矩阵的长度不同,则不能使用点积来识别余弦

现在,在标准TF*IDF方法中,矩阵中的术语应通过
term,document
索引,因此,文档中未出现的任何术语应在矩阵中显示为零

现在你的设置方式似乎表明你的两个文档有两个不同的矩阵。我不确定这是否是你的意图,但它似乎不正确

另一方面,如果其中一个矩阵应该是查询,那么它应该是向量而不是矩阵,这样转置就可以产生正确的结果

TF*IDF的完整解释如下:

好的,在经典的TF*IDF中,您构造了一个术语文档矩阵
a
。矩阵
a
中的每个值都表示为ai,其中
i
是术语,
j
是文档。该值是局部、全局和标准化权重的组合(虽然如果您规范化文档,规范化的权重应该是1)。因此ai,j=fi,j*D/di,其中fi,j是doc
j
中单词
i
的频率,
D
是文档大小,di是其中包含术语
i
的文档数量

您的查询是一个术语向量,指定为
b
。对于每个术语bi,查询中的q指查询
q
的术语
i
。bi,q=fi,q其中fi,q是查询
q
中术语
i
的频率。在这种情况下,每个查询都是一个向量,多个查询形成一个矩阵

然后我们可以计算每个的单位向量,这样当我们取点积时,它将产生正确的余弦。为了得到单位向量,我们将矩阵
a
和查询
b
除以它们的值


最后,我们可以通过对给定查询采用向量
b
的转置来执行余弦距离。因此,每次计算一个查询(或向量)。这表示为bTa。最终结果是一个向量,每个术语的得分越高,表示文档等级越高。

简单java余弦相似性

 static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) {
            Set<String> both = Sets.newHashSet(v1.keySet());
            both.removeAll(v2.keySet());
            double sclar = 0, norm1 = 0, norm2 = 0;
            for (String k : both) sclar += v1.get(k) * v2.get(k);
            for (String k : v1.keySet()) norm1 += v1.get(k) * v1.get(k);
            for (String k : v2.keySet()) norm2 += v2.get(k) * v2.get(k);
            return sclar / Math.sqrt(norm1 * norm2);
    }
静态双余弦相似性(地图v1,地图v2){
Set both=Set.newHashSet(v1.keySet());
都是.removeAll(v2.keySet());
双巩膜=0,norm1=0,norm2=0;
对于(字符串k:两者)sclar+=v1.get(k)*v2.get(k);
for(字符串k:v1.keySet())norm1+=v1.get(k)*v1.get(k);
对于(字符串k:v2.keySet())norm2+=v2.get(k)*v2.get(k);
返回sclar/Math.sqrt(norm1*norm2);
}

谢谢你的回答。是的,我的第一个矩阵是查询。查询和向量之间的区别是什么?它们不是几乎相同吗?我使用一个文档作为查询,第二个文档作为目标。这就是我分别计算目标的tfidf和查询的tfidf的原因。我不能使用transponse,因为我不知道具体的列数和行数是多少be。这只是一个例子:)有问题。你能再解释一下我该如何解决我的问题吗?我应该为查询和目标创建一个tf*idf吗?如果是,那么我将如何计算余弦?@agazerboy足够了吗?或者你需要更多的解释吗?