余弦相似度基本思路是:如果这两句话的用词越相似,它们的内容就应该越相似。因此,可以从词频入手,计算它们的相似程度。
第一步,预处理主要是进行中文分词和去停用词,分词。
第二步,列出所有的词。
第三步,计算词频。
第四步,写出词频向量。
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。
余弦相似度缺陷
这类算法没有很好地解决文本数据中存在的自然语言问题,即同义词和多义词。这样对于搜索的精度产生很大的影响。
衡量文本相似度的几种手段:
(1)最长公共子串(基于词条空间)
(2)最长公共子序列(基于权值空间、词条空间)
(3)最少编辑距离法(基于词条空间)
(4)汉明距离(基于权值空间)
(5)余弦值(基于权值空间)
向量空间余弦相似度(Cosine Similarity)
余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。
上图两个向量a,b的夹角很小可以说a向量和b向量有很高的的相似性,极端情况下,a和b向量完全重合。如下图:
如上图二:可以认为a和b向量是相等的,也即a,b向量代表的文本是完全相似的,或者说是相等的。如果a和b向量夹角较大,或者反方向。如下图
如上图三: 两个向量a,b的夹角很大可以说a向量和b向量有很底的的相似性,或者说a和b向量代表的文本基本不相似。那么是否可以用两个向量的夹角大小的函数值来计算个体的相似度呢?
向量空间余弦相似度理论就是基于上述来计算个体相似度的一种方法。下面做详细的推理过程分析。
想到余弦公式,最基本计算方法就是初中的最简单的计算公式,计算夹角
图(4)
的余弦定值公式为:
但是这个是只适用于直角三角形的,而在非直角三角形中,余弦定理的公式是
图(5)
三角形中边a和b的夹角 的余弦计算公式为:
公式(2)
在向量表示的三角形中,假设a向量是(x1, y1),b向量是(x2, y2),那么可以将余弦定理改写成下面的形式:
图(6)
向量a和向量b的夹角 的余弦计算如下
扩展,如果向量a和b不是二维而是n维,上述余弦的计算法仍然正确。假定a和b是两个n维向量,a是 ,b是 ,则a与b的夹角 的余弦等于:
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,夹角等于0,即两个向量相等,这就叫"余弦相似性"。
二、余弦相似度代码如下:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 字符串相似性匹配算法
*/
public class CosDemo {
//数据结构解析:<单词,二维数组>,其中单词表示公共词,
// 二维数组一维度表示句子一的向量,另一维度表示句子二的向量
Map<Character, int[]> vectorMap = new HashMap<Character, int[]>();
int[] tempArray = null;
public CosDemo(String string1, String string2) {
for (Character character1 : string1.toCharArray()) {
if (vectorMap.containsKey(character1)) {
vectorMap.get(character1)[0]++;
} else {
tempArray = new int[2];
tempArray[0] = 1;
tempArray[1] = 0;
vectorMap.put(character1, tempArray);
}
}
for (Character character2 : string2.toCharArray()) {
if (vectorMap.containsKey(character2)) {
vectorMap.get(character2)[1]++;
} else {
tempArray = new int[2];
tempArray[0] = 0;
tempArray[1] = 1;
vectorMap.put(character2, tempArray);
}
}
for (Map.Entry<Character, int[]> entry : vectorMap.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()[0] +","+entry.getValue()[1]);
}
}
// 求余弦相似度
public double sim() {
double result = 0;
result = pointMulti(vectorMap) / sqrtMulti(vectorMap);
return result;
}
private double sqrtMulti(Map<Character, int[]> paramMap) {
double result = 0;
result = squares(paramMap);
result = Math.sqrt(result);
return result;
}
// 求平方和
private double squares(Map<Character, int[]> paramMap) {
double result1 = 0;
double result2 = 0;
Set<Character> keySet = paramMap.keySet();
for (Character character : keySet) {
int temp[] = paramMap.get(character);
result1 += (temp[0] * temp[0]);
result2 += (temp[1] * temp[1]);
}
return result1 * result2;
}
// 点乘法
private double pointMulti(Map<Character, int[]> paramMap) {
double result = 0;
Set<Character> keySet = paramMap.keySet();
for (Character character : keySet) {
int temp[] = paramMap.get(character);
result += (temp[0] * temp[1]);
}
return result;
}
public static void main(String[] args) {
String s1 = "我爱北京甜安门";
String s2 = "我喜欢吃北京烤鸭";
//第一步,预处理主要是进行中文分词和去停用词,分词。
//第二步,列出所有的词。
//公共词 :我爱北京甜安门喜欢吃烤鸭
//第三步,计算词频,写出词频向量。
//向量1:<1,1,1,1,1,1,1,0,0,0,0,0>
//向量2:<1,0,1,1,0,0,0,1,1,1,1,1>
// 3/6 > cos =3/根号42 > 3/7即结果在3/6和3/7之间
CosDemo similarity = new CosDemo(s1, s2);
System.out.println(similarity.sim());
}
}
相关推荐
本节将详细分析给定的Java代码,并从中提取出关键的知识点。 ##### 2.1 类定义及初始化 代码定义了一个名为`ComputerDecision`的类,用于计算两个字符串表示的向量之间的余弦相似度。 ```java public class ...
"Java基于余弦方法实现的计算相似度算法示例" ...本文主要介绍了Java基于余弦方法实现的计算相似度算法,并提供了一个简单的示例代码。通过这种算法,我们可以计算两个字符串之间的相似度,从而应用于文件比较等领域。
在实际应用中,开发者需要结合这些概念,根据具体需求选择合适的方法和技术,编写Java代码实现词义相似度计算。例如,使用TF-IDF或Word2Vec模型进行向量化,再通过余弦相似度计算两个词向量的相似度。同时,理解并...
本项目专注于使用Java实现一个基于协同过滤算法的电影推荐系统,它利用修正的余弦相似度来为用户推荐最可能感兴趣的电影。以下是这个系统的关键知识点和技术细节: 1. **协同过滤算法**:协同过滤是推荐系统中最...
Java实现的计算稀疏矩阵余弦相似度示例 本文主要介绍了Java实现的计算稀疏矩阵余弦相似度功能,涉及Java基于HashMap的数值计算相关操作技巧。在本示例中,我们将学习如何使用Java实现稀疏矩阵余弦相似度计算,并...
在提供的"作业"文件中,可能包含了实现这些步骤的Java代码示例,包括预处理、分词、向量化和相似度计算的函数,以及运行和展示结果的主程序。通过分析和理解这些代码,你可以更深入地了解如何在实际项目中应用文本...
在这个项目中,重点在于实现了一个基于【余弦相似度算法】的推荐菜品功能,这是系统的一个亮点。余弦相似度算法在信息检索、推荐系统等领域广泛应用,它通过计算两个向量之间的夹角余弦值来评估它们之间的相似性。 ...
JAVA查重算法,包括HanLP 相似度比较、二叉树、DFA算法实现、敏感词处理工具、IKAnalyzer中文分词工具、分词进行敏感词过滤等查重算法,可以计算海明距离、余弦相似性、莱文斯坦距离、Jaccard 相似度、Sorensen Dice...
余弦相似度是通过计算两个向量的夹角余弦值来衡量它们的相似度,值域在-1到1之间,1表示完全相同,0表示完全无关,-1表示方向相反。在VSM中,两个向量的点积除以它们各自的模长乘积即可得到余弦相似度。 这个Java...
在这个Java实现的文本相似度系统中,主要采用了向量空间模型(Vector Space Model, VSM)和余弦相似度算法。接下来,我们将详细讨论这两个核心概念。 **向量空间模型(Vector Space Model)** 向量空间模型是一种将...
该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! ...
6. **计算余弦相似度**:使用点积除以向量的模长之积,计算两个文档的余弦相似度。 在`Cosine-similarity-Tf-Idf--master`这个压缩包中,可能包含了实现这些步骤的Java代码。通过阅读和理解这些代码,你可以深入...
通过计算两个特征向量之间的距离,如欧氏距离或余弦相似度,可以得到人脸的相似度分数。 在"java0323"这个文件夹中,可能包含了项目的源代码、配置文件、数据集以及相关的文档。源代码可能分为几个部分,包括: 1....
此外,还可能使用TF-IDF(词频-逆文档频率)或余弦相似度等方法对处理后的词形进行相似度比较。 2. **词序相似度**: 词序相似度考虑的是句子中单词的相对位置,因为相同单词的不同顺序可能导致不同的语义。在这个...
5. **相似度度量**:最后,根据匹配的结果,可以选择不同的相似度度量方法,如汉明距离、余弦相似度、结构相似度指数(SSIM)等,得出两张图片的整体相似度分数。 在`Compic.java`源代码中,我们可以看到作者具体是...
这个功能是通过TF-IDF和余弦相似度算法来实现的。 TF-IDF,全称Term Frequency-Inverse Document Frequency,是一种在信息检索和文本挖掘中广泛使用的统计方法,用于评估一个词在文档中的重要性。TF代表词频(Term ...
在Java编程环境中,我们可以使用特定的算法和方法来计算两个双值哈希图之间的余弦相似度。这里,我们将深入探讨余弦相似度的概念、计算方式以及在Java中的实现。 余弦相似度的基础是向量空间模型,其中每个文档或...
在Java代码中,代码相似度检测可以帮助开发者发现可能存在的复制粘贴代码(也称为剪切板编程),这种做法可能导致代码维护困难、增加bug风险和降低整体代码质量。此外,通过检测相似代码,可以发现潜在的代码重用...
两个向量的余弦相似度定义为它们的内积除以各自的模长之积。 5. **应用**:计算出的相似度可以用于多种任务,如信息检索(找出与查询最相关的文档)、文本分类(根据文档内容分组)等。 在Java实现中,"Document...
在"SimilarImageSearch"这个压缩包文件中,可能包含了实现上述功能的Java代码示例、库文件或其他相关资源。通过学习和理解这些代码,你可以掌握如何在Java环境中进行图像识别和判断图像相似性的技术。 总的来说,...