Text 有人能用一种非常简单的图形化方式举一个余弦相似性的例子吗?

Text 有人能用一种非常简单的图形化方式举一个余弦相似性的例子吗?,text,data-mining,cosine-similarity,Text,Data Mining,Cosine Similarity,你能在这里显示向量吗(在列表中或其他地方) 然后做数学,让我们看看它是如何工作的 我是初学者。这是我在C#中的实现 使用系统; 名称空间余弦相似性 { 班级计划 { 静态void Main() { int[]vecA={1,2,3,4,5}; int[]vecB={6,7,7,9,10}; var cosSimilarity=计算相似性(vecA,vecB); 控制台写入线(Coseline); Console.Read(); } 私有静态双重计算相似性(int[]vecA,int[]vecB)

你能在这里显示向量吗(在列表中或其他地方) 然后做数学,让我们看看它是如何工作的


我是初学者。

这是我在C#中的实现

使用系统;
名称空间余弦相似性
{
班级计划
{
静态void Main()
{
int[]vecA={1,2,3,4,5};
int[]vecB={6,7,7,9,10};
var cosSimilarity=计算相似性(vecA,vecB);
控制台写入线(Coseline);
Console.Read();
}
私有静态双重计算相似性(int[]vecA,int[]vecB)
{
var dotProduct=dotProduct(vecA,vecB);
var震级a=震级(vecA);
var震级B=震级(vecB);
返回点积/(幅值A*幅值B);
}
私有静态双点积(int[]vecA,int[]vecB)
{
//我不是为了简单而在这里验证输入。
双点积=0;
对于(变量i=0;i
我猜您更感兴趣的是了解余弦相似性的“为什么”起作用(为什么它提供了一个很好的相似性指示),而不是它的“如何”计算(用于计算的特定操作)。如果您对后者感兴趣,请参阅丹尼尔在本文中指出的参考资料,以及

为了解释如何以及为什么,首先,简化问题并只在两个维度上工作是有用的。一旦你在二维中得到这个,在三维中思考它就更容易了,当然在更多的维度中也更难想象,但是到那时我们可以用线性代数来做数值计算,也可以帮助我们在n维中用线/向量/“平面”/“球体”来思考,即使我们不能画这些

因此,在两个维度上:关于文本相似性,这意味着我们将关注两个不同的术语,比如“伦敦”和“巴黎”,我们将计算在我们希望比较的两个文档中,每个词被发现的次数。这为每个文档提供了x-y平面上的一个点。例如,如果Doc1有一次巴黎,四次伦敦,那么(1,4)处的一个点将呈现此文档(关于此文档的小型评估)。或者,就向量而言,Doc1文档将是一个从原点到点(1,4)的箭头。考虑到这个图像,让我们思考两个文档相似意味着什么,以及这与向量的关系

非常相似的文件(同样关于这一有限的维度集)将有非常相同数量的巴黎参考文献,以及非常相同数量的伦敦参考文献,或者,它们可能有相同比例的这些参考文献。一份名为Doc2的文件,其中有2份参考文献指向巴黎,8份参考文献指向伦敦,也会非常相似,只是可能会有更长的文本,或者以某种方式重复城市名称,但比例相同。也许这两份文件都是关于伦敦的指南,只是顺便提到了巴黎(以及那个城市有多不酷;-)只是开玩笑而已

现在,不太相似的文件也可能包括对这两个城市的引用,但比例不同。也许Doc2只会引用巴黎一次,引用伦敦七次

回到我们的x-y平面,如果我们画这些假设的文档,我们会看到当它们非常相似时,它们的向量重叠(尽管有些向量可能更长),当它们的共同点开始减少时,这些向量开始发散,在它们之间有一个更大的角度

通过测量向量之间的角度,我们可以很好地了解它们的相似性,为了让事情变得更简单,通过计算这个角度的余弦,我们得到了一个很好的0到1或-1到1的值,这表示这种相似性,这取决于我们考虑的内容和方式。角度越小,余弦值越大(接近1),相似度也越高

在极端情况下,如果Doc1只引用巴黎,Doc2只引用伦敦,那么这些文件绝对没有任何共同之处。Doc1的向量在x轴上,Doc2在y轴上,角度为90度,余弦为0。在这种情况下,我们可以说这些文档彼此正交

添加维度
有了这种以小角度(或大余弦)表示的相似性的直观感觉,我们现在可以在三维空间中想象事物,比如说,将“阿姆斯特丹”一词带入混合空间,并很好地想象出一个文档(每个文档有两个引用)是如何有一个向量指向特定方向的,我们可以看到这一方向与一份分别引用巴黎和伦敦三次的文件相比会如何,但不是阿姆斯特丹等。正如所说的,我们可以试着想象这个10或100个城市的奇特空间。这很难画,但很容易概念化

最后,我将对公式本身说几句话。正如我所说,其他参考文献提供了有关计算的良好信息

首先是两个方面。两个矢量之间夹角的余弦公式由三角差(夹角a和夹角b之间)导出:

此公式与点积公式非常相似:

Vect1 . Vect2 =  (x1 * x2) + (y1 * y2)
其中,
cos(a)
对应于第一个向量的
x
值和
sin(a)
值。唯一的问题是
Vect1 . Vect2 =  (x1 * x2) + (y1 * y2)
me Julie loves Linda than more likes Jane
   me   2   2
 Jane   0   1
Julie   1   1
Linda   1   0
likes   0   1
loves   2   1
 more   1   1
 than   1   1
a: [2, 0, 1, 1, 0, 2, 1, 1]

b: [2, 1, 1, 0, 1, 1, 1, 1]
Let :
    a : [1, 1, 0]
    b : [1, 0, 1]
 (Theta) = (1*1 + 1*0 + 0*1)/sqrt((1^2 + 1^2))* sqrt((1^2 + 1^2)) = 1/2 = 0.5
a = c(2,1,0,2,0,1,1,1)

b = c(2,1,1,1,1,0,1,1)

d = (a %*% b) / (sqrt(sum(a^2)) * sqrt(sum(b^2)))
e = crossprod(a, b) / (sqrt(crossprod(a, a)) * sqrt(crossprod(b, b)))
/**
   * Method to calculate cosine similarity of vectors
   * 1 - exactly similar (angle between them is 0)
   * 0 - orthogonal vectors (angle between them is 90)
   * @param vector1 - vector in the form [a1, a2, a3, ..... an]
   * @param vector2 - vector in the form [b1, b2, b3, ..... bn]
   * @return - the cosine similarity of vectors (ranges from 0 to 1)
   */
  private double cosineSimilarity(List<Double> vector1, List<Double> vector2) {

    double dotProduct = 0.0;
    double normA = 0.0;
    double normB = 0.0;
    for (int i = 0; i < vector1.size(); i++) {
      dotProduct += vector1.get(i) * vector2.get(i);
      normA += Math.pow(vector1.get(i), 2);
      normB += Math.pow(vector2.get(i), 2);
    }
    return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
  }