SimHash算法

SimHash算法可计算文本间的相似度,实现文本去重。文本相似度的计算,可以使用向量空间模型(VSM),即先对文本分词,提取特征,根据特征建立文本向量,把文本之间相似度的计算转化为特征向量距离的计算,如欧式距离、余弦夹角等。但这样做的缺点是复杂度会很高。

基于VSM的文本相似度计算,对于小量数据处理是可以的,但对于百度,google这样的搜索引擎,爬虫每天爬取的网页数目大得惊人,为了防止网页的重复,需要进行判重处理。对于这样的数据,VSM无能为力,google提出了SimHash算法,大大减少了计算量。具体步骤如下

1. 输入一个 N 维的文本特征向量 V ,每个特征具有一定权重。 
2. 初始化一个 C 维的向量 Q ,初始值均为0, C 位二进制签名 S 为0。 
3. 对于向量 V 的每个特征,使用hash算法计算出一个 C 位的散列值 H 。 
4. 对任意 i\in[1,C] ,若H 第 i 位为1,则 Q 的第 i 维加该特征的权重,否则减。 
5. 若最终 Q 的第 i 维元素大于0,则 S 的第 i 维为1,否则为0。 
6. 最终这个 C 维的二进制签名 S 就是该文本的二进制签名。

算法流程如下

每篇文档算出签名S后,再计算两个签名的海明距离,海明距离是这两个二进制数异或后1的个数。根据经验,对于64位的SimHash,海明距离在3以内的都可以认为相似度比较高,认为这两个文档基本相同。以64位的签名来说,把它以每16位划分块,如果两个签名海明距离小于等于3,则至少有一个16位块完全相同。但是我们不知道具体是哪两个块相同,所以要进行枚举,这里只需要枚举4次。问题抽象如下

有10亿个不重复的64位01串,给定一个64位的01串,如何快速从这10亿个串中找出与给定串的海明距离小于等于3的字符串。

以8位数字签名01100011说明。划分为4块,每块两位,即01 10 00 11,然后在所有8位二进制签名中分别查找以01,10,00,11开始的签名。在所有的8位二进制签名中,按前两位进行索引,例如把01000000和01111111放在一个簇中,若找不到以01,10,00,11开始的二进制签名,说明海明距离肯定大于3,这样就直接可以判断这两个文本不相似,否则再比较后面的部分,大大减少计算量。

凯哥推荐:

lelouchcr's blog

simhash针对文本的话,k值敏感,一般选取3。认为汉明距离小于3的文本是相似的。

缺点:完全无关的文本正好对应成了相同的simhash,精确度并不是很高,而且simhash更适用于较长的文本,但是在大规模语料进行去重时,simhash的计算速度优势还是很不错的。

短文本相似度计算:python 中的hash - CSDN博客

simhash简单明了的一篇博文:simhash Java和Python版本的实现 - CSDN博客

NLP点滴--文本相似度,计算文本间的距离 - CSDN博客

simhash调用包:python文本去重方法:simhash

A Python Implementation of Simhash Algorithm

文本相似度的几种方法的对比:短文本相似度度量 - CSDN博客

基于LDA模型以及TF-IDF模型的文本相似度计算:

pythonNLP-文本相似度计算实验汇总 - CSDN博客

吳YH堅:推荐系统技术文本相似性计算(三)实战篇​zhuanlan.zhihu.com图标

TF-IDF:转:Python 文本挖掘:使用gensim进行文本相似度计算

转自知乎:

https://zhuanlan.zhihu.com/p/36266622

https://zhuanlan.zhihu.com/p/32078737

猜你喜欢

转载自blog.csdn.net/qq_38150441/article/details/81841508