我试图找到两个向量(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 维的向量。谢谢
如果你是二维的,那么你可以将向量表示为
(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>
。因此,在 4 维中,第一个向量将具有分量 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));
}
最后一行应该是
return (dotX + dotY)/(Math.Sqrt(magX) * Math.Sqrt(magY))
Microsoft 在 Microsoft.SemanticKernel.Core Nuget 包(当前版本为 1.0.0-beta1)中有一个扩展方法,该扩展方法称为 CosineSimilarity。它具有三个重载:
使用浮点数组,用法如下所示:
float[] vector1 = new[] { 0.018007852f, 0.031938456f, -0.046234965f, };
float[] vector2 = new[] { 0.01055384f, 0.0020128791f, 0.013548848f };
double result = vector1.CosineSimilarity(vector2);
结果越接近 1,两个项目越相似。