SimHash和網頁查重

2021-06-29 12:35:04 字數 1870 閱讀 8731

方法出自google文章detecting near-duplicates for web crawling(2007 www)。

google要解決的問題是當crawler得到乙個網頁時,如何判斷該網頁是否是已經存在的或存在相似的。

解決這個問題分為兩步,第一是對網頁的內容進行hash,得到網頁的「指紋」;第二是給定某個網頁的指紋,如果快速的在資料庫中找到相似的指紋。

解決第乙個問題使用的hash方法是simhash,simhash與一般的hash方法最大的不同是對於相似的兩個物件,使用simhash得到的hash結果(二進位制串)也是相似的,即海明距離比較小。

simhash:

1. 提取網頁的特徵,並同時得到這些特徵相應的權重

2. 對每個特徵進行一般的hash,得到乙個n bit的二進位制串,假設n=64;

3. 設定網頁的simhash為向量v,v的初值0,向量v的維數與特徵hash結果的維數相同,都是64位;

4. 對於每個特徵i的hash值,如果第j位為0,則向量v的第j位減去

5. 處理所有特徵的hash值後,將向量v中的負數置為0,正數置為1,此時的向量v就是該網頁的simhash值。

假設現在有乙個由網頁simhash值(後面稱作指紋)組成的資料庫,資料庫可能非常大,假設為

detecting near-duplicates:

方案一:窮舉搜尋

最簡單的辦法是進行窮舉搜尋,比較輸入指紋f與每乙個庫內指紋d,看他們的海明距離是否不大於3。該方法的時間複雜度是

方案二:窮舉探測(probe)

另乙個很暴力的方法是窮舉probe。首先對資料庫中的指紋進行排序(認為是預處理,不計入總的時間複雜度),對於輸入指紋f,求出所有可能的與f海明距離不大於3的指紋f',使用f'在排序的資料庫中進行二分查詢(一次probe過程)。該方法的時間複雜度約為

方案三:預處理法

該方案是首先算出資料庫中每個指紋d的海明距離不大於3的指紋d',並且d'是在資料庫內的。也就是說一旦通過f查詢到d,由於與d海明距離不大於3的指紋已經預處理得到,就可以得到f的所有相似指紋。該方法的時間複雜度為

方案四:折中二三

該方案也是google在這篇**中提出的方法,是對方案二和方案三的乙個折中,即使用可以接受的記憶體消耗,減少查詢次數。

因為資料庫中共有

現在選擇p位的顯著位,p小於d並且

其實說白了核心思想就是先用f的某些位進行查詢,縮小校驗指紋海明距離的範圍。那麼問題來了,如何確定d和p呢?其實不用也沒有辦法找出d位的顯著位,google用了一種很巧妙的辦法解決這個問題,就是建立多個表!

具體檢索流程:

1. 將指紋分成若干段,這裡使用最簡單的方法,假設就分成4段,每段為16位。

2. 假設第一段,也就是前16位為上面提到的p位,使用這p為到指紋資料庫中進行查詢(資料庫是排序的),那麼大概會得到

現在問題又來了,如果只是簡單的取第一段,那麼如果第一段中存在某一位不同,但是後面三段中的每一位都相同,這時海明距離還是不大於3的,但是卻把這樣的結果給濾掉了!解決這個問題的方法就是建立多個表。還是以將指紋分為4段為例,這時4段中至少有一段是應該與查詢指紋相應段完全相同的。所以這時就要建立

當然分段的方法有很多種,而分成多少段跟表的個數是有關的,比如分成5段就應該有

以分成4段4個表的方法為例,一次probe(查詢)大約返回

可以看出當劃分的段越多時,表就越多,記憶體消耗就越大,但是p就越接近於d,也就是每次probe返回的結果就越少,速度越快。所以劃分段或者建立多少個表是記憶體與速度之間的權衡,而方案二和方案三是兩個極端的情況。

在**中還提到了表的壓縮問題和批量查詢的問題。

高效網頁去重演算法 SimHash

記得以前有人問過我,網頁去重演算法有哪些,我不假思索的說出了余弦向量相似度匹配,但如果是數十億級別的網頁去重呢?這下糟糕了,因為每兩個網頁都需要計算一次向量內積,查重效率太低了!我當時就想 論查詢效率肯定是要考慮hash演算法,相同字串的hashcode肯定相同,不同字串的hashcode卻是大不相...

文字去重之SimHash演算法

說到文字相似性計算,大家首先想到的應該是使用向量空間模型vsm vector space model 使用vsm計算相似度,先對文字進行分詞,然後建立文字向量,把相似度的計算轉換成某種特徵向量距離的計算,比如余弦角 歐式距離 jaccard相似係數等。這種方法存在很大乙個問題 需要對文字兩兩進行相似...

文字去重之SimHash演算法

說到文字相似性計算,大家首先想到的應該是使用向量空間模型vsm vector space model 使用vsm計算相似度,先對文字進行分詞,然後建立文字向量,把相似度的計算轉換成某種特徵向量距離的計算,比如余弦角 歐式距離 jaccard相似係數等。這種方法存在很大乙個問題 需要對文字兩兩進行相似...