余弦方法计算相似度算法--Python实现 Java实现

(1)余弦相似性 

          通过测量两个向量之间的角的余弦值来度量它们之间的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。所以,它通常用于文件比较。

          详见百科介绍(点击打开链接

(2)算法实现的中未使用权重(IDF ---逆文档频率),使用词项的出现次数作为向量空间的值。

python实现


#!usr/bin/evn python
#! -*- coding:utf8 -*-
from __future__ import division
import re
from math import sqrt

class Similarity(object):
    def __init__(self, target1, target2):
        self.target1 = target1
        self.target2 = target2

    def vector(self):
        self.vdict1 = {}
        self.vdict2 = {}
        for target in re.findall('([a-zA-Z0-9_.&%]+)+', self.target1):
            self.vdict1[target] = self.vdict1.get(target, 0) + 1
        for target in re.findall('([a-zA-Z0-9_.&%]+)+', self.target2):
            self.vdict2[target] = self.vdict2.get(target, 0) + 1
        print self.vdict1
        print self.vdict2

    def mix(self):
       # def mapminmax(vdict):
       #    _min = min(vdict.values())
       #    _max = max(vdict.values())
       #    _mid = _max - _min
       #    print _min, _max, _mid
       #    for key in vdict:
       #         vdict[key] = (vdict[key] - _min)/_mid
       #    return vdict
       
        for key in self.vdict1:
            self.vdict2[key] = self.vdict2.get(key, 0)
        for key in self.vdict2:
            self.vdict1[key] = self.vdict1.get(key, 0)
            
        print self.vdict1
        print self.vdict2   
        
      #  self.vdict1 = mapminmax(self.vdict1)
      #  self.vdict2 = mapminmax(self.vdict2)

    def similar(self):
        self.vector()
        self.mix()
        sum = 0
        for key in self.vdict1:
            sum += self.vdict1[key] * self.vdict2[key]
        A = sqrt(reduce(lambda x,y: x+y, map(lambda x: x*x, self.vdict1.values())))
        B = sqrt(reduce(lambda x,y: x+y, map(lambda x: x*x, self.vdict2.values())))
        return sum/(A*B)

if __name__ == '__main__':
    t1 = "aa bb cc"
    t2 = "aa bb ee"
    s = Similarity(t1, t2)
    print s.similar()
    

--------------------------------------------------------------------------------------------------------------------------

Java实现

[java]  view plain  copy
  1. import java.util.HashMap;  
  2. import java.util.Iterator;  
  3. import java.util.Map;  
  4.   
  5. public class SimilarDegreeByCos  
  6. {  
  7.     /* 
  8.      * 计算两个字符串(英文字符)的相似度,简单的余弦计算,未添权重 
  9.      */  
  10.      public static double getSimilarDegree(String str1, String str2)  
  11.      {  
  12.         //创建向量空间模型,使用map实现,主键为词项,值为长度为2的数组,存放着对应词项在字符串中的出现次数  
  13.          Map<String, int[]> vectorSpace = new HashMap<String, int[]>();  
  14.          int[] itemCountArray = null;//为了避免频繁产生局部变量,所以将itemCountArray声明在此  
  15.            
  16.          //以空格为分隔符,分解字符串  
  17.          String strArray[] = str1.split(" ");  
  18.          for(int i=0; i<strArray.length; ++i)  
  19.          {  
  20.              if(vectorSpace.containsKey(strArray[i]))  
  21.                  ++(vectorSpace.get(strArray[i])[0]);  
  22.              else  
  23.              {  
  24.                  itemCountArray = new int[2];  
  25.                  itemCountArray[0] = 1;  
  26.                  itemCountArray[1] = 0;  
  27.                  vectorSpace.put(strArray[i], itemCountArray);  
  28.              }  
  29.          }  
  30.            
  31.          strArray = str2.split(" ");  
  32.          for(int i=0; i<strArray.length; ++i)  
  33.          {  
  34.              if(vectorSpace.containsKey(strArray[i]))  
  35.                  ++(vectorSpace.get(strArray[i])[1]);  
  36.              else  
  37.              {  
  38.                  itemCountArray = new int[2];  
  39.                  itemCountArray[0] = 0;  
  40.                  itemCountArray[1] = 1;  
  41.                  vectorSpace.put(strArray[i], itemCountArray);  
  42.              }  
  43.          }  
  44.            
  45.          //计算相似度  
  46.          double vector1Modulo = 0.00;//向量1的模  
  47.          double vector2Modulo = 0.00;//向量2的模  
  48.          double vectorProduct = 0.00//向量积  
  49.          Iterator iter = vectorSpace.entrySet().iterator();  
  50.            
  51.          while(iter.hasNext())  
  52.          {  
  53.              Map.Entry entry = (Map.Entry)iter.next();  
  54.              itemCountArray = (int[])entry.getValue();  
  55.                
  56.              vector1Modulo += itemCountArray[0]*itemCountArray[0];  
  57.              vector2Modulo += itemCountArray[1]*itemCountArray[1];  
  58.                
  59.              vectorProduct += itemCountArray[0]*itemCountArray[1];  
  60.          }  
  61.            
  62.          vector1Modulo = Math.sqrt(vector1Modulo);  
  63.          vector2Modulo = Math.sqrt(vector2Modulo);  
  64.            
  65.          //返回相似度  
  66.         return (vectorProduct/(vector1Modulo*vector2Modulo));  
  67.      }  
  68.        
  69.      /* 
  70.       *  
  71.       */  
  72.      public static void main(String args[])  
  73.      {  
  74.          String str1 = "gold silver truck";  
  75.          String str2 = "Shipment of gold damaged in a fire";  
  76.          String str3 = "Delivery of silver arrived in a silver truck";  
  77.          String str4 = "Shipment of gold arrived in a truck";  
  78.          String str5 = "gold gold gold gold gold gold";  
  79.            
  80.          System.out.println(SimilarDegreeByCos.getSimilarDegree(str1, str2));  
  81.          System.out.println(SimilarDegreeByCos.getSimilarDegree(str1, str3));  
  82.          System.out.println(SimilarDegreeByCos.getSimilarDegree(str1, str4));  
  83.          System.out.println(SimilarDegreeByCos.getSimilarDegree(str1, str5));  
  84.      }  
  85. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值