1. 程式人生 > >LSHash(區域性敏感雜湊)

LSHash(區域性敏感雜湊)

原載:http://cool.sinaapp.com
作者:junGle
原文網址:http://1.cool.sinaapp.com/?p=911

前文所說的minhash,比較的是jaccard相似度,基於兩兩來比較的話,如果文件數很大,比如:100w文件,根據排列組合公式可知,需要對比5000億次。如果兩篇文件簽名相似度比較需要花費1微秒,那需要花費6天時間。

有啥辦法能快速進行比較呢?有的,區域性敏感雜湊(locality-sensitive hashing, LSH)。

目標:減少對比次數

方法:通過多次雜湊處理,讓相似項儘可能落到同一桶中(確實相似的稱為候選對,非相似的稱為偽正例). 不相似的文件最好永遠都不會雜湊到相同的桶中。

————————————————————————————

一、MinHash的區域性敏感雜湊

以MinHash及其簽名矩陣為例。

一個有效的雜湊處理方法:將簽名矩陣劃分成多個band(行條, 行帶),每個band由r行組成。對每個band,存在一個雜湊函式能夠將band中的每r個整陣列成的列向量對映到某個大數目範圍的雜湊桶。對所有band使用相同的雜湊函式,但是每個band都落在一個獨立的桶陣列中,因而保證了不同band間即使有列向量相同,也不會落到同一個桶中。

以12行的簽名矩陣為例(每個band由3行組成):

假設:當且僅當兩個向量相等時,才雜湊到同一桶中

對於band1中, [0,2,1],有兩列相同,因而落在相同桶中。[1,3,0]和[0,2,1]落在不同桶中。

整體上看,如果簽名矩陣中的兩列越相似,多個band中的向量相等的可能性也越大。

二、分析

假設:有b個行條(band),每個band都由r行組成,並假定對具體文件間的jaccard相似度為s。那麼,文件的最小雜湊簽名矩陣中,某個具體行中的兩個簽名相等的概率等於s.

  • 1.在某個band中,所有行的兩兩簽名相等的概率為  :s^r;     (冪運算)
  • 2.在某個band中,至少有一對簽名不相等的概率為:1-s^r;
  • 3.在任何band中,任意一行的簽名對都不相等的概率為:(1-s^r)^b;
  • 4.簽名至少在一個band中全部相等的概率(成為候選對的概率):1-(1-s^r)^b;

成為候選對的概率:1-(1-s^r)^b。這個概率函式曲線(S曲線:S-curve)如下所示。上升最陡的地方對應的相似度就是閥值(它是b和r的函式,閥值的一個近似估計是:(1/b)^(1/r))。

當b=20, r=5時,成為候選對的概率為:1-(1-s^5)^20, s的取值(相似程度)決定了候選對“抱團”的質量。

可以看到,當s=0.8時,1-(0.8)^5為0.328,其概率可以達到0.9996,也就是說,如果認為兩篇文件的相似度達80%時,如果有3000個對,大致只有1個對相似度為80%的對不會成為候選對(3000*(1-0.9996)=1.2左右)。

【簡單介紹下Jaccard距離】

d(x,y)=1-SIM(x,y)

三、區域性敏感函式

3.1  (d1, d2, p1, p2)-sensitive

我們需要一個判定函式,函式f判定f(x,y)的兩個輸入項是否為候選對。

  • x和y是一個候選對,用f(x)=f(y)表示
  • x和y不是候選對,用f(x)≠f(y)表示

多個這種形式的函式集合構成一個“函式族”F。函式族F中的每個函式f,都基於特徵矩陣的一個可能行排列轉換而成。

令d1<d2是定義在某個距離測度d下的兩個距離值。如果一個函式族F中的每一個函式f都滿足下列條件:

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

(2)如果d(x,y)≥d2,那麼f(x)=f(y)的概率最大是p2.

則稱F為(d1,d2,p1,p2)-敏感的函式族;

有點“馬太效應” 的味道在裡頭。

對於MinHash來說,換一個方法解釋最小雜湊函式h:當且僅當h(x)=h(y)時,x和y是一個候選對。(很容易理解)

於是有結論:

對於任意d1,d2,0≤d1<d2≤1,最小雜湊函式族是 (d1, d2, 1-d1, 1-d2)-敏感 的。

推導:如果x,y的jaccard距離d(x,y)≤d1, 那麼SIM(x,y)=1-d(x,y)≥1-d1。由x,y的jaccard相似度等於h(x)=h(y)的概率可知,上述p1≥SIM(x,y)≥1-d1。 對d2的推導類似。

設d1=0.3, d2=0.6,可以斷言最小雜湊函式族是 (0.3, 0.6, 0.7, 0.4)-sensitive 的。

也就是說,

如果x和y的jaccard距離不大於0.3, 那麼x,y雜湊到相同值的概率至少為0.7.

如果x和y之間的jaccard距離不小於0.6,那麼最小雜湊函式將x和y雜湊到相同值的概率至多為0.4.

3.2  與構造:(d1, d2, p1^r, p2^r)-sensitive

F ‘ 的成員函式由r個F成員函式組成。=> 降低所有概率

3.3 或構造:(d1, d2, 1-(1-p1)^b, 1-(1-p2)^b)-sensitive

F ‘ 的成員函式f由b個F中的成員函式{f1, f2, f3, … , fb}組成。=> 提升所有概率

===========================================

simhash的漢明距離

4. 利用 Simhash 查詢相似文件

已知兩篇文件 Simhash 值之間的海明距離越小,Jaccard 相似度越高,假設我們能夠接受的最大海明距離為K,根據上面對 LSH 的描述,我們可以實現一種快速查詢相似文件的方法:

  1. 對文件集中的每一篇文件:
    • 計算一個 N 位的 Simhash 值,
    • 對值按位做 T 次隨機排列,得到 T 個 N 位的值,
    • 對每個值取前 P 位生成 Key 存入詞典,Value 為原 Simhash 值;
  2. 查詢時:
    • 對查詢文件生成一個 N 位的 Simhash 值,
    • 對值按位做 T 次隨機排列,得到 T 個 N 位的值,
    • 對每個值取前 P 位生成 Key 查詢詞典,計算原 Simhash 值和 Value 間的海明距離,
    • 如果小於 K,則加入到結果中。

假設文件集中有一篇文件和查詢文件的 Simhash 值間海明距離為 K,則上述查詢過程能夠找到這個文件(即Key 命中)的概率:

  1. 對某個排列,前 K 位相同的概率為:(1-K/N)**P
  2. 對某個排列,前 K 位不相同的概率為:1 - (1-K/N)**P
  3. 對 T 次排列,前 K 位都不相同的概率為:(1 - (1-K/N)**P)**T
  4. 對 T 次排列,前 K 位至少有一次相同的概率為:1 - (1 - (1-K/N)**P)**T
    因此, Key 命中的概率為 1 - (1 - (1-K/N)**P)**T

例如當 N=64,P=16,K=6,T=8 時,P = 0.791520

2.漢明距離 計算x,y裡面不同bit的個數。 這個也很簡單,hash函式集合F中,fi(x) = xi即可 其實這個和simhash的後續處理一致

對於haming距離

假設兩條相似訊息的simhash每一位相同的概率為p
從64位裡隨機選取a位
這a位數相同的概率是p^a,不同的概率就是1-p^a
進行b次選取,每次取的a位數都不相同的概率就是(1-p^a)^b
這b次選取中有1次或以上a位數相同的概率是y=1-(1-p^a)^b

若漢明距離閥值定為8(<8即相似),那麼對於兩條相似的訊息,p=(64-8)/64=0.875
然後,我們可以定義b個不同的0-64的排列,每個排列選前a個數,表示“隨機選取a位,組成一個a位數”。
對每條訊息,都計算b次這樣的a位數,作為b個索引。
假設a=16,b=10,若一條訊息是命中相似的,則有y=1-(1-0.875^16)^10 = 0.715=71%的概率可以通過以上方法建立的索引找到與其相似的訊息

假設有100w訊息,大約每條訊息只要經過100w/(2^16)*10=152次漢明距離計算就有一定概率找到確實與其相似的訊息,計算量降低了不少.