原文:http://blog.csdn.net/yc461515457/article/details/48845775?locationNum=1
LSH(Locality Sensitive Hashing)
- 一、局部敏感哈希LSH
- 二、Hamming 距離
- 三、Euclidean 距離
- 四、Jaccard 系數
- 五、參考資料
在很多問題中,從海量數據庫中尋找到與查詢數據相似的數據是一個很關鍵的問題。比如在圖片檢索領域,需要找到與查詢圖像相似的圖片,又比如在3D維重建和 視覺SLAM等問題中,需要在3維點云模型(數據庫)中找到與查詢描述子最相近的描述子,以實現特征匹配。這個問題也叫近似近鄰問題 Approximate Near Neighbor。當數據中的數據量很大時(百萬以上),線性查找是不實際的,kd-tree是一個很好算法,但是當數據的維數很高時,kd-tree的性能將變得很差(kd-tree只適用數據在30維以下)。對于高維數據的海量數據近鄰查找,局部敏感哈希是一個很好的解決方法。
?局部敏感哈希(Locality Sensitive Hashing)是一個方法,應用到不同數據的距離度量時,兩個數據之間的相似性(相似性往往是和距離是負相關的)有不同的衡量,那么就需要不同的算法。下面我先總體介紹局部敏感哈希方法,然后針對不同的距離度量空間來具體展開介紹,主要包括了Hamming距離、Euclidean距離、Jaccard 系數、余弦相似度。
如上圖是一個圖片檢索的例子,應用LSH可以從海量數據庫中快速檢索出所查詢的圖片。
一、局部敏感哈希LSH
先說說哈希Hash,哈希是通過一個哈希函數(Hash function)將數據映射到一個哈希表(Hash Table),通過哈希表的索引,來使搜索時間從線性搜索的O(N)降到O(1)。這里的關鍵在于哈希函數的選取,對于不同的應用和數據會有不用的哈希函數。
局部敏感哈希的基本思想:在高維數據空間中的兩個相鄰的數據被映射到低維數據空間中后,將會有很大的概率任然相鄰;而原本不相鄰的兩個數據,在低維空間中也將有很大的概率不相鄰。通過這樣一映射,我們可以在低維數據空間來尋找相鄰的數據點,避免在高維數據空間中尋找,因為在高維空間中會很耗時。有這樣性質的哈希映射稱為是局部敏感的。
局部敏感哈希定義:
一個哈希函數族滿足如下條件時,被稱為是(R,cR,P1,P2)-sensitvie,對于任意兩個點??p,q∈Rd:
為了讓局部敏感哈希函數族起作用,需要滿足c>1,P1>P2.
舉個例子來說明這個概念。考慮二進制的兩個數據點p,q,它們的每一個比特位要么是0要么是1。它們之間的距離是用Hamming距離來計算的,也是就不同的比特位數。我們使用一個很簡單的哈希函數族H,每一個哈希函數是隨機的選擇一個特定的比特位上的值,H包含了所有的從{0,1}d映射到{0,1}的函數,并且有hi(p)=pi。從H中隨機地選擇哈希函數h,那么hi(p)將會隨機地返回p的一個比特位。?
那么Pr[h(p)=h(q)]就等于p,q中相同的比特位數的比例,因此有P1=1?R/d,P2=1?cR/d,對于任意的c>1,都滿足P1>P2。即這種構造出來的哈希函數族是局部敏感的![1]
Emdedding:
上面講的一個例子因為數據本身剛好就是二進制,使用的Hamming距離,不需要其他的操作,但是實際上在最開始提出LSH時,是還有一個Embedding操作的。
Original LSH在哈希之前,首先要先將數據從L1準則下的歐幾里得空間嵌入到Hamming空間,因為L2準則下的歐幾里得空間沒有直接的方法嵌入到Hamming空間。在做此Embedding時,有一個假設就是原始點在L1準則下的效果與在L2準則下的效果相差不大,即歐氏距離和曼哈頓距離的差別不大。
Embedding算法:?
1. 找到所有點的所有坐標值中的最大值C;?
2. 對于一個點P來說,P=(x1,x2,…,xd),d是數據的維度;?
3. 將每一維xi轉換為一個長度為C的0/1序列,其中序列的前xi個值為1,剩余的為0.?
4. 然后將d個長度為C的序列連接起來,形成一個長度為Cd的序列.
值得說明的是,Embedding操作是保距離的,即在Embedding前后兩個點之間的距離是不變的。更多細節可看論文[2]
概率放大:
一個哈希函數族的概率P1,P2之間的差不夠大,通常會通過增加哈希鍵的長度k和哈希表的個數L來增加P1,P2之間的差。搜索多個哈希表后找出Candidates,然后進行線性搜索,這時只要有一個哈希表能夠找到真實近鄰就能保證最終能找到近鄰。理想的情況是對于距離在R以內的點,通過哈希映射后距離為0,對于距離在cR?以外的點,距離為1(這里1是歸一化后的距離)。如何做到這個呢??
想要的概率曲線 ?
單個哈希的概率曲線 ?
b個哈希表、哈希鍵長度為r時的概率曲線
我們選擇參數k,L,有L個哈希函數gj(q)=(h1,j(q),h2,j(q),...,hk,j(q)),其中hk,j(q)(1≤t≤k,1≤j≤L)?
若哈希鍵的長度為k,由于哈希函數的選擇都是獨立隨機選擇的,對一個每一個哈希函數gi,Pr[gi(p)=gi(q)]≥Pk1,那么使用L個哈希表找到真實近鄰的概率至少為1?(1?Pk1)L。
關于k,L的選擇說明,可以參考斯坦福課件[3],這里可以通過一個表簡單說一下。如下表所示,當k=4,L=4,對于p=0.9,1?(1?Pk1)L=0.9860,而對于概率較小的p,會使其值變得更小,比如對于p=0.5,1?(1?Pk1)L=0.2275,這樣的一個變化趨勢正是我們想要的!通常在應用中會選擇更大的k,L。?
搜索近似最近鄰:
在搜索近似最近鄰的時候,按照選擇的哈希函數來映射,對于每一個哈希表,選擇出落入的哈希桶里的所有節點,對L個哈希表都做相同操作,線性搜索所有的candidates。
總結一下,就是如下步驟:?
二、Hamming距離
在對圖像進行匹配時,通常是將圖像的描述子與數據中的圖像描述子進行匹配實現的。在實時應用中,通常是使用二進制描述子,比如BIREF、BRISK、ORB等。對于二進制描述子使用的是Hamming距離。下面就介紹關于Hamming距離的局部敏感哈希函數。
正如在上面所說的那樣,對于二進制描述子,哈希函數就是直接選擇描述子的某一個比特位,通過若干個哈希函數選擇出來的位的級聯,就形成了一個哈希鍵了。通過對這個哈希鍵對數據庫中的描述子進行索引,即形成了一個哈希表,選擇若干個哈希表來增大找到近似最近鄰的概率。
三、Euclidean距離
對于歐式距離,參考E2LSH,基于p-stable distribution的LSH(有時間再補上)
四、Jaccard 系數
LSH還可以用來查找相似新聞網頁或文章,這時候用來評價兩個網頁或者文章的相似度的量是Jaccard?系數。
Jaccard系數用來度量兩個集合的相似度,值越大值相似度越高。設有兩個集合S1和S2,它們之間的Jaccard系數定義為:?
s=∥S1∩S2∥∥S1∪S2∥
例如?S1=A,B,C,S2=B,C,D, 則s=24
上圖是一個總體的流程圖,分為三步:
第一步就是對一個文檔轉化為關鍵詞的集合,用這個集合來表示這個文檔,叫Shingling。?
第二步就是用MinHashing函數來構造哈希表。?
第三步就是使用LSH來尋找相似的文檔。
這里主要對MinHashing進行介紹。更多細節還是請看斯坦福的課件[3]。
當查詢文檔時,先Shingling,得到一個文檔和詞的關系,通常是一個列向量,這個列向量和原數據庫的所有列向量一起組成了一個矩陣。可以想象這個矩陣是個很稀疏的高維矩陣,行數是所有的詞匯的個數,列數是所有的文檔個數。直接用這個高維矩陣進行操作會很耗時,于是就要對其進行壓縮,這一步就是MinHashing,然后得到一個維數小得多的Signature矩陣,每一列還是表示一個文檔。得到Signature矩陣之后的操作就和前面一樣了,使用LSH就可以很快找到相似文檔了。
這里有一個很重要的一點,就是在進行MinHashing之后,相似度是保持不變的!正是因為如此才能保證在低維的Signature矩陣找到相似的列在原來的高維矩陣中仍然是相似的。這就保證了這樣的哈希函數是局部哈希函數族!
那么MinHashing是怎么做的呢?
上圖中白色框中為一個輸入矩陣,每一個列表示一個文檔,行表示一個關鍵詞。這里哈希函數就是hπ(C)=minπ(C)。首先重點內容定義一個變異(Permutation?π),這個變異操作將原來的矩陣的行之間交換。比如從咖啡紅表示的第一個變異,其序列值是{2,3,7,6,1,5,4},表示新的矩陣的每一行的行號是原來矩陣的哪一行。然后看變異后的矩陣每一列的第一個1出現在哪一行,行號就是該列元素值。這樣操作過后,每一個變異?π得到一個行向量,如圖中所示,咖啡紅表示的變異{2,3,7,6,1,5,4}得到的行向量為{2,1,2,1}。使用N個變異,即可以得到一個N行的矩陣,這個矩陣就是Signature Matrix。
右下角有關于對原矩陣和Signature矩陣的列的相似度的比較,可以看到,兩個矩陣的列的相似度很接近。事實上,后面會證明,從概率的意義上這兩者會是一樣的。
?直接定義π(y)=min(π(C1∪C2)),那么y要么屬于C1,要么屬于C2。所以y同時屬于C1,C2的概率就是Pr(y∈C1∩C2)。也就是說Pr[min(π(C1)=min(π(C2))]=∥C1∩C2)∥∥C1∪C2)∥。
換個角度理解,對于C1,C2的行分為三種:
- 類X: 兩個列的值都是1;
- 類Y: 一列是1,另一列是0;
- 類Z: 兩個列的值都是0;
由于是稀疏矩陣,所以絕大多數是Z類別。變異后隨機排列行,那么從上到下在遇到類Y之前遇到類X的概率是∥X∥∥X+Y∥,首先遇到的列類型是X,說明min(hπ(C1))=min(hπ(C2))。又有∥X∥=∥C1∩C2∥,∥X+Y∥=∥C1∪C2∥,所以可以得到∥X∥∥X+Y∥=∥C1∩C2)∥∥C1∪C2)∥。也同樣可以得到Pr[min(π(C1)=min(π(C2))]=∥X∥∥X+Y∥=∥C1∩C2)∥∥C1∪C2)∥。
對于式子Pr[min(π(C1)=min(π(C2))]=∥C1∩C2)∥∥C1∪C2)∥,右邊就是C1,C2的Jaccard系數!即證明了Pr[min(π(C1)=min(π(C2))]=sim(C1,C2)
到現在完成了第一步了。后面對于Signature矩陣的操作就和之前講的類似了。本質上都是通過AND和OR操作來提升概率差,得到我們想要的概率曲線。不過具體實現方式稍微有點不同。?
首先通過很多變異操作得到一個足夠大的Signature矩陣,然后對這個矩陣進行劃分,每r個行構成一個Band,總共有b個Bands,也就是說總共進行了r?b次變異操作,得到了一個行數為r?b的Signature矩陣。使用上面提到的MinHashing對每一個band單獨進行哈希,就得到了b個哈希表。
五、參考資料:
[1] Andoni A, Indyk P. Near-Optimal Hashing Algorithms for Approximate Nearest Neighbor in High Dimensions.?
[2] Gionis A, Indyk P, Motwani R. Similarity search in high dimensions via hashing.?
[3] Stanford CS246 關于LSH的章節?http://cs246.stanford.edu?
[4] Datar M, Immorlica N, Indyk P, et al. Locality-sensitive hashing scheme based on p-stable distributions.?
[5] E2LSH user manual?
[6] Slaney M, Casey M. Locality-Sensitive Hashing for Finding Nearest Neighbors [Lecture Notes]
頂1
踩