SimHash算法可计算文本间的相似度,实现文本去重。文本相似度的计算,可以使用向量空间模型(VSM),即先对文本分词,提取特征,根据特征建立文本向量,把文本之间相似度的计算转化为特征向量距离的计算,如欧式距离、余弦夹角等。但这样做的缺点是复杂度会很高。
基于VSM的文本相似度计算,对于小量数据处理是可以的,但对于百度,google这样的搜索引擎,爬虫每天爬取的网页数目大得惊人,为了防止网页的重复,需要进行判重处理。对于这样的数据,VSM无能为力,google提出了SimHash算法,大大减少了计算量。具体步骤如下
1. 输入一个 维的文本特征向量 ,每个特征具有一定权重。
2. 初始化一个 维的向量 ,初始值均为0, 位二进制签名 为0。
3. 对于向量 的每个特征,使用hash算法计算出一个 位的散列值 。
4. 对任意 ,若 第 位为1,则 的第 维加该特征的权重,否则减。
5. 若最终 的第 维元素大于0,则 的第 维为1,否则为0。
6. 最终这个 维的二进制签名 就是该文本的二进制签名。
算法流程如下
每篇文档算出签名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,这样就直接可以判断这两个文本不相似,否则再比较后面的部分,大大减少计算量。
凯哥推荐:
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进行文本相似度计算
转自知乎:
来源:CSDN
作者:会飞的小罐子
链接:https://blog.csdn.net/qq_38150441/article/details/81841508