區域性敏感雜湊(Locality-Sensitive Hashing, LSH)方法介紹

chinabing發表於2017-07-06

區域性敏感雜湊(Locality-Sensitive Hashing, LSH)方法介紹

本文主要介紹一種用於海量高維資料的近似最近鄰快速查詢技術——區域性敏感雜湊(Locality-Sensitive Hashing, LSH),內容包括了LSH的原理、LSH雜湊函式集、以及LSH的一些參考資料。


一、區域性敏感雜湊LSH

在很多應用領域中,我們面對和需要處理的資料往往是海量並且具有很高的維度,怎樣快速地從海量的高維資料集合中找到與某個資料最相似(距離最近)的一個資料或多個資料成為了一個難點和問題。如果是低維的小資料集,我們通過線性查詢(Linear Search)就可以容易解決,但如果是對一個海量的高維資料集採用線性查詢匹配的話,會非常耗時,因此,為了解決該問題,我們需要採用一些類似索引的技術來加快查詢過程,通常這類技術稱為最近鄰查詢(Nearest  Neighbor,AN),例如K-d tree;或近似最近鄰查詢(Approximate Nearest  Neighbor, ANN),例如K-d tree with BBF, Randomized Kd-trees, Hierarchical K-means Tree。而LSH是ANN中的一類方法。


我們知道,通過建立Hash Table的方式我們能夠得到O(1)的查詢時間效能,其中關鍵在於選取一個hash function,將原始資料對映到相對應的桶內(bucket, hash bin),例如對資料求模:h = x mod w,w通常為一個素數。在對資料集進行hash 的過程中,會發生不同的資料被對映到了同一個桶中(即發生了衝突collision),這一般通過再次雜湊將資料對映到其他空桶內來解決。這是普通Hash方法或者叫傳統Hash方法,其與LSH有些不同之處。



區域性敏感雜湊示意圖(from: Piotr Indyk)


LSH的基本思想:將原始資料空間中的兩個相鄰資料點通過相同的對映或投影變換(projection)後,這兩個資料點在新的資料空間中仍然相鄰的概率很大,而不相鄰的資料點被對映到同一個桶的概率很小。也就是說,如果我們對原始資料進行一些hash對映後,我們希望原先相鄰的兩個資料能夠被hash到相同的桶內,具有相同的桶號。

對原始資料集合中所有的資料都進行hash對映後,我們就得到了一個hash table,這些原始資料集被分散到了hash table的桶內,每個桶會落入一些原始資料,屬於同一個桶內的資料就有很大可能是相鄰的,當然也存在不相鄰的資料被hash到了同一個桶內。因此,如果我們能夠找到這樣一些hash functions,使得經過它們的雜湊對映變換後,原始空間中相鄰的資料落入相同的桶內的話,那麼我們在該資料集合中進行近鄰查詢就變得容易了,我們只需要將查詢資料進行雜湊對映得到其桶號,然後取出該桶號對應桶內的所有資料,再進行線性匹配即可查詢到與查詢資料相鄰的資料。換句話說,我們通過hash function對映變換操作,將原始資料集合分成了多個子集合,而每個子集合中的資料間是相鄰的且該子集合中的元素個數較小,因此將一個在超大集合內查詢相鄰元素的問題轉化為了在一個很小的集合內查詢相鄰元素的問題,顯然計算量下降了很多。


那具有怎樣特點的hash functions才能夠使得原本相鄰的兩個資料點經過hash變換後會落入相同的桶內?這些hash function需要滿足以下兩個條件:

1)如果d(x,y) ≤ d1, 則h(x) = h(y)的概率至少為p1;

2)如果d(x,y) ≥ d2, 則h(x) = h(y)的概率至多為p2;

其中d(x,y)表示x和y之間的距離,d1 < d2, h(x)和h(y)分別表示對x和y進行hash變換。

滿足以上兩個條件的hash functions稱為(d1,d2,p1,p2)-sensitive。而通過一個或多個(d1,d2,p1,p2)-sensitive的hash function對原始資料集合進行hashing生成一個或多個hash table的過程稱為Locality-sensitive Hashing。



使用LSH進行對海量資料建立索引(Hash table)並通過索引來進行近似最近鄰查詢的過程如下:

1. 離線建立索引

(1)選取滿足(d1,d2,p1,p2)-sensitive的LSH hash functions;

(2)根據對查詢結果的準確率(即相鄰的資料被查詢到的概率)確定hash table的個數L,每個table內的hash functions的個數K,以及跟LSH hash function自身有關的引數;

(3)將所有資料經過LSH hash function雜湊到相應的桶內,構成了一個或多個hash table;

2. 線上查詢

(1)將查詢資料經過LSH hash function雜湊得到相應的桶號;

(2)將桶號中對應的資料取出;(為了保證查詢速度,通常只需要取出前2L個資料即可);

(3)計算查詢資料與這2L個資料之間的相似度或距離,返回最近鄰的資料;


LSH線上查詢時間由兩個部分組成: (1)通過LSH hash functions計算hash值(桶號)的時間;(2)將查詢資料與桶內的資料進行比較計算的時間。因此,LSH的查詢時間至少是一個sublinear時間。為什麼是“至少”?因為我們可以通過對桶內的屬於建立索引來加快匹配速度,這時第(2)部分的耗時就從O(N)變成了O(logN)或O(1)(取決於採用的索引方法)。


LSH為我們提供了一種在海量的高維資料集中查詢與查詢資料點(query data point)近似最相鄰的某個或某些資料點。需要注意的是,LSH並不能保證一定能夠查詢到與query data point最相鄰的資料,而是減少需要匹配的資料點個數的同時保證查詢到最近鄰的資料點的概率很大。




二、LSH的應用


LSH的應用場景很多,凡是需要進行大量資料之間的相似度(或距離)計算的地方都可以使用LSH來加快查詢匹配速度,下面列舉一些應用:

(1)查詢網路上的重複網頁

網際網路上由於各式各樣的原因(例如轉載、抄襲等)會存在很多重複的網頁,因此為了提高搜尋引擎的檢索質量或避免重複建立索引,需要查詢出重複的網頁,以便進行一些處理。其大致的過程如下:將網際網路的文件用一個集合或詞袋向量來表徵,然後通過一些hash運算來判斷兩篇文件之間的相似度,常用的有minhash+LSH、simhash。

(2)查詢相似新聞網頁或文章

與查詢重複網頁類似,可以通過hash的方法來判斷兩篇新聞網頁或文章是否相似,只不過在表達新聞網頁或文章時利用了它們的特點來建立表徵該文件的集合。

(3)影象檢索

在影象檢索領域,每張圖片可以由一個或多個特徵向量來表達,為了檢索出與查詢圖片相似的圖片集合,我們可以對圖片資料庫中的所有特徵向量建立LSH索引,然後通過查詢LSH索引來加快檢索速度。目前影象檢索技術在最近幾年得到了較大的發展,有興趣的讀者可以檢視基於內容的影象檢索引擎的相關介紹。

(4)音樂檢索

對於一段音樂或音訊資訊,我們提取其音訊指紋(Audio Fingerprint)來表徵該音訊片段,採用音訊指紋的好處在於其能夠保持對音訊發生的一些改變的魯棒性,例如壓縮,不同的歌手錄製的同一條歌曲等。為了快速檢索到與查詢音訊或歌曲相似的歌曲,我們可以對資料庫中的所有歌曲的音訊指紋建立LSH索引,然後通過該索引來加快檢索速度。

(5)指紋匹配

一個手指指紋通常由一些細節來表徵,通過對比較兩個手指指紋的細節的相似度就可以確定兩個指紋是否相同或相似。類似於圖片和音樂檢索,我們可以對這些細節特徵建立LSH索引,加快指紋的匹配速度。



三、LSH family

我們在第一節介紹了LSH的原理和LSH hash function需要滿足的條件,回顧一下:

滿足以下兩個條件的hash functions稱為(d1,d2,p1,p2)-sensitive:

1)如果d(x,y) ≤ d1, 則h(x) = h(y)的概率至少為p1;

2)如果d(x,y) ≥ d2, 則h(x) = h(y)的概率至多為p2;


d(x,y)是x和y之間的一個距離度量(distance measure),需要說明的是,並不是所有的距離度量都能夠找到滿足locality-sensitive的hash functions。


下面我們介紹一些滿足不同距離度量方式下的locality-sensitive的hash functions:

1. Jaccard distance

Jaccard distance: (1 - Jaccard similarity),而Jaccard similarity = (A intersection B) / (A union B),Jaccard similarity通常用來判斷兩個集合的相似性。

Jaccard distance對應的LSH hash function為:minhash,其是(d1,d2,1-d1,1-d2)-sensitive的。


2. Hamming distance

Hamming distance: 兩個具有相同長度的向量中對應位置處值不同的次數。

Hamming distance對應的LSH hash function為:H(V) = 向量V的第i位上的值,其是(d1,d2,1-d1/d,1-d2/d)-sensitive的。


3. Cosine distance 

Cosine distance:cos(theta) = A·B / |A||B| ,常用來判斷兩個向量之間的夾角,夾角越小,表示它們越相似。


Cosine distance對應的LSH hash function為:H(V) = sign(V·R),R是一個隨機向量。V·R可以看做是將V向R上進行投影操作。其是(d1,d2,(180-d1)180,(180-d2)/180)-sensitive的。


理解:利用隨機的超平面(random hyperplane)將原始資料空間進行劃分,每一個資料被投影后會落入超平面的某一側,經過多個隨機的超平面劃分後,原始空間被劃分為了很多cell,而位於每個cell內的資料被認為具有很大可能是相鄰的(即原始資料之間的cosine distance很小)。


4. normal Euclidean distance

Euclidean distance是衡量D維空間中兩個點之間的距離的一種距離度量方式


Euclidean distance對應的LSH hash function為:H(V) = |V·R + b| / a,R是一個隨機向量,a是桶寬,b是一個在[0,a]之間均勻分佈的隨機變數。V·R可以看做是將V向R上進行投影操作。其是(a/2,2a,1/2,1/3)-sensitive的。

理解:將原始資料空間中的資料投影到一條隨機的直線(random line)上,並且該直線由很多長度等於a的線段組成,每一個資料被投影后會落入該直線上的某一個線段上(對應的桶內),將所有資料都投影到直線上後,位於同一個線段內的資料將被認為具有很大可能是相鄰的(即原始資料之間的Euclidean distance很小)。



四、增強LSH(Amplifying LSH


通過LSH hash functions我們能夠得到一個或多個hash table,每個桶內的資料之間是近鄰的可能性很大。我們希望原本相鄰的資料經過LSH hash後,都能夠落入到相同的桶內,而不相鄰的資料經過LSH hash後,都能夠落入到不同的桶中。如果相鄰的資料被投影到了不同的桶內,我們稱為false negtive;如果不相鄰的資料被投影到了相同的桶內,我們稱為false positive。因此,我們在使用LSH中,我們希望能夠儘量降低false negtive rate和false positive rate。


通常,為了能夠增強LSH,即使得false negtive rate和/或false positive rate降低,我們有兩個途徑來實現:1)在一個hash table內使用更多的LSH hash function;2)建立多個hash table。


下面介紹一些常用的增強LSH的方法:


1. 使用多個獨立的hash table

每個hash table由k個LSH hash function建立,每次選用k個LSH hash function(同屬於一個LSH function family)就得到了一個hash table,重複多次,即可建立多個hash table。多個hash table的好處在於能夠降低false positive rate。


2. AND 與操作

從同一個LSH function family中挑選出k個LSH function,H(X) = H(Y)有且僅當這k個Hi(X) = Hi(Y)都滿足。也就是說只有當兩個資料的這k個hash值都對應相同時,才會被投影到相同的桶內,只要有一個不滿足就不會被投影到同一個桶內。


AND與操作能夠使得找到近鄰資料的p1概率保持高概率的同時降低p2概率,即降低了false positive rate  (原文為false negtive rate)。


3. OR 或操作

從同一個LSH function family中挑選出k個LSH function,H(X) = H(Y)有且僅當存在一個以上的Hi(X) = Hi(Y)。也就是說只要兩個資料的這k個hash值中有一對以上相同時,就會被投影到相同的桶內,只有當這k個hash值都不相同時才不被投影到同一個桶內。


OR或操作能夠使得找到近鄰資料的p1概率變的更大(越接近1)的同時保持p2概率較小,即降低了false negative rate(原文為false positive rate)。


4. AND和OR的級聯

將與操作和或操作級聯在一起,產生更多的hahs table,這樣的好處在於能夠使得p1更接近1,而p2更接近0。



除了上面介紹的增強LSH的方法外,有時候我們希望將多個LSH hash function得到的hash值組合起來,在此基礎上得到新的hash值,這樣做的好處在於減少了儲存hash table的空間。下面介紹一些常用方法:

1. 求模運算

new hash value = old hash value % N


2. 隨機投影

假設通過k個LSH hash function得到了k個hash值:h1, h2..., hk。那麼新的hash值採用如下公式求得:

new hash value = h1*r1 + h2*r2 + ... + hk*rk,其中r1, r2, ..., rk是一些隨機數。


3. XOR異或

假設通過k個LSH hash function得到了k個hash值:h1, h2..., hk。那麼新的hash值採用如下公式求得:

new hash value = h1 XOR h2 XOR h3 ... XOR hk




五、相關參考資料


Website:

[1] http://people.csail.mit.edu/indyk/ (LSH原作者)

[2] http://www.mit.edu/~andoni/LSH/ (E2LSH)


Paper:

[1] Approximate nearest neighbor: towards removing the curse of dimensionality

[2] Similarity search in high dimensions via hashing

[3] Locality-sensitive hashing scheme based on p-stable distributions 

[4] MultiProbe LSH Efficient Indexing for HighDimensional Similarity Search

[5] Near-Optimal Hashing Algorithms for Approximate Nearest Neighbor in High Dimensions

Tutorial:

[1] Locality-Sensitive Hashing for Finding Nearest Neighbors

[2] Approximate Proximity Problems in High Dimensions via Locality-Sensitive Hashing

[3] Similarity Search in High Dimensions


Book:

[1] Mining of Massive Datasets
[2] Nearest Neighbor Methods in Learning and Vision: Theory and Practice


Cdoe:

[1] http://sourceforge.net/projects/lshkit/?source=directory

[2] http://tarsos.0110.be/releases/TarsosLSH/TarsosLSH-0.5/TarsosLSH-0.5-Readme.html 

[3] http://www.cse.ohio-state.edu/~kulis/klsh/klsh.htm 

[4] http://code.google.com/p/likelike/ 

[5] https://github.com/yahoo/Optimal-LSH

[6] OpenCV LSH(分別位於legacy module和flann module中)


宣告:

作者:icvpr  | blog.csdn.net/icvpr

相關文章