ノルティ:
私は2つのダブル配列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;
}
計算時間をスピードアップする方法はありますか?
JBX:
私はあなたが大規模な配列を持っていて、二回それらを介してループを回避したい場合、あなたの心配があるためと推測します。他の場所で指摘したように、最初の次元は、私はそれを避ける下のような答えに、あなたの関数で冗長であるように思われます。
あなたはどうすることができ、1つの関数で一緒に両方のループを結合しようとしています。
何かのようなもの:
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;
}
あなたが本当に2次元を必要とする場合は、各次元で上記の関数を呼び出します。だからあなたの例では、あなたは次のようにそれを呼び出しますcomputeSimilarity(target[0], compare[0]);