SimHash是用來網頁去重最經常使用的hash方法,速度很快。Google採用這種算法來解決萬億級別的網頁去重任務。html
SimHash算法的主要思想是降維。將高維的特徵向量映射成一個低維的特徵向量,經過兩個向量的Hamming Distance來肯定文章是否重複或者高度近似。java
在simhash的發明人Charikar的論文中並無給出具體的simhash算法和證實,「量子圖靈」得出的證實simhash是由隨機超平面hash算法演變而來的。算法
參考文獻:《Detecting Near-Duplicates for Web Crawling 》函數
傳統hash函數解決的是生成惟一值,好比md5,hashmap等。Md5是用於生成惟一簽名串,只要稍微多加一個字符,md5的兩個數字看起來相差甚遠。而咱們的目的是解決文本類似度計算,要比較的是兩個文章是否類似。而simhash對類似文本的哈希映射結果也類似。測試
傳統的hash算法只負責將原始內容儘可能均勻隨機地映射爲一個簽名值,原理上至關於僞隨機數產生算法。產生的兩個簽名,若是相等,說明原始內容在必定機率下是相等的;若是不相等,除了說明原始內容不相等外,再也不提供任何信息,由於即便原始內容只相差一個字節,所產生的簽名也極可能差異極大。從這個意義上來講,要設計一個hash算法,對類似的內容產生的簽名也相近,是更爲艱難的任務,由於它的簽名值除了提供原始內容是否相等的信息外,還能額外提供不相等的原始內容的差別程度的信息。spa
而Google的simhash算法產生的簽名,能夠用來比較原始內容的類似度。設計
從文件夾res1366x768x565中,查找與OSDTbl_ATV_c.inl文件類似的全部文件。htm
1)、把須要判斷的文本進行分詞,造成這個文章的特徵單詞。md5
2)、最後造成去掉噪音詞的單詞序列,併爲每一個單詞加上權重。字符串
經過傳統hash算法,對文章的每一個特徵單詞產生一個f位的簽名b。
1)、加權
經過步驟2中生成的hash值,須要按照單詞的權重造成加權數字串。
2)、合併
把步驟3中第一步各個單詞算出來的序列值對應位累加,變成只有一個序列串。
3)、降維
把步驟2中第三步算出來的序列串變成0 1串,造成咱們最終的simhash簽名。
經過以上操做的轉換,咱們把庫裏的文本都轉換爲simhash代碼,並轉換爲string類型存儲,空間大大減小。接下來咱們經過海明距離(Hamming distance)計算兩個simhash到底相不類似。
兩個碼字的對應比特取值不一樣的比特數稱爲這兩個碼字的海明距離。
舉例以下: 10101 和 00110 從第一位開始依次有第一位、第4、第五位不一樣,則海明距離爲3。
計算海明距離的廣泛算法爲:
對於二進制字符串的a和b,海明距離爲a,b作異或操做(a XOR b)後,結果中1的個數。
異或: 只有在兩個比較的位不一樣時其結果是1 ,不然結果爲 0
到此,咱們完成了simhash算法的全部步驟。
總結simhash算法的步驟:
一、生成每一個文件的simhash值
二、計算兩個文件的Hamming distance
simhash用於比較大文本,好比500字以上效果都還蠻好,距離小於3的基本都是類似,誤判率也比較低。可是若是咱們處理的是微博信息,最多也就140個字,使用simhash的效果並不那麼理想。看以下圖,在距離爲3時是一個比較折中的點,在距離爲10時效果已經不好了,不過咱們測試短文本不少看起來類似的距離確實爲10。若是使用距離爲3,短文本大量重複信息不會被過濾,若是使用距離爲10,長文本的錯誤率也很是高,如何解決?
參考資料:《simHash 簡介以及 java 實現》http://www.open-open.com/lib/view/open1375690611500.html