閱讀目錄
- 基本思想
- 局部敏感哈希LSH
- 文檔相似度計算
局部敏感哈希(Locality Sensitive Hashing,LSH)算法是我在前一段時間找工作時接觸到的一種衡量文本相似度的算法。局部敏感哈希是近似最近鄰搜索算法中最流行的一種,它有堅實的理論依據(jù)并且在高維數(shù)據(jù)空間中表現(xiàn)優(yōu)異。它的主要作用就是從海量的數(shù)據(jù)中挖掘出相似的數(shù)據(jù),可以具體應(yīng)用到文本相似度檢測、網(wǎng)頁搜索等領(lǐng)域。
基本思想
局部敏感哈希的基本思想類似于一種空間域轉(zhuǎn)換思想,LSH算法基于一個假設(shè),如果兩個文本在原有的數(shù)據(jù)空間是相似的,那么分別經(jīng)過哈希函數(shù)轉(zhuǎn)換以后的它們也具有很高的相似度;相反,如果它們本身是不相似的,那么經(jīng)過轉(zhuǎn)換后它們應(yīng)仍不具有相似性。
哈希函數(shù),大家一定都很熟悉,那么什么樣的哈希函數(shù)可以具有上述的功能呢,可以保持?jǐn)?shù)據(jù)轉(zhuǎn)化前后的相似性?當(dāng)然,答案就是局部敏感哈希。局部敏感哈希LSH
局部敏感哈希的最大特點就在于保持?jǐn)?shù)據(jù)的相似性,我們通過一個反例來具體介紹一下。
假設(shè)一個哈希函數(shù)為Hash(x) = x%8,那么我們現(xiàn)在有三個數(shù)據(jù)分別為255、257和1023,我們知道255和257本身在數(shù)值上具有很小的差距,也就是說它們在三者中比較相似。我們將上述的三個數(shù)據(jù)通過Hash函數(shù)轉(zhuǎn)換:
Hash(255) = 255%8 = 7;
Hash(257) = 257%8 = 1;
Hash(1023) = 1023%8 = 7;
我們通過上述的轉(zhuǎn)換結(jié)果可以看出,本身很相似的255和257在轉(zhuǎn)換以后變得差距很大,而在數(shù)值上差很多的255和1023卻對應(yīng)相同的轉(zhuǎn)換結(jié)果。從這個例子我們可以看出,上述的Hash函數(shù)從數(shù)值相似度角度來看,它不是一個局部敏感哈希,因為經(jīng)過它轉(zhuǎn)換后的數(shù)據(jù)的相似性喪失了。
我們說局部敏感哈希要求能夠保持?jǐn)?shù)據(jù)的相似性,那么很多人懷疑這樣的哈希函數(shù)是否真的存在。我們這樣去思考這樣一個極端的條件,假設(shè)一個局部敏感哈希函數(shù)具有10個不同的輸出值,而現(xiàn)在我們具有11個完全沒有相似度的數(shù)據(jù),那么它們經(jīng)過這個哈希函數(shù)必然至少存在兩個不相似的數(shù)據(jù)變?yōu)榱讼嗨茢?shù)據(jù)。從這個假設(shè)中,我們應(yīng)該意識到局部敏感哈希是相對的,而且我們所說的保持?jǐn)?shù)據(jù)的相似度不是說保持100%的相似度,而是保持最大可能的相似度。
對于局部敏感哈希“保持最大可能的相似度”的這一點,我們也可以從數(shù)據(jù)降維的角度去考慮。數(shù)據(jù)對應(yīng)的維度越高,信息量也就越大,相反,如果數(shù)據(jù)進行了降維,那么毫無疑問數(shù)據(jù)所反映的信息必然會有損失。哈希函數(shù)從本質(zhì)上來看就是一直在扮演數(shù)據(jù)降維的角色。文檔相似度計算
我們通過利用LSH來實現(xiàn)文檔的相似度計算這個實例來介紹一下LSH的具體用法。
3.1 Shingling
假設(shè)現(xiàn)在有4個網(wǎng)頁,我們將它們分別進行Shingling(將待查詢的字符串集進行映射,映射到一個集合里,如字符串“abcdeeee", 映射到集合”(a,b,c,d,e)", 注意集合中元素是無重復(fù)的,這一步驟就叫做Shingling, 意即構(gòu)建文檔中的短字符串集合,即shingle集合。),得到如下的特征矩陣:
其中“1”代表對應(yīng)位置的Shingles在文檔中出現(xiàn)過,“0”則代表沒有出現(xiàn)過。
在衡量文檔的相似度中,我們有很多的方法去完成,比如利用歐式距離、編輯距離、余弦距離、Jaccard距離等來進行相似度的度量。在這里我們運用Jaccard相似度。接下來我們就要去找一種哈希函數(shù),使得在hash后盡量還能保持這些文檔之間的Jaccard相似度。
我們的目標(biāo)就是找到這樣一種哈希函數(shù),如果原來文檔的Jaccard相似度高,那么它們的hash值相同的概率高,如果原來文檔的Jaccard相似度低,那么它們的hash值不相同的概率高,我們稱之為Min-hashing(最小哈希)。
3.2 Min-hashing
Min-hashing定義為:特征矩陣按行進行一個隨機的排列后,第一個列值為1的行的行號。舉例說明如下,假設(shè)之前的特征矩陣按行進行的一個隨機排列如下:
最小哈希值:h(S1)=3,h(S2)=5,h(S3)=1,h(S4)=2.
為什么定義最小hash?事實上,兩列的最小hash值就是這兩列的Jaccard相似度的一個估計,換句話說,兩列最小hash值同等的概率與其相似度相等,即P(h(Si)=h(Sj)) = sim(Si,Sj)。為什么會相等?我們考慮Si和Sj這兩列,它們所在的行的所有可能結(jié)果可以分成如下三類:
?。?)A類:兩列的值都為1;
?。?)B類:其中一列的值為0,另一列的值為1;
(3)C類:兩列的值都為0.
特征矩陣相當(dāng)稀疏,導(dǎo)致大部分的行都屬于C類,但只有A、B類行的決定sim(Si,Sj),假定A類行有a個,B類行有b個,那么sim(si,sj)=a/(a+b)?,F(xiàn)在我們只需要證明對矩陣行進行隨機排列,兩個的最小hash值相等的概率P(h(Si)=h(Sj))=a/(a+b),如果我們把C類行都刪掉,那么第一行不是A類行就是B類行,如果第一行是A類行那么h(Si)=h(Sj),因此P(h(Si)=h(Sj))=P(刪掉C類行后,第一行為A類)=A類行的數(shù)目/所有行的數(shù)目=a/(a+b),這就是最小hash的神奇之處。
Min-hashing的具體做法可以根據(jù)如下進行表述:
返回到我們的實例,我們首先生成一堆隨機置換,把特征矩陣的每一行進行置換,然后hash function就定義為把一個列C hash成一個這樣的值:就是在置換后的列C上,第一個值為1的行的行號。如下圖所示:
圖中展示了三個置換,就是彩色的那三個,我現(xiàn)在解釋其中的一個,另外兩個同理。比如現(xiàn)在看藍(lán)色的那個置換,置換后的Signature Matrix為:
然后看第一列的第一個是1的行是第幾行,是第2行,同理再看二三四列,分別是1,2,1,因此這四列(四個document)在這個置換下,被哈希成了2,1,2,1,就是右圖中的藍(lán)色部分,也就相當(dāng)于每個document現(xiàn)在是1維。再通過另外兩個置換然后再hash,又得到右邊的另外兩行,于是最終結(jié)果是每個document從7維降到了3維。我們來看看降維后的相似度情況,就是右下角那個表,給出了降維后的document兩兩之間的相似性。可以看出,還是挺準(zhǔn)確的,回想一下剛剛說的:希望原來documents的Jaccard相似度高,那么它們的hash值相同的概率高,如果原來documents的Jaccard相似度低,那么它們的hash值不相同的概率高,如何進行概率上的保證?Min-Hashing有個驚人的性質(zhì):
就是說,對于兩個document,在Min-Hashing方法中,它們hash值相等的概率等于它們降維前的Jaccard相似度。
注:在上述例子中,我們還可以采取歐氏距離等相似度量來替代Jaccard相似度,這時候LSH相應(yīng)的策略也需要進行改變,從而使得最后的hash值等于降為前的相似度。