1

HashMap として表される 2 つのベクトルがあり、それらの間の類似性を測定したいと考えています。次のコードのように、コサイン類似度メトリックを使用します。

public static void cosineSimilarity(HashMap<Integer,Double> vector1, HashMap<Integer,Double> vector2){
double scalar=0.0d, v1Norm=0.0d, v2Norm=0.0d;

for(int featureId: vector1.keySet()){
   scalar+= (vector1.get(featureId)* vector2.get(featureId));
   v1Norm+= (vector1.get(featureId) * vector1.get(featureId));
   v2Norm+= (vector2.get(featureId) * vector2.get(featureId));
}

 v1Norm=Math.sqrt(v1Norm);
 v2Norm=Math.sqrt(v2Norm);

 double cosine= scalar / (v1Norm*v2Norm);
 System.out.println("v1 is: "+v1Norm+" , v2 is: "+v2Norm+" Cosine is: "+cosine);    
}

不思議なことに、似ていないはずの 2 つのベクトルが 0.9999 の結果に近くなりましたが、これはまったくの間違いです!

キーは両方のマップでまったく同じであることに注意してください。

データファイルはここにあります: file

ファイル形式:

FeatureId vector1_value vector2_value

4

1 に答える 1

4

あなたのコードは問題ありません。

ベクトルは、いくつかの大きな特徴によって支配されています。これらの特徴では、2 つのベクトルはほぼ同一線上にあるため、類似度の測定値は に近くなり1ます。

以下に 6 つの最大の機能を示します。vec2overの比率を見てくださいvec1。これらの機能全体でほぼ同じです。

feature     vec1    vec2        vec2/vec1

64806110    2875    1.85E+07    6.43E+03
64806108    5750    3.68E+07    6.40E+03
64806107    8625    5.49E+07    6.37E+03
64806106    11500   7.29E+07    6.34E+03
64806111    14375   9.07E+07    6.31E+03
64806109    17250   1.08E+08    6.28E+03
于 2013-03-12T07:56:11.907 に答える