加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

余弦相似性获取文章相似度的java实现

发布时间:2020-12-14 03:17:52 所属栏目:大数据 来源:网络整理
导读:转自:http://www.chepoo.com/cosine-similarity-java-implementation.html 文章相似度的实现可以用余弦相似性实现。余弦定理可参考: 余弦定理 字符串之间的相似度实现:字符串相似度算法(编辑距离)java实现 我们可以把它们想象成空间中的两条线段,都是从

转自:http://www.chepoo.com/cosine-similarity-java-implementation.html

文章相似度的实现可以用余弦相似性实现。余弦定理可参考:
余弦定理

字符串之间的相似度实现:字符串相似度算法(编辑距离)java实现

我们可以把它们想象成空间中的两条线段,都是从原点([0,...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫”余弦相似性”。

阮一峰老师写的一篇博文简单明了,大家可以看看:TF-IDF与余弦相似性的应用(二):找出相似文章

实现该算法思路:
1.先用es-ik进行文章分词。
2.得到两篇文章的词频向量
3.计算两个向量的余弦相似度,值越大就表示越相似。

相关代码实现已经github上。具体地址为:https://github.com/awnuxkjy/recommend-system

package com.xq.algorithm;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * <p>Title:</p>
 * <p>Description: 余弦获取文章相似性
 * </p>
 * @createDate:2013-8-26
 * @author xq
 * @version 1.0
 */
public class CosineSimilarAlgorithm {

	/**
	 * 
	* @Title: cosSimilarityByFile
	* @Description: 获取两个文件相似性
	* @param @param firstFile
	* @param @param secondFile
	* @param @return    
	* @return Double   
	* @throws
	 */
	public static Double cosSimilarityByFile(String firstFile,String secondFile){
		try{
			Map<String,Map<String,Integer>> firstTfMap=TfIdfAlgorithm.wordSegCount(firstFile);
			Map<String,Integer>> secondTfMap=TfIdfAlgorithm.wordSegCount(secondFile);
			if(firstTfMap==null || firstTfMap.size()==0){
				throw new IllegalArgumentException("firstFile not found or firstFile is empty! ");
			}
			if(secondTfMap==null || secondTfMap.size()==0){
				throw new IllegalArgumentException("secondFile not found or secondFile is empty! ");
			}
			Map<String,Integer> firstWords=firstTfMap.get(firstFile);
			Map<String,Integer> secondWords=secondTfMap.get(secondFile);
			if(firstWords.size()<secondWords.size()){
				Map<String,Integer> temp=firstWords;
				firstWords=secondWords;
				secondWords=temp;
			}
			return calculateCos((LinkedHashMap<String,Integer>)firstWords,(LinkedHashMap<String,Integer>)secondWords);
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return 0d;
	}
	
	/**
	 * 
	* @Title: cosSimilarityByString
	* @Description: 得到两个字符串的相似性
	* @param @param first
	* @param @param second
	* @param @return    
	* @return Double   
	* @throws
	 */
	public static Double cosSimilarityByString(String first,String second){
		try{
			Map<String,Integer> firstTfMap=TfIdfAlgorithm.segStr(first);
			Map<String,Integer> secondTfMap=TfIdfAlgorithm.segStr(second);
			if(firstTfMap.size()<secondTfMap.size()){
				Map<String,Integer> temp=firstTfMap;
				firstTfMap=secondTfMap;
				secondTfMap=temp;
			}
			return calculateCos((LinkedHashMap<String,Integer>)firstTfMap,Integer>)secondTfMap);
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return 0d;
	}

	/**
	 * 
	* @Title: calculateCos
	* @Description: 计算余弦相似性
	* @param @param first
	* @param @param second
	* @param @return    
	* @return Double   
	* @throws
	 */
	private static Double calculateCos(LinkedHashMap<String,Integer> first,LinkedHashMap<String,Integer> second){
		
		List<Map.Entry<String,Integer>> firstList = new ArrayList<Map.Entry<String,Integer>>(first.entrySet());
		List<Map.Entry<String,Integer>> secondList = new ArrayList<Map.Entry<String,Integer>>(second.entrySet());
		//计算相似度  
        double vectorFirstModulo = 0.00;//向量1的模  
        double vectorSecondModulo = 0.00;//向量2的模  
        double vectorProduct = 0.00; //向量积  
        int secondSize=second.size();
		for(int i=0;i<firstList.size();i++){
			if(i<secondSize){
				vectorSecondModulo+=secondList.get(i).getValue().doubleValue()*secondList.get(i).getValue().doubleValue();
				vectorProduct+=firstList.get(i).getValue().doubleValue()*secondList.get(i).getValue().doubleValue();
			}
			vectorFirstModulo+=firstList.get(i).getValue().doubleValue()*firstList.get(i).getValue().doubleValue();
		}
	   return vectorProduct/(Math.sqrt(vectorFirstModulo)*Math.sqrt(vectorSecondModulo));
	}
	
	public static void main(String[] args){
		Double result=cosSimilarityByString("中国是超级大国","中国是世界超级大国。");
		System.out.println(result);
	}
}



文固定链接:?http://www.chepoo.com/cosine-similarity-java-implementation.html | IT技术精华网

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读