前言
余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估他们的相似度。余弦相似度将向量根据坐标值,绘制到向量空间中。用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,反之越接近0就表示两个向量相似度越低,这就叫"余弦相似性"。
正文
重温余弦定理
先简单的重温一下高中数学知识,余弦定理
这个公式大家不知道还有没有印象呢?没有的话我们看下下面的图
此时a=(xa,ya)
,b=(xb,0)
,那么怎么计算各边长的长度呢?
此时将各边长代入上图的公式当中,最后可以得出最终的计算公式
文本相似度计算步骤
那么在我们的文本相似度计算中,都有哪些步骤呢?
- 分词,比如有两行文本,第一句:
你好,我是小王,我是个程序员”
,将会分割成你好/我/是/小王/我/是/个/程序员
。第二句:你好,我是设计师
,将会分成你好/我/是/设计师
- 统计词频,其实就是统计所有语句中的每个词在当前句子出现的次数,第一句:
你好1,我2,是2,小王1,个1,程序员1,设计师0
,第二句你好1,我1,是1,小王0,个0,程序员0,设计师1
- 组合词频向量,第一句
(1,2,2,1,1,1,0)
,第二句(1,1,1,0,0,0,1)
。 - 将数据代入上面的公式计算相似度
maven 引入ikanalyzer依赖
这里使用ikanalyzer来实现一个简单的分词功能
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
IKUtils分词工具类,代码比简单,唯一一个方法返回的是语句分词的List对象
/**
* 分词相关工具类
* @author wangzh
*/
public class IKUtils {
/**
* 以List的格式返回文本分词的结果
* @param text
* @return
*/
public static List<String> divideText(String text){
if(null == text || "".equals(text.trim())){
return null;
}
List<String> resultList = new ArrayList<>();
StringReader re = new StringReader(text);
IKSegmenter ik = new IKSegmenter(