JAVA-简单实现文本相似度计算-余弦相似度

简介

在下是刚毕业的小萌新,现在在一家股票资讯公司做Java开发。手上是一个消息监控的项目,需要实时把爬虫组爬到的新闻经过处理入库。今天来了个需求,需要对新闻做一个去重的处理,减少类似新闻的出现。我理性分析一波,应该就是要计算一下文本的相似度嗯嗯。。。那该怎么做呢。。。

计算文本相似度方法

文本的相似度计算方法可以分为两大类:基于深度学习的方法和基于非深度学习的方法。
虽然小的我在自然语言处理与交互部,但我只是个开发,不是算法,所以这里采用简单的非深度学习的方法。
常用的几个计算方法:余弦相似度、最小编辑距离。。。。。
由于场景比较简单,所以并没有对文本进行分词,如果有需要,可以用jieba,hanlp等等

余弦相似度

private static double getSimilarity(String doc1, String doc2) {
     
		if (StringUtils.isBlank(doc1) or StringUtils.isBlank(doc2)) {
     
				return 0L;
		}
		Map<Character,int[]> algMap=new HashMap<>();
		for (int i = 0; i<doc1.length(); i++) {
     
				char d1 = doc1.charAt(i);
				int[] fq = algMap.get(d1);
				if (fq != null && fq.length == 2) {
     
						fq[0]++;
				} else {
     
						fq = new int[2];
						fq[0] = 1;
						fq[1] = 0;
						algMap.put(d1, fq);
				}
		}
		for (int i = 0; i<doc2.length(); i++) {
     
				char d2 = doc2.charAt(i);
				int[] fq = algMap.get(d2);
				if (fq != null && fq.length == 2) {
     
						fq[1]++;
				} else {
     
						fq = new int[2];
						fq[0] = 0;
						fq[1] = 1;
						algMap.put(d2, fq);
				}
		}
		double sqdoc1 = 0;
		double sqdoc2 = 0;
		double denuminator = 0;
		for (Map.Entry entry : algMap.entrySet()) {
     
				int[] c = (int[]) entry.getValue();
				denuminator += c[0] * c[1];
				sqdoc1 += c[0] * c[0];
				sqdoc2 += c[1] * c[1];
		}
		return denuminator / Math.sqrt(sqdoc1 * sqdoc2);
}

体会

这只是比较简单的实现,对比最小编辑距离,貌似余弦向量更适合我的场景。简单的方法速度会快一点,但是这是脱离语义的计算,如果有更高级的场景,可以自行选择分词器,这边是对单个字符的计算

参考

  1. 文本相似度计算_02
    https://segmentfault.com/a/1190000017469294?utm_source=tag-newest

你可能感兴趣的:(java,文本相似度,余弦相似度)