相似數據檢測算法對給定的一對數據序列計算兩者之間的相似度([0,1], 1表示完全相同)或距離([0, ), 0表示完全相同),從而度量數據之間的相似程度。相似數據檢測在信息科學領域具有非常重要的應用價值,比如搜索引擎檢索結果的聚類與排序、數據聚類與分類、Spam檢測、論文剽竊檢測、重復數據刪除、Delta數據編碼等應用。正是由於它的重要性,近年來成為了研究的重點,不斷有新檢測方法涌現並得到評估。其中,Broder提出的shingling算法和Charikar的simhash算法被認為是目前為止最好的算法。
對於相似數據檢測,最為簡單地可以采用類似Unix diff的方法。Unix diff對文檔進行逐行對比來檢測相似文件,它采用經典的LCS(Longest Common Subsequence,最長公共子串)算法,運用動態規划方法來計算相似性。LCS的含義是同時包含在字符串里的一個最長字符序列,LCS的長度作為這兩個字符串相似性的度量。Diff算法以整行作為"字符"來計算最長公共子串,性能上比字符級的LCS算法快很多。這種方法效率很低,而且只適用文本文件的相似比較,不能直接適用於二進制文件。為此,研究者們提出為每個文檔提取一組特征,這樣將文件相似性問題轉換為集合相似性問題,如基於shingle的計算方法。這種方式的核心思想是為每個文件提取組特征值,以特征值集合來計算相似性,從而降低空間和計算復雜性來提高性能。
經過對shingle算法和simhash算法以及筆者基於bloom filter實現算法的分析,相似數據檢測算法大致流程如下:
(1) 將數據段分解成一組shingle(即子序列或數據塊),可以采用定長、變長、單詞或段落(文本文件)等分塊算法;
(2) 為了降低空間和時間計算復雜性,可以對shingle集合進行抽樣,比如Min-Wise,Modm,Mins方法;
(3) 基於選定的shingle集合為數據文件抽取特征,通常是為每個shingle計算hash值組成的序列作為特征值;
(4) 為了降低空間和時間計算復雜性,可以對文件特征進行降維處理,比如simhash和bloom filter;
(5) 基於文件特征計算兩個數據對象之間的相似性,計算方法有Cosine、Overlap、Dice、Jaccard或Hamming距離。
Shingle算法
Shingle算法的核心思想是將文件相似性問題轉換為集合的相似性問題,集合的相似性度量方法主要有resemblance 和containment兩種,其定義如下。
Rw(f1, f2) = ----------------------------------------------
|shingle(f1, w) ∪ shingle(f2, w)|
|shingle(f1, w) ∩ shingle(f2, w)|
Cw(f1, f2) = ----------------------------------------------
|shingle(f1, w)|
數量較大時,如果對所有shingle進行相似性處理則系統開銷較大,包括內存和CPU資源。這時就可以考慮對shingle集合進行抽樣,以降低空間和時間計算復雜性,但同時由於樣本覆蓋率有限,相似性精確度會有所降低。shingle取樣主要有三種方法,即Min-Wise,Modm,和Mins。Min-Wise技術是通過將shingle的長度w和整數值進行映射產生隨機哈希的公共集,在此相同的模式下進行隨機最小獨立置換的采樣,從而得到采樣集合;Modm 技術是通過在與Min-Wise同樣的公共映射集中選擇所有模m為0 的哈希值對應的shingle組成取樣集合;Mins技術同樣也是先將shingle和整數集進行映射,然后從中選擇最小s個元素組成取樣集合。此外,還可以使用shingle的hash值代表shingle進行相似性計算,能夠節省一定計算開銷。
Simhash算法
Shingle算法的空間和時間計算復雜性都比較高,對於大數據集的Simlarity Join問題將難以適用。Charikar的simhash算法的核心思想是用一個b位的hash值來表示文件的特征值,然后使用simhash之間的Hamming距離來衡量相似性。Hamming距離的定義為,兩個二進制序列中對應位不同的個數。simhash的計算方法如下:
(1) 將一個b維的向量V初始化為0,b位的二進制數s初始化為0;
(2) 對每一個shingle,用hash函數(如MD5, SHA1)計算一個b位的簽名h。對i=1到b,如果h的第i位為1,則V的第i個元素加上該特征權重;否則,V的第i個元素減去該特征權重;
(3) 如果V的第i個元素大於0,則s的第i位為1,否則為0;
(4) 輸出s作為simhash。
與傳統hash函數相比,simhash具有一個這樣的顯著特征,即越相似的文件具有越相似的simhash值,也就是說Hamming距離越小。顯而易見,Simhash僅使用b位的hash值來表示文件 的特征,節省了大量的存儲開銷;Hamming距離計算簡單高效,Simhash使用Hamming距離來衡量相似性,計算復雜性得到大大降低。簡而言之,simhash算法通過對文件特征的降維,有效解決了Shingle算法的高空間和時間計算復雜性問題。然而,simhash算法的精確度也會有所損耗,並且與simhash的位數b有關,b越大精確度越高。
Bloom filter算法
與Simhash算法本質相似,Bloom filter算法的核心思想也是着眼於文件特征的降維,它使用Bloom filter數據結構來表示特征值。Bloom filter是一個空間效率很高的數據結構,它由一個位數組和一組hash映射函數組成。Bloom filter可以用於檢索一個元素是否在一個集合中,它的優點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難。使用Bloom filter進行相似數據檢測,可以彌補shingle中應用特征集交集計算文件相似性所導致的高計算和存儲空間開銷,在性能與相似性匹配精度之間取得平衡。Bloom filter構造方法如下:
(1) 構造一個m位的bloom filter數據結構bf,並將所有位初始為0;
(2) 選定兩個hash函數作為映射函數,分別為hash1,hash2;
(3) 對每一個shingle,分別應用hash1和hash2,並對bf相應比特位置1;
(4) 輸出bf作為文件特征值。
這樣,兩個文件相似性計算就轉換成兩個bloom filter的相似性計算,越相似的文件在它們的bloom filter中有更多共同的1。由於Bloom filter具有有限的誤識別率的特性,相似性算法精確度取決於Bloom filter的大小,越大則精確度越高,同時存儲空間消耗也越大。Bloom filter同樣可以使用Hamming距離衡量相似性,也可以使用Cosine、Overlap、Dice、Jaccard等方法來度量。Hamming距離前面已有定義,這里介紹一下后四種方法的計算公式。
Cosine_sim(x, y) = -----------------
sqrt(|x|.|y|)
dot(x, y)
Overlap_sim(x, y) = -----------------
min(|x|, |y|)
2.dot(x, y)
Dice_sim(x, y) = -----------------
|x| + |y|
dot(x, y)
Jaccard_sim(x, y) = ------------------------
|x| + |y| - dot(x, y)
其中,dot(x, y) = Σx[i].y[i],在這里相當於兩個Bloom filter數據結構中同時為1的位數;|x|表示bloom filter數據結構中為1的位數。相似性計算函數如下:
- static double bloom_sim(BLOOM *bloom1, BLOOM *bloom2)
- {
- int i, r1, r2;
- int c1 = 0, c2 = 0, comm = 0;
- double sim;
- for (i = 0; i < BLOOM_ARRAY_SZ; i++) {
- r1 = bloom_check(bloom1, 1, i);
- r2 = bloom_check(bloom2, 1, i);
- if (r1 && r2) {
- comm++;
- c1++;
- c2++;
- } else {
- if (r1) {
- c1++;
- }
- if (r2) {
- c2++;
- }
- }
- }
- /* similarity measures */
- //sim = comm/(sqrt(c1) * sqrt(c2)); /* Cosine */
- //sim = comm/1.0/(c1 + c2 - comm); /* Jaccard */
- //sim = comm*2.0/(c1 + c2); /* Dice */
- sim = comm*1.0/(c1<c2?c1:c2); /* Overlap */
- return sim;
- }
三種算法對比
Shingle算法的空間和計算復雜性高,相似性精度也高,適合數據量不大且對精度要求高的應用。Simhash和bloom filter算法在空間消耗和計算復雜性方面都優於Shingle算法,但是精度有所損耗,取決於simhash的長度和bloom filter的大小。simhash的長度通常為64位或128位,這個基本可以滿足應用的需求,可以根據實際需求增大位數。bloom filter要大於simhash長度,可以根據最大shingle數的兩倍來估算,精度方面也要優於simhash。由於hash函數的碰撞問題,simhash和bloom filter算法可能出現誤判現象,即不相似的文件可能會判定為相似的。總結一下,通常情況下,文件特征值存儲空間消耗方面,Shingle > bloom filter > simhash;相似性計算精度方面,Shingle < bloom filter < simhash。Bloom filter算法往往是比較折中的相似數據檢測方法選擇,但海量數據集的相似性計算往往采用simhash算法,在計算性能方面具有很大優勢,而且更加適合MapReduce計算模型。