2016-05-12 179 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方法*无论您有矩阵的表示形式 –