Winnowing:一種文檔指紋的通用算法

       本文爲論文《Winnowing: Local Algorithms for Document Fingerprinting》的讀書筆記。

       在當今時代,電子內容會通過很多途徑出現相同的情況,比如說:引用,版本修訂,剽竊等。而文檔指紋是用來準確指定拷貝的有效途徑,哪怕是在大量的文檔集合種有小部分的拷貝。

       在該論文中,作者介紹了通用的文檔指紋算法,這些算法似乎可以捕捉到任何指紋的通用屬性來保證拷貝的檢測。另外,作者還提出了一種新的效果卓越的算法,名稱是“Winnowing”。該算法對於文檔指紋的偵測非常高效。

       作者首先從背景入手,講述了文檔抄襲檢測的實際意義。關於文檔的抄襲,不僅僅是大篇幅的引用或剽竊,同時還包括小部分的拷貝,而後者更加隱蔽,且不會輕易被發現,但是現在後者這種現象已經受到廣泛的關注,有很多的研究在嘗試解決後者這個難題。

       之前很多的檢測算法都利用了一個觀點,那就是k-gram,長度爲k的連續子串。這些算法,首先將文檔分成很多個k-grams,而這個k值是用戶指定的。然後再哈希每一個k-gram,最後選出這些哈希值的一些子集,作爲這個文檔的指紋。在所有的實用的算法中,指紋還帶有位置信息,這些信息代表着這些指紋來自的文檔位置。這裏需要注意的是,如果在實際過程中,一旦hash函數被選定的話,那麼兩個不同文檔衝突的概率會非常小,這樣也就大大降低了偶然性,反過來講,一旦兩個文檔的文檔指紋是一樣的,那麼非常可能這兩個文檔使用的是同一個k-gram。

       可見,爲了效率而言,並沒有將所有的hash值作爲文檔的指紋,而是選取了其中的一部分來作爲文檔指紋。那麼這裏就會存在一個如何選擇hash值的問題,這個問題也是本文的一個關鍵點,好的選擇策略可以使得算法的效率高,可用性高,並且干擾噪聲小。在選擇策略中,有一種方法是之前被廣泛使用的,那就是0 mod p,而這個p值是被用戶指定的。這樣的方法是很容易實現,因爲這使得所有的hash值中的1/p被保留下來作爲文檔指紋。而作爲檢測文檔間是否存在雷同的方法,就是檢測文檔指紋相同指紋的個數。

       但是以上的方法會有一個弊端,那就是不能保證文檔間的所有匹配會被檢測出來,因爲它把所有的選擇都依賴於0 mod p。而本文提出的方法winnowing,可以從hash序列種選取合適的集合作爲文檔指紋,並且可以保證任意總夠長的匹配都會被檢測出來。這個winnowing算法之所以會這樣的高效,是因爲在選取hash值集合的時候,採用了滑動窗(window)的概念來選取hash值,使用滑動窗口來選擇指紋的好處是:指紋的選擇更多的依賴於窗口內的hash值序列,但是0 mod p選擇時,更多取決於0 mod p函數。也就是在最原始的hash值中,作者首先以窗口大小w來選擇這個窗口中最小的hash值,然後將這個窗口向右移動,每移動一個,都選擇出窗口中最小的hash值。這樣的過程結束後,會選擇出很多的hash值,但是可以預見的是,在這些hash值中,肯定會存在很多相鄰的hash值是相同的,這是因爲窗口滑動的緣故。然後再將這些相同的hash值進行處理,最後得到比原來數量少很多的hash值集合,這就是使用winnowing後的文檔指紋。

       當然這樣的算法也有一些文檔那個是不適用的,比如說整個文檔中都是同一個字符的文檔。因爲這樣的話,幾乎產生的hash值只有一個,而這將大大降低文檔指紋的代表性。

       隨後作者還介紹了在文檔相似檢測領域的一些背景和相關性工作。

       首先,如果要對一個文檔進行指紋提取的話,那麼這個指紋提取算法必須滿足3個特性。第一,該算法對空格具有不敏感性。也就是說,對文檔的初步處理會採取措施,使得文檔中空格,標點等的個數對初步處理結果是不具有影響的。第二,算法本身具有噪聲抑制的特性。首先需要注意的是,比如“the”這樣的單詞在文檔間出現,然後被檢測出來,是沒有意義的。所以在匹配方面,匹配必須足夠長,使得這樣的匹配可以預示着文檔間的確存在抄襲或者雷同現象。同樣的,比如說在不同文檔間出現了相同的諺語,雖然諺語的長度可能足夠長,但是不應該就憑此就認爲文檔間存在雷同。第三,算法與文檔內容的位置不存在依賴關係。比如說,兩個文檔已經存在相似現象,那麼在其中一篇文章中插入某些成段內容將不會影響到原先的相似度結果;或者刪除了某些無關內容也不會影響到最終的相似度結果。

       關於第一個特性,對文檔進行簡單的預處理即可以做到,該文也沒有大篇幅講述。

       但是第二個特性的講述,作者提出了一個閾值概念,也就是說需要選擇足夠長的的值k,使得這個k值比普通的諺語長度要長。所以這裏用的一個假設,這個假設是長度不小於k的子串匹配是有意義的,而長度小於k的子串匹配是不具有意義的。

       其實第三個特性的講述,是非常有趣也是有意義的,爲達到這個特性的時候,作者介紹了一種之前也被廣泛使用的策略Karp-Rabin String Match。

       Karp-Rabin算法是爲了實現快速子串匹配的。在計算hash值的時候,主要是呈現出一個多項式計算。但是由於hash值計算的特殊性,前一個hash計算值其實和後一個hash計算值有很大的相似性,因爲前一個計算和後一個計算在本質上只是相差一個字符。所以可以採用後者利用前者已有的計算值進行計算,在計算上只是在前者的計算結果上多兩個加法計算和兩次乘法計算,大大降低了原始計算的計算複雜性。

       隨後的論文中,作者描述和分析了winnowing算法,其實也可以發現,該算法的主要關鍵點是如何從k-grams的衆多hash值種選出最終的指紋。在檢測過程中,作者希望子串在匹配過程中滿足兩個特性:1,如果一個子串匹配的長度至少和受保證的閾值t的話,這樣的匹配會被檢測出來;2,算法不會檢測出長度小於k的匹配,這個k值被稱爲噪聲閾值。

       可以看到,如果k越大的話,那麼我就越有信心證明檢測出來的匹配不是偶然性的。在winnowing中選擇文檔指紋的時候,如果出現了很多相鄰的相同最小值,那麼選擇最右端出現的那個值,最後保存所有被選擇出來的hash值作爲文檔的指紋。

       關於在本算法在運用的時候,雖然指紋可以按照算法獲取,但是在具體算法流程中,可能會存在一個效率問題,也就是如何使得hash值被一次選出。首先這些值都是被存放在數據庫中的,然後這些指紋會被索引。如果我們採取另一個窗口Fw來實現對指紋選擇的話,那麼這樣在實現流程中使用的內存和磁盤訪問會變得更少,更有利於指紋的查找。

       在該論文的後面部分,作者使用了一系列的實驗數據來檢驗winnowing算法。以及以C語言展現了winnowing算法的具體代碼實現。

發佈了47 篇原創文章 · 獲贊 10 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章