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 ...
随机推荐
- 查询接口---flask+python+mysql
环境准备 安装flask pip install flask 项目结构如图 1.新建配置文件conf.py #!/usr/bin/python# -*- coding:utf-8 -*- impor ...
- JDBC连接池的九种查询
package JDBC_Demo; import java.sql.SQLException; import java.util.List; import java.util.Map; import ...
- 使用Git管理品优购项目 开始部分
- 前端之CSS(上)
CSS CSS 简介 ## CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染 ...
- 【Linux】Windows终端远程链接Linux服务器
一.Windows cmd ssh链接 1.控制面板->程序->启用Telnet客户端 2.输入命令链接 cmd中输入 ssh 账号名@服务器ip地址:端口号 例如: ssh root@1 ...
- c# 文件夹权限
/// <summary> /// 创建文件路径 /// </summary> /// <param name=" ...
- 【LG2567】[SCOI2010]幸运数字
[LG2567][SCOI2010]幸运数字 题面 洛谷 题目大意: 问你区间\([L,R](1\leq L\leq R\leq 10^{10})\)中有几个数是仅由\(6,8\)组成的数的倍数. 题 ...
- R地图包 maps
安装 maps install.packages(“maps”) 使用 maps library("maps") nz <- map_data("nz")
- Java查询MySQL数据库指定数据库中所有表名、字段名、字段类型、字段长度、字段描述
1,查询方法 public static List<Map<String, String>> getColumnInfoByTableName(String databaseN ...
- Salesforce LWC学习(八) Look Up组件实现
本篇参考https://www.salesforcelwc.in/2019/10/lookup-in-lwc.html,感谢前人种树. 我们做lightning的时候经常会遇到Look up 或者MD ...