simhash主要是用于海量数据的去重方面。
和传统的hash的区别
传统hash算法是将原始文本均匀随机映射到一个签名值,传统的hash算法产生两个hash值,对于内容相同的文本在一定概率是相同的;如果不相同,除了说明原始文本不相等之外,不再提供任何信息。即是相差一个字节的内容,产生的hash值也会完全不一样,所以,传统hash只能用来衡量文本是否相同,而不能做相似度的衡量。
simhash就是一种局部敏感hash算法,他产生的hash签名在一定程度上可以表示原始内容的相似度。
我们主要解决的是文本相似度计算,要比较的是两个文章是否相识,当然我们降维生成了hash签名也是用于这个目的。看到这里估计大家就明白了,我们使用的simhash就算把文章中的字符串变成 01 串也还是可以用于计算相似度的,而传统的hash却不行。我们可以来做个测试,两个相差只有一个字符的文本串,“你妈妈喊你回家吃饭哦,回家罗回家罗”
和 “你妈妈叫你回家吃饭啦,回家罗回家罗”
。
通过simhash计算结果为:
1000010010101101111111100000101011010001001111100001001011001011
1000010010101101011111100000101011010001001111100001101010001011
通过传统hash计算为:
0001000001100110100111011011110
1010010001111111110010110011101
大家可以看得出来,相似的文本只有部分 01 串变化了,而普通的hash却不能做到,这个就是局部敏感哈希的魅力。
simhash算法的思想
对于海量的数据去重,需要对去重算法的效率有很高的要求,局部敏感hash算法可以讲原始文本映射为数字(hash签名),在内容相近的文本内容对应的hash签名也比较相近。可以完美解决这个问题。
流程
- 分词,去除stop-words(有时候会做词根stem处理)
- 对单词赋予权值(frequency,or tf-idf)
- 对每个单词计算一个b比特的唯一hash编码值
- 对每个单词的hash值,将0变成-1,然后乘以对应的word的权值
- 对所有的words,按照列进行相加,将和大于0的设置为1,否则设置为0
这样,我们就可以得到每个文本的simhash签名了。
计算相似度
通过hamming distance进行计算。
参考链接: