局部敏感哈希(Locality-Sensitive Hashing, LSH)方法介紹

局部敏感哈希(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概率,即降低了falsenegtiverate


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 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章