SimHash算法--文章相似度匹配
SimHash原理
1.SimHash背景
- SimHash算法来自于 GoogleMoses Charikar发表的一篇论文“detecting near-duplicates for web crawling” ,其主要思想是降维, 将高维的特征向量映射成低维的特征向量,通过两个向量的Hamming Distance(汉明距离)来确定文章是否重复或者高度近似。
- Hamming Distance: 又称汉明距离,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。也就是说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:1011101 与 1001001 之间的汉明距离是 2(异或)。至于我们常说的字符串编辑距离则是一般形式的汉明距离。这样通过比较文档之间simHash值的汉明距离,可以获取他们相似度。
2.如何比较两篇文章相似度呢?
- 方法1:通过分词(这里用到jieba),得到一系列特征向量, 然后计算特征向量之间的距离(可以计算它们之间的欧氏距离、海明距离或者夹角余弦等等),从而通过距离的大小来判断两篇文章的相似度。
- 方法2: 另外一种方案是传统hash,我们考虑为每一个web文档通过hash的方式生成一个指纹 (finger print)。
3.实现流程
- 分词:对一段语句,进行分词,得到有效特征向量,然后给每一个特征向量设置1-5个级别代表权重(如果给定是一个文本特征向量可以通过TF-IDF)。
- hash:通过hash函数计算各个特征向量的hash值。hash值为二进制数0 1 组成的n-bit签名。比如 “茶壶”的hash值为100101,“饺子”的hash值为101011.
- 加权:在hash值的基础上,给所有特征向量进行加权,即
W = Hash * weight,且遇到1则hash值和权值正相乘,遇到0则hash值和权值负相乘。例如给“茶壶”的hash值“100101”加权得 到:W= 100101*4 = 4 -4 -4 4 -4 4,给“饺子”的hash值“101011”加权得到:W=101011*5 = 5 -5 5 -5 5 5,其余特征向量类似此般操作。 - 合并: 将上述各个特征向量的加权结果累加,变成只有一个序列串。拿前两个特征向量举例,例如“茶壶”的“4 -4 -4 4 -4 4”和“饺子”的“5 -5 5 -5 5 5”进行累加,得到“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”,得到“9 -9 1 -1 1”。
- 降维:对于n-bit签名的累加结果,如果大于0则置1,否则置0,从而得到该语句的simhash值,最后我们便可以根据不同语句simhash的海 明距离来判断它们的相似度。例如把上面计算出来的“9 -9 1 -1 1 9”降维(某位大于0记为1,小于0记为0),得到的01串为:“1 0 1 0 1 1”,从而形成它们的simhash签名。

4.python代码中的实现:
import json
import jieba
import jieba.analyse
import numpy as np
class Simhash(object):
def simhash(self,content):
keylist = []
#jieba分词
seg = jieba.cut(content)
#去除停用词永祥
jieba.analyse.set_stop_words("stopwords.txt")
#得到前20个分词和tf-idf权值
keywords = jieba.analyse.extract_tags("|".join(seg),topK=20,withWeight=True,allowPOS=())
a = 0
for feature,weight in keywords:
weight = int(weight * 20)
feature = self.string_hash(feature)
temp = []
for i in feature:
if i == "1":
temp.append(weight)
else:
temp.append(-1*weight)
keylist.append(temp)
list1 = np.sum(np.array(keylist),axis=0)
if keylist == []:
return "00"
simhash = ""
#降维处理
for i in list1:
if i>0:
simhash += "1"
else:
simhash += "0"
return simhash
def string_hash(self,source):
if source == "":
return 0
else:
x = ord(source[0]) << 7
m = 1000003
mask = 2 ** 128 - 1
for c in source:
x = ((x * m) ^ ord(c)) & mask
x ^= len(source)
if x == -1:
x = -2
x = bin(x).replace('0b', '').zfill(64)[-64:]
return str(x)
# x=str(bin(hash(source)).replace('0b','').replace('-','').zfill(64)[-64:])
# return x
- 相似度比较
def hammingDis(s1,s2):
t1 = "0b" + s1
t2 = "0b" + s2
n = int(t1,2) ^ int(t2,2)
i = 0
while n:
n &= (n-1)
i += 1
print(i)
if i <= 18:
print("文本相似")
else:
print("文本不相似")
if __name__ == "__main__":
text1 = open("article1.txt","r",encoding="utf-8")
text2 = open("article2.txt","r",encoding="utf-8")
hammingDis(text1,text2)
text1.close()
text2.close()
5. simhash 模块
simhash算法的主要思想是降维,将高维的特征向量映射成一个f-bit的指纹(fingerprint),通过比较两篇文章的f-bit指纹的Hamming Distance来确定文章是否重复或者高度近似。
下载
pip install simhash
代码实现
from simhash import Simhash
def simhash_similarity(text1,text2):
a_simhash = Simhash(text1)
b_simhash = Simhash(text2)
print(a_simhash.value)
print(b_simhash.value)
max_hashbit = max(len(bin(a_simhash.value)),len(bin(b_simhash.value)))
print(max_hashbit) #汉明距离
distince = a_simhash.distance(b_simhash)
print(distince)
similar = distince/max_hashbit
return similar
if __name__ == "__main__":
text1 = open("article1.txt","r",encoding="utf-8")
text2 = open("article2.txt","r",encoding="utf-8")
similar=simhash_similarity(text1,text2)
#相相似度
print(similar)
text1.close()
text2.close()
源码展示:github代码
参考资料:
SimHash算法--文章相似度匹配的更多相关文章
- 彻底弄懂LSH之simHash算法
马克·吐温曾经说过,所谓经典小说,就是指很多人希望读过,但很少人真正花时间去读的小说.这种说法同样适用于“经典”的计算机书籍. 最近一直在看LSH,不过由于matlab基础比较差,一直没搞懂.最近看的 ...
- 基于局部敏感哈希的协同过滤算法之simHash算法
搜集了快一个月的资料,虽然不完全懂,但还是先慢慢写着吧,说不定就有思路了呢. 开源的最大好处是会让作者对脏乱臭的代码有羞耻感. 当一个做推荐系统的部门开始重视[数据清理,数据标柱,效果评测,数据统计, ...
- 海量数据去重之SimHash算法简介和应用
SimHash是什么 SimHash是Google在2007年发表的论文<Detecting Near-Duplicates for Web Crawling >中提到的一种指纹生成算法或 ...
- 字符串匹配算法之SimHash算法
SimHash算法 由于实验室和互联网基本没啥关系,也就从来没有关注过数据挖掘相关的东西.在实际工作中,第一次接触到匹配和聚类等工作,虽然用一些简单的匹配算法可以做小数据的聚类,但数据量达到一定的时候 ...
- 浅谈压缩感知(二十八):压缩感知重构算法之广义正交匹配追踪(gOMP)
主要内容: gOMP的算法流程 gOMP的MATLAB实现 一维信号的实验与结果 稀疏度K与重构成功概率关系的实验与结果 一.gOMP的算法流程 广义正交匹配追踪(Generalized OMP, g ...
- 浅谈压缩感知(二十五):压缩感知重构算法之分段正交匹配追踪(StOMP)
主要内容: StOMP的算法流程 StOMP的MATLAB实现 一维信号的实验与结果 门限参数Ts.测量数M与重构成功概率关系的实验与结果 一.StOMP的算法流程 分段正交匹配追踪(Stagewis ...
- MLlearning(2)——simHash算法
这篇文章主要讲simHash算法.这是一种LSH(Locality-Sensitive Hashing,局部敏感哈希)的简单实现.它是广泛用于数据去重的算法,可以用于相似网站.图片的检索.而且当两个样 ...
- (转)simhash算法原理及实现
simhash是google用来处理海量文本去重的算法. google出品,你懂的. simhash最牛逼的一点就是将一个文档,最后转换成一个64位的字节,暂且称之为特征字,然后判断重复只需要判断他们 ...
- 浅谈压缩感知(二十三):压缩感知重构算法之压缩采样匹配追踪(CoSaMP)
主要内容: CoSaMP的算法流程 CoSaMP的MATLAB实现 一维信号的实验与结果 测量数M与重构成功概率关系的实验与结果 一.CoSaMP的算法流程 压缩采样匹配追踪(CompressiveS ...
随机推荐
- Python 字符串内置方法笔记
一. 大小写转换 ① capitalize() capitalize() #字符串首字母大写 >>> str0 = 'hello World' >>> str0.c ...
- 洛谷P3835 【模板】可持久化平衡树(FHQ Treap)
题面 传送门 题解 可持久化一下就好了,具体可以看代码 这里有一个小\(trick\)就是我们原本在\(merge\)的时候也要新建节点的,但是我们\(merge\)之前一般已经\(split\)过了 ...
- Random Access Iterator 徐州网络赛(树形dp)
Random Access Iterator \[ Time Limit: 4000 ms \quad Memory Limit: 262144 kB \] 题意 给出伪代码,问按着伪代码在树上跑,能 ...
- Scrapy的中间件(一)
中间件是Scrapy里面的一个核心概念.使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫. "中间件"这个中文名字和前面章节讲到 ...
- ERP(Enterprise Resource Planning,企业资源计划)
企业资源计划或称企业资源规划简称ERP(Enterprise Resource Planning),由美国著名管理咨询公司Gartner Group Inc.于1990年提出来的,最初被定义为应用软件 ...
- Oracle客户端和服务端菜单区别
- 2019年底前的web前端面试题初级-web标准应付HR大多面试问题
作者 | Jeskson来源 | 达达前端小酒馆 问:你知道在css中,html的标签元素分多少中不同的类型吗? 答:大体可分三种:1,块状元素,2,内联元素,3,内联块状元素 块级元素:就是每个块级 ...
- js 判断字符串是否为空或是否全为空格
判断字符串是否为空 if (str == "") { } 判断字符串是否为空且不能全为空格 if (str.match(/^[ ]*$/)) { } 第二种方式不仅可以校验空格 ...
- JSON Template
public java.lang.String toString() {#if ( $members.size() > 0 ) #set ( $i = 0 )return "{\&qu ...
- storm杂记+性能调优
1.默认情况下: 1个supervisor节点启动4个worker进程. 每一个topology默认占用一个worker进程. 每个worker会启动executor. 每个executor默认启动一 ...