余弦相似度算法
相信大家对这个概念并不陌生,废话少说,先来炒点现饭!
概念
余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估他们的相似度。余弦相似度将向量根据坐标值,绘制到向量空间中,如最常见的二维空间。
余弦相似度衡量的是2个向量间的夹角大小,通过夹角的余弦值表示结果,因此2个向量的余弦相似度为:
余弦相似度公式分子为向量A与向量B的点乘,分母为二者各自的L2相乘,即将所有维度值的平方相加后开方。
余弦相似度的取值为[-1,1],值越大表示越相似。
理论推导
我们以二维向量为例,计算向量(x1,y1)(x1,y1)与向量(x2,y2)(x2,y2)的余弦相似度。
先回顾一下初中的知识,看下图:
比较两个向量是否一致,看其在另外一边的投影我们可以得到公式:
公式其中A与B表达向量(x1,y1)(x1,y1)与向量(x2,y2)(x2,y2)。
分子为A与B的点乘,分母为二者各自的L2相乘,即将所有维度值的平方相加后开方。
Java代码实现
废话少说,直接上核心代码:
1. 首先,必须明确,余弦相似度是 点乘和叉乘的商;点乘的数据保存于int[]中,具体开辟多少位by自己需要;然后我们可以写出一个构造类,类中只需要有一个成员HashMap
2. 其次,对HashMap中的各个Key分别点乘求和,叉乘求和
3. 然后,就可以求余弦相似度了
4. 最后,不得不啰嗦一句:本文的写法适用于文本的处理(自然语言)、数据的处理,意图想一套算法覆盖各种需求,然而使用久了之后发现该算法存在一个弊端:
当特征向量的顺序完全相反时,其结论也是1;这与HashMap在吸收各个Charactor时的设计有关,HashMap的Key嘛不会重复,当然也无顺序;因此,如果对向量的方向有很严格的要求,那么就使用[加强型余弦相似度]算法了;
【加强型余弦相似度算法】可以很好的处理自然语言情感分类类型的问题,对于类似“淘宝”、“京东”等大型购物网站的“客户评论信息”分类分析是个不错的落地场景,欢迎大家一起讨论,共同进步!