矩阵中每一行的余弦相似度
Cosine similarity of each row in a matrix
我有一个名为 vectors[i][j] 的矩阵。我想计算每一行之间的余弦相似度。例如对于这个矩阵
1 0 1 0 1 0 0
v= 0 0 1 1 1 0 1
1 1 0 0 1 0 1
我想计算第 1 行和第 2 行、第 1 行和第 3 行、第 2 行和 row3.Further 之间的相似度,如果第 1 行和第 2 行之间的相似度分别等于 = 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));
}
}
分解你的解决方案!提取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
}
Edit: 因为,实际上 vectors
是 double[,]
(2d array)
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);
我有一个名为 vectors[i][j] 的矩阵。我想计算每一行之间的余弦相似度。例如对于这个矩阵
1 0 1 0 1 0 0
v= 0 0 1 1 1 0 1
1 1 0 0 1 0 1
我想计算第 1 行和第 2 行、第 1 行和第 3 行、第 2 行和 row3.Further 之间的相似度,如果第 1 行和第 2 行之间的相似度分别等于 = 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));
}
}
分解你的解决方案!提取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
}
Edit: 因为,实际上 vectors
是 double[,]
(2d array)
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);