simhash演算法實現 查詢檔案相似度

2021-09-24 10:14:55 字數 2016 閱讀 4791

為什麼80%的碼農都做不了架構師?>>>

simhash是用來網頁去重最常用的hash方法,速度很快。google採用這種演算法來解決萬億級別的網頁去重任務。

simhash演算法的主要思想是降維。將高維的特徵向量對映成乙個低維的特徵向量,通過兩個向量的hamming distance來確定文章是否重複或者高度近似。

在simhash的發明人charikar的**中並沒有給出具體的simhash演算法和證明,「量子圖靈」得出的證明simhash是由隨機超平面hash演算法演變而來的。

detecting near-duplicates for web crawling》

傳統hash函式解決的是生成唯一值,比如md5,hashmap等。md5是用於生成唯一簽名串,只要稍微多加乙個字元,md5的兩個數字看起來相差甚遠。而我們的目的是解決文字相似度計算,要比較的是兩個文章是否相似。而simhash對相似文字的雜湊對映結果也相似。

傳統的hash演算法只負責將原始內容盡量均勻隨機地對映為乙個簽名值,原理上相當於偽隨機數產生演算法。產生的兩個簽名,如果相等,說明原始內容在一定概率下是相等的;如果不相等,除了說明原始內容不相等外,不再提供任何資訊,因為即使原始內容只相差乙個位元組,所產生的簽名也很可能差別極大。從這個意義上來說,要設計乙個hash演算法,對相似的內容產生的簽名也相近,是更為艱難的任務,因為它的簽名值除了提供原始內容是否相等的資訊外,還能額外提供不相等的原始內容的差異程度的資訊。

而google的simhash演算法產生的簽名,可以用來比較原始內容的相似度。

從資料夾res1366x768x565中,查詢與osdtbl_atv_c.inl檔案相似的所有檔案。

1)、把需要判斷的文字進行分詞,形成這個文章的特徵單詞。

2)、最後形成去掉噪音詞的單詞序列,並為每個單詞加上權重。

通過傳統hash演算法,對文章的每個特徵單詞產生乙個f位的簽名b。

1)、加權

通過步驟2中生成的hash值,需要按照單詞的權重形成加權數字串。

2)、合併

把步驟3中第一步各個單詞算出來的序列值對應位累加,變成只有乙個序列串。

3)、降維

把步驟2中第三步算出來的序列串變成0 1串,形成我們最終的simhash簽名。

通過以上操作的轉換,我們把庫里的文字都轉換為simhash**,並轉換為string型別儲存,空間大大減少。接下來我們通過海明距離(hamming distance)計算兩個simhash到底相不相似。

兩個碼字的對應位元取值不同的位元數稱為這兩個碼字的海明距離。

舉例如下:1010100110從第一位開始依次有第一位、第

四、第五位不同,則海明距離為3。

計算海明距離的普遍演算法為:

對於二進位制字串的a和b,海明距離為a,b做異或操作(a xor b)後,結果中1的個數。

異或:只有在兩個比較的位不同時其結果是1 ,否則結果為 0 

到此,我們完成了simhash演算法的所有步驟。

總結simhash演算法的步驟:

1、生成每個檔案的simhash值

2、計算兩個檔案的hamming distance

simhash用於比較大文字,比如500字以上效果都還蠻好,距離小於3的基本都是相似,誤判率也比較低。但是如果我們處理的是微博資訊,最多也就140個字,使用simhash的效果並不那麼理想。看如下圖,在距離為3時是乙個比較折中的點,在距離為10時效果已經很差了,不過我們測試短文本很多看起來相似的距離確實為10。如果使用距離為3,短文本大量重複資訊不會被過濾,如果使用距離為10,長文字的錯誤率也非常高,如何解決?

python實現查詢檔案名包含指定字串的檔案

1 當前目錄以及當前目錄的所有子目錄下查詢檔案名包含指定字串的檔案,並列印出相對路徑。自廖雪 峰的官方 實現如下 import os def myfind pattern,root for each in os.path.listdir root if os.path.isdir os.path.j...

mapx實現查詢

1 屬性查詢。find search方法 注意的是find方法只支援tab表檔案,不支援空間資料 表。find 與foxpro中locate定位命令想類似。search 支援sql語句。寫法 僅指sql語句的where 部分,且from語句中只能有乙個表 僅對單錶進行操作 select from l...

Linux find 查詢檔案

在日誌資料夾下判斷是否有web伺服器的日誌資料夾,寫了個指令碼 bin bash cd wls annuity acc for sys in cat wiiserver name list.txt do find logs sys name sys xargs echo en n 123.txt f...