我有两个双精度数组 a 和 b,想要计算它们之间的余弦相似度。我的代码如下所示:
double [][] target = new double [1][65000];
double [][] compare = new double [1][65000];
double dotProduct = dot(target[0], compare[0]);
double eucledianDist = norm2(target) * norm2(compare);
double output = dotProduct / eucledianDist;
private double norm2(double[][] a){
double sum = 0;
for (int i = 0; i < a[0].length; i++){
sum = sum + a[0][i] * a[0][i];
}
return Math.sqrt(sum);
}
private double dot(double[] a, double [] b){
double sum = 0;
for(int i = 0; i < a.length; i ++){
sum += a[i] * b[i];
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
有什么办法可以加快计算时间吗?
我想您担心的是当您有大型数组并且您想避免循环遍历它们两次时。正如其他地方所指出的,第一个维度在您的函数中似乎是多余的,因此在下面的答案中我避免了它。
您可以做的就是尝试将两个循环组合在一个函数中。
就像是:
double computeSimilarity(double[] a, double[] b) {
//todo: you might want to check they are the same size before proceeding
double dotProduct = 0;
double normASum = 0;
double normBSum = 0;
for(int i = 0; i < a.length; i ++) {
dotProduct += a[i] * b[i];
normASum += a[i] * a[i];
normBSum += b[i] * b[i];
}
double eucledianDist = Math.sqrt(normASum) * Math.sqrt(normBSum);
return dotProduct / eucledianDist;
}
Run Code Online (Sandbox Code Playgroud)
如果您确实需要二维,请在每个维度上调用上面的函数。所以在你的例子中你会这样称呼它computeSimilarity(target[0], compare[0]);
| 归档时间: |
|
| 查看次数: |
740 次 |
| 最近记录: |