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 ...
随机推荐
- opencart卸载语言包要记得在后台进行设置否则会出错
今天ytkah在一个项目中把中文包卸载了,但是前端购买按钮变为空了,研究了一遍发现要把system - localisation - languages中的对应语言删除才可以.正确的卸载语言步骤是1. ...
- python nose 自写插件打乱class类中用例执行顺序,但将test_a和test_z排除
在使用nose时,有这样一个需求,用例执行打乱,但部分用例因场景原因必须先执行,这类用例在写用例时人为的加上了test_a或test_z字样 网上找了一圈,都没找到合适的方法,只有自己写插件了 已写完 ...
- 12 opencv图像合成
#include < stdio.h > #include < opencv2\opencv.hpp > #include < opencv2\stitching.hpp ...
- Pandas | 13 索引和选择数据
Pandas现在支持三种类型的多轴索引; 编号 索引 描述 1 .loc() 基于标签 2 .iloc() 基于整数 3 .ix() 基于标签和整数 .loc() Pandas提供了各种方法来完成基于 ...
- 将python项目.py文件打包成.exe文件
安装pyinstaller包 pip3 install pyinstaller 如果不行 pip3 install pyinstaller -i https://pypi.doubanio.com/s ...
- 微信小程序 scroll-view 横向滚动条 隐藏无效
看了许多网上教程说是添加如下样式可以解决,我加入到组件wxss中无效,加入全局wxss生效. 添加css代码如下: ::-webkit-scrollbar { ; ; color: transpare ...
- SqlServer 快速查看表结构
--快速查看表结构(比较全面的) THEN obj.name ELSE '' END AS 表名, col.colorder AS 序号 , col.name AS 列名 , ISNULL(ep.[v ...
- IIS 安装 .net core 绑定为 https 使用SSL证书
前提条件: 自己服务器(Windows Server 2016)运行 dotnet .\Web****.dll 服务是可以使用http访问的 但由于实际情况必须使用https 思想历程,但未用: 1. ...
- EmotiW 历年竞赛冠军数据及论文信息
date Baseline paper Champion paper Model & Feature Test_acc 2013 [1] [2] EmoNets 41.03 2014 [3] ...
- Appium Grid并发测试
背景 Selenium玩的比较6的同学比较清楚:在Selenium中三大组件中有包含了Selenium Grid,而其作用就是分布式执行测试用例.主要的应用场景在于: 缩短测试执行时间,提高自动化测试 ...