(转)simhash算法原理及实现
simhash是google用來處理海量文本去重的算法。 google出品,你懂的。 simhash最牛逼的一點就是將一個文檔,最后轉(zhuǎn)換成一個64位的字節(jié),暫且稱之為特征字,然后判斷重復(fù)只需要判斷他們的特征字的距離是不是<n(根據(jù)經(jīng)驗這個n一般取值為3),就可以判斷兩個文檔是否相似。
原理
simhash值的生成圖解如下:
大概花三分鐘看懂這個圖就差不多怎么實現(xiàn)這個simhash算法了。特別簡單。谷歌出品嘛,簡單實用。
算法過程大概如下:
將Doc進行關(guān)鍵詞抽取(其中包括分詞和計算權(quán)重),抽取出n個(關(guān)鍵詞,權(quán)重)對, 即圖中的(feature, weight)們。 記為feature_weight_pairs = [fw1, fw2 ... fwn],其中fwn = (feature_n, weight_n)。
hash_weight_pairs = [ (hash(feature), weight) for feature, weight in feature_weight_pairs ]生成圖中的(hash,weight)們, 此時假設(shè)hash生成的位數(shù)bits_count = 6(如圖);
然后對hash_weight_pairs進行位的縱向累加,如果該位是1,則+weight,如果是0,則-weight,最后生成bits_count個數(shù)字,如圖所示是[13, 108, -22, -5, -32, 55], 這里產(chǎn)生的值和hash函數(shù)所用的算法相關(guān)。
[13,108,-22,-5,-32,55] -> 110001這個就很簡單啦,正1負0。
到此,如何從一個doc到一個simhash值的過程已經(jīng)講明白了。 但是還有一個重要的部分沒講,
simhash值的海明距離計算
二進制串A 和 二進制串B 的海明距離 就是A xor B后二進制中1的個數(shù)。
舉例如下:
A = 100111;
B = 101010;
hamming_distance(A, B) = count_1(A xor B) = count_1(001101) = 3;
當我們算出所有doc的simhash值之后,需要計算doc A和doc B之間是否相似的條件是:
A和B的海明距離是否小于等于n,這個n值根據(jù)經(jīng)驗一般取值為3,
simhash本質(zhì)上是局部敏感性的hash,和md5之類的不一樣。 正因為它的局部敏感性,所以我們可以使用海明距離來衡量simhash值的相似度。
高效計算二進制序列中1的個數(shù)
/* src/Simhasher.hpp */
bool isEqual(uint64_t lhs, uint64_t rhs, unsigned short n = 3)
{
unsigned short cnt = 0;
lhs ^= rhs;
while(lhs && cnt <= n)
{
lhs &= lhs - 1;
cnt++;
}
if(cnt <= n)
{
return true;
}
return false;
}
由上式這個函數(shù)來計算的話,時間復(fù)雜度是 O(n); 這里的n默認取值為3。由此可見還是蠻高效的。
simhash實現(xiàn)的工程項目
我自己寫的simhash
主要是針對中文文檔,也就是此項目進行simhash之前同時還進行了分詞和關(guān)鍵詞的抽取。
對比其他算法
百度的去重算法
百度的去重算法最簡單,就是直接找出此文章的最長的n句話,做一遍hash簽名。n一般取3。 工程實現(xiàn)巨簡單,據(jù)說準確率和召回率都能到達80%以上。
shingle算法
shingle原理略復(fù)雜,不細說。 shingle算法我認為過于學(xué)院派,對于工程實現(xiàn)不夠友好,速度太慢,基本上無法處理海量數(shù)據(jù)。
其他算法
具體看微博上的討論
參考
Similarity estimation techniques from rounding algorithms
simhash與Google的網(wǎng)頁去重
海量數(shù)據(jù)相似度計算之simhash和海明距離
總結(jié)
以上是生活随笔為你收集整理的(转)simhash算法原理及实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让手机打开网页显示跟电脑上一样如何让
- 下一篇: windows下如何查看和修改MySQL