2011-09-26 49 views
6

我想找到2個向量(x,y點)之間的餘弦相似度,我做出了一些我無法確定的愚蠢錯誤。請原諒我是一個新手,如果我犯了一個非常簡單的錯誤(我很可能是),對不起。餘弦相似性代碼(非期限向量)

感謝您的幫助

public static double GetCosineSimilarity(List<Point> V1, List<Point> V2) 
    { 
     double sim = 0.0d; 
     int N = 0; 
     N = ((V2.Count < V1.Count)?V2.Count : V1.Count); 
     double dotX = 0.0d; double dotY = 0.0d; 
     double magX = 0.0d; double magY = 0.0d; 
     for (int n = 0; n < N; n++) 
     { 
      dotX += V1[n].X * V2[n].X; 
      dotY += V1[n].Y * V2[n].Y; 
      magX += Math.Pow(V1[n].X, 2); 
      magY += Math.Pow(V1[n].Y, 2); 
     } 

     return (dotX + dotY)/(Math.Sqrt(magX) * Math.Sqrt(magY)); 
    } 

編輯:除了語法,我的問題也與給我處理不同長度的向量邏輯結構做。另外,上面如何將其推廣到m維向量。由於

+0

您正在混淆索引和X,Y.每個列表中的索引應表示組件(即0-> x,1-> y,2-> z)。另一種方式,你只需要2個點V1和V2,每個點都有一個x和y,代表一個2維向量。您不需要索引n和.X和.Y – JohnPS

回答

11

如果你是2維,那麼你可以有表示爲(V1.X, V1.Y)(V2.X, V2.Y)載體,然後用

public static double GetCosineSimilarity(Point V1, Point V2) { 
return (V1.X*V2.X + V1.Y*V2.Y) 
     /(Math.Sqrt(Math.Pow(V1.X,2)+Math.Pow(V1.Y,2)) 
      Math.Sqrt(Math.Pow(V2.X,2)+Math.Pow(V2.Y,2)) 
      ); 
} 

如果你在更高那麼您可以將每個矢量表示爲List<double>。因此,在四維中,第一個向量將包含組件V1 = (V1[0], V1[1], V1[2], V1[3])

public static double GetCosineSimilarity(List<double> V1, List<double> V2) 
{ 
    int N = 0; 
    N = ((V2.Count < V1.Count) ? V2.Count : V1.Count); 
    double dot = 0.0d; 
    double mag1 = 0.0d; 
    double mag2 = 0.0d; 
    for (int n = 0; n < N; n++) 
    { 
     dot += V1[n] * V2[n]; 
     mag1 += Math.Pow(V1[n], 2); 
     mag2 += Math.Pow(V2[n], 2); 
    } 

    return dot/(Math.Sqrt(mag1) * Math.Sqrt(mag2)); 
} 
+0

謝謝!你有很大的幫助。 – Mikos

1

最後一行應

return (dotX + dotY)/(Math.Sqrt(magX) * Math.Sqrt(magY))