2016-05-12 83 views
0

我有一個名爲向量的矩陣[i] [j]。我想計算每行之間的餘弦相似度。例如,對於這個矩陣的計算矩陣中每一行的餘弦相似度

1 0 1 0 1 0 0 
v= 0 0 1 1 1 0 1 
    1 1 0 0 1 0 1 

我想有相似度計算,ROW1和列2,ROW1和ROW3,ROW2和row3.Further之間更分別如果ROW1和ROW2之間的相似性等於= 0.6和其他0.5和0.4 。我想在這些行的每個元素(e =!0)上加上這個值,並得到最終的矩陣。

2.1 0 2.1 0 2.1 0 0 
v= 0  0  2 2 2  0 2 
    1.9 1.9 0 0 1.9 0 1.9 

這裏是我定義和填充我的矩陣的代碼部分;

string text = Request.Form["TextBox1"]; ; // text 
      string[] textInArray = text.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); 
      int[,] vectors = new int[textInArray.Length, keywords.Length]; 

      for (int i = 0; i < textInArray.Length; i++) 
      { 
       string[] words = textInArray[i].Split(' '); 
       for (int j = 0; j < keywords.Length; j++) 
       { 
        foreach (var word in words) 
        { 
         if (word.Contains(keywords[j])) 
         { 
          vectors[i, j]++; 
         } 
        } 
       } 
      } 

,這裏是我的代碼來計算相似度,但我認爲它不是某個地方我有錯誤,我不知道我怎樣才能在當前的兩行的元素添加此值完成。

for(i=1 i<matrix.GetLength(0) i++){ 
    for(j=1 j<matrix.GetLength(0) j++){ 
      dot += vectors[i] * vectors[j]; 
      mag1 += Math.Pow(vectors[i], 2); 
      mag2 += Math.Pow(vectors[j], 2); 
     } 

     float M= dot/(Math.Sqrt(mag1) * Math.Sqrt(mag2)); 

} 
} 
+1

刪除了asp.net標籤,因爲問題似乎並不涉及asp.net以任何方式,添加C# – Andrei

回答

1

分解您的解決方案!提取Similarity方法

private static double Similarity(double[] left, double[] right) { 
    double ab = 0.0; 
    double aa = 0.0; 
    double bb = 0.0; 

    for (int i = 0; i < left.length; ++i) { 
    aa += left[i] * left[i]; 
    ab += left[i] * right[i]; 
    bb += right[i] * right[i]; 
    } 

    // do not forget degenerated cases: all-zeroes vectors 
    if (aa == 0) 
    return bb == 0 ? 1.0 : 0.0; 
    else if (bb == 0) 
    return 0.0; 
    else 
    return ab/Math.Sqrt(aa)/Math.Sqrt(bb); 
} 

然後把簡單的邏輯

// vectors[][] is an array of array, so we can get lines easily by vectors[0] etc. 
double sim12 = Similarity(vectors[0], vectors[1]); 
double sim23 = Similarity(vectors[1], vectors[2]); 
double sim13 = Similarity(vectors[0], vectors[2]); 

// compare double with tolerance 
if ((Math.Abs(sim12 - 0.6) < 1e-10) && 
    (Math.Abs(sim13 - 0.5) < 1e-10) && 
    (Math.Abs(sim23 - 0.4) < 1e-10)) { 
    //TODO: update the matrix 
} 

編輯:因爲,事實上vectorsdouble[,]2D陣列

private static double Similarity(double[,] matrix, int left, int right) { 
    double ab = 0.0; 
    double aa = 0.0; 
    double bb = 0.0; 

    for (int i = 0; i < matrix.GetLength(1); ++i) { 
    aa += matrix[left, i] * matrix[left, i]; 
    ab += matrix[left, i] * matrix[right, i]; 
    bb += matrix[right, i] * matrix[right, i]; 
    } 

    if (aa == 0) 
    return bb == 0 ? 1.0 : 0.0; 
    else if (bb == 0) 
    return 0.0; 
    else 
    return ab/Math.Sqrt(aa)/Math.Sqrt(bb); 
} 

... 。

double sim12 = Similarity(vectors, 0, 1); 
double sim23 = Similarity(vectors, 1, 2); 
double sim13 = Similarity(vectors, 0, 2); 
+0

我得到這個錯誤「指數錯誤[];預計2「\t爲linedouble sim12 =相似性(....)你認爲這是因爲我已經在begininng中定義了我的矩陣嗎? int [,] vectors = new int [textInArray.Length,keywords.Length ]; – dpointttt

+0

@:dpointttt:*它是*。如果你有像矩陣一樣的問題*'vector [i] [j]'ie * array * array *我的代碼會做;但如果你真的把它放在' int [,] vectors' ie * 2D array *我的代碼不會這樣做array.array(又名* jugged array *)比2D更靈活 –

+0

@:dpointttt:但是,主要原理是相同的:* extract方法*無論您有矩陣的表示形式 –