局部敏感哈希(Locality Sensitive Hashing,LSH)算法是我在前一段時間找工做時接觸到的一種衡量文本類似度的算法。局部敏感哈希是近似最近鄰搜索算法中最流行的一種,它有堅實的理論依據而且在高維數據空間中表現優異。它的主要做用就是從海量的數據中挖掘出類似的數據,能夠具體應用到文本類似度檢測、網頁搜索等領域。算法
1. 基本思想
局部敏感哈希的基本思想相似於一種空間域轉換思想,LSH算法基於一個假設,若是兩個文本在原有的數據空間是類似的,那麼分別通過哈希函數轉換之後的它們也具備很高的類似度;相反,若是它們自己是不類似的,那麼通過轉換後它們應仍不具備類似性。函數
哈希函數,你們必定都很熟悉,那麼什麼樣的哈希函數能夠具備上述的功能呢,能夠保持數據轉化先後的類似性?固然,答案就是局部敏感哈希。post
2. 局部敏感哈希LSH
局部敏感哈希的最大特色就在於保持數據的類似性,咱們經過一個反例來具體介紹一下。spa
假設一個哈希函數爲Hash(x) = x%8,那麼咱們如今有三個數據分別爲25五、257和1023,咱們知道255和257自己在數值上具備很小的差距,也就是說它們在三者中比較類似。咱們將上述的三個數據經過Hash函數轉換:htm
Hash(255) = 255%8 = 7;blog
Hash(257) = 257%8 = 1;ci
Hash(1023) = 1023%8 = 7;文檔
咱們經過上述的轉換結果能夠看出,自己很類似的255和257在轉換之後變得差距很大,而在數值上差不少的255和1023卻對應相同的轉換結果。從這個例子咱們能夠看出,上述的Hash函數從數值類似度角度來看,它不是一個局部敏感哈希,由於通過它轉換後的數據的類似性喪失了。字符串
咱們說局部敏感哈希要求可以保持數據的類似性,那麼不少人懷疑這樣的哈希函數是否真的存在。咱們這樣去思考這樣一個極端的條件,假設一個局部敏感哈希函數具備10個不一樣的輸出值,而如今咱們具備11個徹底沒有類似度的數據,那麼它們通過這個哈希函數必然至少存在兩個不類似的數據變爲了類似數據。從這個假設中,咱們應該意識到局部敏感哈希是相對的,並且咱們所說的保持數據的類似度不是說保持100%的類似度,而是保持最大可能的類似度。
對於局部敏感哈希「保持最大可能的類似度」的這一點,咱們也能夠從數據降維的角度去考慮。數據對應的維度越高,信息量也就越大,相反,若是數據進行了降維,那麼毫無疑問數據所反映的信息必然會有損失。哈希函數從本質上來看就是一直在扮演數據降維的角色。
3. 文檔類似度計算
咱們經過利用LSH來實現文檔的類似度計算這個實例來介紹一下LSH的具體用法。
3.1 Shingling
假設如今有4個網頁,咱們將它們分別進行Shingling(將待查詢的字符串集進行映射,映射到一個集合裏,如字符串「abcdeeee", 映射到集合」(a,b,c,d,e)", 注意集合中元素是無重複的,這一步驟就叫作Shingling, 意即構建文檔中的短字符串集合,即shingle集合。),獲得以下的特徵矩陣:
其中「1」表明對應位置的Shingles在文檔中出現過,「0」則表明沒有出現過。
在衡量文檔的類似度中,咱們有不少的方法去完成,好比利用歐式距離、編輯距離、餘弦距離、Jaccard距離等來進行類似度的度量。在這裏咱們運用Jaccard類似度。接下來咱們就要去找一種哈希函數,使得在hash後儘可能還能保持這些文檔之間的Jaccard類似度,即:
咱們的目標就是找到這樣一種哈希函數,若是原來文檔的Jaccard類似度高,那麼它們的hash值相同的機率高,若是原來文檔的Jaccard類似度低,那麼它們的hash值不相同的機率高,咱們稱之爲Min-hashing(最小哈希)。
3.2 Min-hashing
Min-hashing定義爲:特徵矩陣按行進行一個隨機的排列後,第一個列值爲1的行的行號。舉例說明以下,假設以前的特徵矩陣按行進行的一個隨機排列以下:
元素 |
S1 |
S2 |
S3 |
S4 |
他 |
0 |
0 |
1 |
0 |
成功 |
0 |
0 |
1 |
1 |
我 |
1 |
0 |
0 |
0 |
減肥 |
1 |
0 |
1 |
1 |
要 |
0 |
1 |
0 |
1 |
最小哈希值: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這兩列,它們所在的行的全部可能結果能夠分紅以下三類:
(1)A類:兩列的值都爲1;
(2)B類:其中一列的值爲0,另外一列的值爲1;
(3)C類:兩列的值都爲0.
特徵矩陣至關稀疏,致使大部分的行都屬於C類,但只有A、B類行的決定sim(Si,Sj),假定A類行有a個,B類行有b個,那麼sim(si,sj)=a/(a+b)。如今咱們只須要證實對矩陣行進行隨機排列,兩個的最小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類行的數目/全部行的數目=a/(a+b),這就是最小hash的神奇之處。
Min-hashing的具體作法能夠根據以下進行表述:
返回到咱們的實例,咱們首先生成一堆隨機置換,把特徵矩陣的每一行進行置換,而後hash function就定義爲把一個列C hash成一個這樣的值:就是在置換後的列C上,第一個值爲1的行的行號。以下圖所示: