使用simhash算法對網頁去重


本文轉載自:http://www.lai18.com/content/2095944.html

如果搜索文檔有很多重復的文本,比如一些文檔是轉載的其他的文檔,只是布局不同,那么就需要把重復的文檔去掉,一方面節省存儲空間,一方面節省搜索時間,當然搜索質量也會提高。 

simhash是google用來處理海量文本去重的算法。

[b]1. 原理:[/b]

simhash將一個文檔轉換成一個64位的字節,暫且稱之為簽名值,然后判斷兩篇文檔的簽名值的距離是不是小於等於n(根據經驗這個n一般取值為3),就可以判斷兩個文檔是否相似。

[b]2. simhash和傳統的hash算法有什么不同?[/b]

simhash和傳統的hash都可以將文檔轉換為一個簽名值,它們有什么不同呢? 

simhash基於局部敏感哈希框架,即如果兩個文檔內容越相似,則其對應的兩個哈希值也越接近,所以就可以將文本內容相似性問題轉換為哈希值的相近性問題。 

而傳統的hash算法只負責將原始內容盡量均勻隨機地映射為一個簽名值,原理上相當於偽隨機數產生算法。產生的兩個簽名,如果相等,說明原始內容在一定概率下是相等的;如果不相等,除了說明原始內容不相等外,不再提供任何信息,因為即使原始內容只相差一個字節,所產生的簽名也很可能差別極大。而simhash的簽名值除了提供原始內容是否相等的信息外,還能額外提供不相等的原始內容的差異程度的信息。

[b]3. simhash算法步驟描述:[/b]

simhash算法步驟見下圖: 




1)首先從文檔內容中抽取n個能表征文檔的特征,至於具體實現,則可以采用不同的抽取方法,經過此步驟,獲得文檔的特征詞及其權值對,即圖中的n個(feature,weight)。方法之一可以參考 使用向量空間模型(df-idf)計算搜索文檔與查詢詞的相關性中的(6)使用TF*IDF框架提取文檔和用戶查詢的特征詞及其權重。 

2)利用一個哈希函數將每個特征詞映射成bit_count位的二進制數值。圖中所示算法將每個特征詞轉換為了bit_count=6的二進制數值,這樣每個(feature,weight)就轉換為圖中的(hash,weight)了。 

3)利用權重改寫特征的二進制hash值,將權重融入其中,將bit_count位的二進制數值改寫為bit_count個實數,形成一個實數向量。假設某個特征的權值是w,則對二進制向量做如下改寫:如果二進制的某個比特位是數值1,則實數向量中對應位置改寫為數值w;如果比特位數值為0,則實數向量中對應位置改寫為數值-w,即權值的負數。通過以上規則,就將bit_count的二進制數改為了特征權重的實數向量。 

4)當n個特征都進行了上述改寫后,對所有特征的實數向量累加獲得一個代表文檔整體的實數向量。累加規則也很簡單,就是將對應位置的數值累加即可。 

5)再次將實數向量轉換為bit_count位的二進制數值。轉換規則如下:如果對應位置的數值大於0,則設置為二進制數字1;如果小於等於0,則設置為二進制數字0。如此就得到了文檔的信息指紋,即最終的simhash值。 

上圖將文檔特征詞hash為6位的二進制數值,在實際計算中,往往會將長度設定為64,即每個文檔轉換為64比特的simhash值。

[b]4. 利用simhash對文檔去重[/b]

將文檔轉換為simhash值后,如何利用simhash值比較兩個文檔的相似性呢?對於兩個文檔A和B,其內容相似性可以通過比較simhash值的差異來體現,內容越相似,則二進制數值對應位置的相同的0或者1越多,兩個二進制數值不同的二進制位數稱為“海明距離”(也就是兩個二進制數值xor 后二進制中1的個數)。 

舉例如下:

[code]A = 100111;
B = 101010;
hamming_distance(A, B) = count_1(A xor B) = count_1(001101) = 3;


當我們算出所有文檔的simhash值之后,需要計算文檔 A和文檔 B之間是否相似的條件是:
A和B的海明距離是否小於等於n
。 

一般對於64位二進制數來說,判斷兩個文檔是否近似重復的標准是:海明距離是否小於等於3,如果兩個文檔的二進制數值小於等於3位不同,則判定為近似重復文檔。

[b]5. simhash的c++實現: [/b]

1) https://github.com/yanyiwu/simhash  (讀過) 

2) https://github.com/seomoz/simhash-cpp  (未讀) 

兩者將字符串hash為64位數都是使用
jenkins hash


[b]6. 處理海量文檔 [/b]

1)利用hash查找海量simhash(一)  

海量的網頁經過上述步驟,轉換為海量的二進制數值,此時如果新抓取到一個網頁,如何找出近似重復的內容呢? 

一個很容易想到的方式是一一匹配,將新網頁轉換為64比特的二進制數值,之后和所有網頁的simhash一一比較,如果兩者的海明距離小於等於3,則可以認為是近似重復網頁。這種方法雖然直觀,但是計算量過大,所以在以億計的網頁中,實際是不太可行的。 

假設我們要尋找海明距離3以內的數值,根據抽屜原理,只要我們將整個64位的二進制串划分為4塊,無論如何,匹配的兩個simhash之間至少有一塊區域是完全相同的,所以我們可以借鑒hash查找的方法,把這一區域的數值作為key,先找到哪些simhash的key等於目標simhash的key,然后在這些simhash集合中查找那些海明距離在3以內的數值。 

這就要求我們在存儲simhash時,需要把key相同的simhash存儲在一起。 

但又因為我們無法事先得知完全相同的是哪一塊區域,所以四個區域的每個區域都應該作為我們查找value的key值。 

具體做法如下: 




存儲: 

1)將64位的simhash code平均分成4個區域,每個區域都有16bit。(圖上紅色的16位) 

2)分別以4個16位二進制碼作為key,查找該key對應位置上是否有元素。(放大后的16位) 

3)對應位置沒有元素,直接追加到鏈表上;對應位置有則直接追加到鏈表尾端。(圖上的 S1 — SN) 

查找: 

1)將需要比較的simhash code拆分成4個16位的二進制碼。 

2)分別以4個16位二進制碼作為key,查找simhash集合每個key對應位置上是否有元素。 

3)如果有元素,則把鏈表拿出來順序查找比較,查找那些海明距離小於3的數值,整個過程完成。 

2)空間和時間開銷(一)  

這種方法,由於每個hashcode最多有4個key(顯然如果有兩個區域的code值相同,則key小於4個),每個key都要存儲一遍,所以需要的空間是原來的4倍。但每個key對應的simhash平均數量變為simhash數量總和的1/2161/2^{16},所以搜索時間是一一搜索的4216\frac{4}{2^{16}}。 

3)利用hash查找海量simhash(二)  

假設我們還是要尋找海明距離3以內的數值,如果我們要把4個區域變成5個區域,所花的空間和時間又變成多少呢? 

因為根據抽屜原理,如果分成5個區域,則至少有兩個區域是完全相同的,所以需要將這兩塊區域的值作為key,查找時先找到哪些simhash的key等於目標simhash的key,然后在這些simhash集合中查找那些海明距離在3以內的數值。 

究竟是哪兩塊區域相同共有C25C_5^2=10種情況,所以兩個區域組成的這10個key都應該作為我們查找value的key值。 

具體做法如下: 

存儲: 

1)將64位的simhash code分成5個區域,每個區域分別有13 13 13 13 12位。 

2)分別以10種26位(13+13)或25位(13+12)二進制碼作為key,查找該key對應位置上是否有元素 

3)對應位置沒有元素,直接追加到鏈表上;對應位置有則直接追加到鏈表尾端 

查找: 

1)將需要比較的simhash code分成5個區域,每個區域分別有13 13 13 13 12位。 

2)分別以10種26位(13+13)或25位(13+12)二進制碼作為key,查找simhash集合對應key位置上是否有元素。 

3)如果有元素,則把鏈表拿出來順序查找比較,查找那些海明距離小於3的數值,整個過程完成。 

4)空間和時間開銷(二)  

這種方法,由於每個hashcode最多有10個key,每個key都要存儲一遍,所以需要的空間是原來的10倍。但每個key對應的simhash平均數量為simhash數量總和的1226\frac{1}{2^{26}}或1225\frac{1}{2^{25}},所以搜索時間是一一搜索的10226\frac{10}{2^{26}}或10225\frac{10}{2^{25}}。

[b]7. 存儲simhash的數據結構: [/b]

根據6,存儲simhash需要用的數據結構應該為:hash < int,vector < uint_64>>吧。

[b]8. 參考: [/b]

1)《這就是搜索引擎–核心技術詳解10.4》 

2) 《simhash算法原理及實現》  

3) 《海量數據相似度計算之simhash短文本查找》  

4) 《我的數學之美系列二 —— simhash與重復信息識別》  

5)google發布的simhash論文: 《Detecting near-duplicates for web crawling》  

6)google講解simhash的ppt《Detecting Near-Duplicates for Web Crawling》 

7) 《Simhash算法原理和網頁查重應用》


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com