0

私はドキュメントを推奨するためにいくつかの作業を行っており、そのためにコサイン類似度法を使用しています。そのメソッドのコードは次のとおりです。

static double cosineSimilarity(HashMap<String, Double> v1, HashMap<String, Double> v2) 
{
    Set<String> both = v1.keySet();
    both.retainAll(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);
}

問題は、パラメーターが渡される順序によって結果が異なることです。たとえば、呼び出すcosineSimilarity(v1, v2)と返され0.3ますが、呼び出すcosineSimilarity(v2, v1)とまったく異なる値が返されます。

Map.keySet() これは、マップに基づくセットを返すという事実と関係があると思いますが、これの意味を完全には理解していません。

メソッドのどこが間違っているのか誰にもわかりますか?

4

1 に答える 1

6

試す

Set<String> both = new HashSet<String>(v1.keySet());

それ以外の

Set<String> both = v1.keySet();

メソッドから取得したセットを変更しないでください。これはkeySet、マップがそれを使用し、そこから要素を削除すると (retainAllあなたの場合は) 要素もマップから削除されるためです。例:

Map<Integer, Integer> mp = new HashMap<Integer, Integer>();
mp.put(1, 1);
System.out.println(mp); // output {1=1}
mp.keySet().remove(1);
System.out.println(mp); // output {}
于 2012-12-28T16:04:07.567 に答える