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

el/2024/7/17 22:18:48

(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. }  

http://www.ngui.cc/el/5557106.html

相关文章

Python与shell交互os.system、 os.popen、 subprocess

这篇文章主要介绍了Python与shell的3种交互方式介绍,本文讲解了 os.system、 os.popen、 subprocess 模块等3种方法,需要的朋友可以参考下。 问题概述 考虑这样一个问题&#xff0c;有hello.py脚本&#xff0c;输出”hello, world!”&#xff1b;有TestInput.py脚本&#…

浏览器页面的缓存设置(不缓存设置)

HTML的HTTP协议头信息中控制着页面在几个地方的缓存信息&#xff0c;包括浏览器端&#xff0c;中间缓存服务器端(如&#xff1a;squid等)&#xff0c;Web服务器端。本文讨论头信息 中带缓存控制信息的HTML页面(JSP/Servlet生成好出来的也是HTML页面)在中间缓存服务器中的缓存情…

信号、信号量、进程的状态的区别你知道吗?

信号量(Semaphore)&#xff0c;有时被称为信号灯&#xff0c;是在多环境下使用的一种设施&#xff0c;是可以用来保证两个或多个关键代码段不被并发调用。 在进入一个关键代码段之前&#xff0c;线程必须获取一个信号量&#xff1b;一旦该关键代码段完成了&#xff0c;那么该线…

网关的作用(两个内网主机通信原理)

网关是一种充当转换重任的计算机系统或设备。在使用不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间&#xff0c;网关是一个翻译器。与网桥只是简单地传达信息不同&#xff0c;网关对收到的信息要重新打包&#xff0c;以适应目的系统的需求。同时&#xff…

python中 if __name__ == '__main__': 的解析

当你打开一个.py文件时,经常会在代码的最下面看到 if __name__ __main__: ,现在就来介绍一下它的作用. 模块是对象&#xff0c;并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值取决于您如何应用模块。&#xff08; 1 &#xff09;如果 import 一个模块&a…

正则表达式 学习手册三

javascript表达式举例: 举例&#xff1a;匹配IP地址 100.4.5.6 var reg /^ ( (?: (?: 25[0-5] | 2[0-4] \d | ( (1\d{2}) |([1-9]?\d)) ) \. ) {3} (?:25[0-5]|2[0-4] \d | ( (1\d{2}) | ([1-9]?\d) ) ) ) $/; if (!reg.test($(#master).val())) …

区块链技术介绍----分布式总帐

区块链(Blockchain)是比特币的底层技术&#xff0c;像一个数据库账本&#xff0c;记载所有的交易记录。这项技术也因其安全、便捷的特性逐渐得到了银行与金融业的关注。 ​区块链(Blockchain)是比特币的一个重要概念&#xff0c;区块链是一串使用密码学方法相关联产生的数据块&…

正则表达式 高级规则——四(贪婪与非贪婪)

匹配次数中的贪婪与非贪婪 在使用修饰匹配次数的特殊符号时&#xff0c;有几种表示方法可以使同一个表达式能够匹配不同的次数&#xff0c;比如&#xff1a;"{m,n}", "{m,}", "?", "*",""&#xff0c;具体匹配的次数随被匹…

正则表达式高级用法---五(反向引用 /1, /2...)

反向引用 /1, /2... 表达式在匹配时&#xff0c;表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候&#xff0c;小括号包含的表达式所匹配到的字符串可以单独获取。这一点&#xff0c;在前面的举例中&#xff0c;已经多次展示…

正则表达式---六(其他通用规则)

还有一些在各个正则表达式引擎之间比较通用的规则&#xff0c;在前面的讲解过程中没有提到。 4.1 规则一 表达式中&#xff0c;可以使用 "/xXX" 和 "/uXXXX" 表示一个字符&#xff08;"X" 表示一个十六进制数&#xff09; 形式 …