minHash最小哈希原理


minHash最小哈希原理

  • 發表於 9個月前
  • 閱讀 208
  • 收藏 9
  • 點贊 1
  • 評論 0
摘要: 在數據挖掘中,一個最基本的問題就是比較兩個集合的相似度。通常通過遍歷這兩個集合中的所有元素,統計這兩個集合中相同元素的個數,來表示集合的相似度;這一步也可以看成特征向量間相似度的計算(歐氏距離,余弦相似度)。當這兩個集合里的元素數量異常大(特征空間維數很大),同時又有很多個集合需要判斷兩兩間的相似度時,傳統方法會變得十分耗時,最小哈希(minHash)可以用來解決該問題。

前言

       在數據挖掘中,一個最基本的問題就是比較兩個集合的相似度。通常通過遍歷這兩個集合中的所有元素,統計這兩個集合中相同元素的個數,來表示集合的相似度;這一步也可以看成特征向量間相似度的計算(歐氏距離,余弦相似度)。當這兩個集合里的元素數量異常大(特征空間維數很大),同時又有很多個集合需要判斷兩兩間的相似度時,傳統方法會變得十分耗時,最小哈希(minHash)可以用來解決該問題。

Jaccard相似度

       在本例中,我們僅探討集合的相似度,先來看Jaccard相似度。假設有兩個集合A,B,則

       Jaccard(A, B)= |A ∩ B| / |A ∪ B|,我們舉一個例子:

 

       在上述例子中,sim(A,B)=2/7。

minHash最小哈希

       假設現在有4個集合,分別為S1,S2,S3,S4;其中,S1={a,d}, S2={c}, S3={b,d,e}, S4={a,c,d},所以全集U={a,b,c,d,e}。我們可以構造如下0-1矩陣:

       為了得到各集合的最小哈希值,首先對矩陣進行隨機行打亂,則某集合(某一列)的最小哈希值就等於打亂后的這一列第一個值為1的行所在的行號。舉一個例子:

       定義一個最小哈希函數h,用於模擬對矩陣進行隨機行打亂,打亂后的0-1矩陣為

       如圖所示,h(S1)=2, h(S2)=4, h(S3)=0, h(S4)=2。

       在經過隨機行打亂后,兩個集合的最小哈希值相等的概率等於這兩個集合的Jaccard相似度,證明如下:

       現僅考慮集合S1和S2,那么這兩列所在的行有下面3種類型:
       1、S1和S2的值都為1,記為X
       2、只有一個值為1,另一個值為0,記為Y
       3、S1和S2的值都為0,記為Z

       S1和S2交集的元素個數為x,並集的元素個數為x+y,所以sim(S1,S2) = Jaccard(S1,S2) = x/(x+y)。接下來計算h(S1)=h(S2)的概率,經過隨機行打亂后,從上往下掃描,在碰到Y行之前碰到X行的概率為x/(x+y),即h(S1)=h(S2)的概率為x/(x+y)。

最小哈希簽名

---------------------------------------------------

 

最小簽名的計算

 

           其實得到上面的簽名矩陣之后,我們就可以用簽名矩陣中列與列之間的相似度來計算集合間的Jaccard相似度了;但是這樣會帶來一個問題,就是當一個特征矩陣很大時(假設有上億行),那么對其進行行打亂是非常耗時,更要命的是還要進行多次行打亂。               為了解決這個問題,可以通過一些隨機哈希函數來模擬行打亂的效果。具體做法如下:

 

           假設我們要進行n次行打亂,則為了模擬這個效果,我們選用n個隨機哈希函數h1,h2,h3…hn(注意,這里的h跟上面的h不是同一個哈希函數,只是為了方便,就不用其他字母了)。處理過程如下:

 

令SIG(i,c)表示簽名矩陣中第i個哈希函數在第c列上的元素。開始時,將所有的SIG(i,c)初始化為Inf(無窮大),然后對第r行進行如下處理:

 

1.      計算h1(r), h2(r)…hn(r);

 

2.      對於每一列c:

 

a)        如果c所在的第r行為0,則什么都不做;

 

b)        如果c所在的第r行為1,則對於每個i=1,2…n,將SIG(i,c)置為原來的SIG(i,c)和hi(r)之間的最小值。

 

(看不懂的直接看例子吧,這里講的比較晦澀)

 

例如,考慮上面的特征矩陣,將abcde換成對應的行號,在后面加上兩個哈希函數,其中h1(x)=(x+1) mod 5,h2(x) = (3*x+1) mod 5,注意這里x指的是行號:


接下來計算簽名矩陣。一開始時,全部初始化為Inf:


接着看特征矩陣中的第0行;這時S2和S3的值為0,所以無需改動;S1和S4的值為1,需改動。h1= 1,h2= 1。1比Inf小,所以需把S1和S4這兩個位置對應的值替換掉,替換后效果如下:


接着看第1行;只有S3的值為1;此時h1= 2,h2= 4;對S3那一列進行替換,得到:


接着看第2行;S2和S4的值為1;h1=3,h2=2;因為簽名矩陣S4那一列的兩個值都為1,比3和2小,所以只需替換S2那一列:


接着看第3行;S1,S3和S4的值都為1,h1=4, h2= 0;替換后效果如下:


接着看第4行;S3值為1,h1=0, h2= 3,最終效果如下:


這樣,所有的行都被遍歷一次了,最終得到的簽名矩陣如下:


基於這個簽名矩陣,我們就可以估計原始集合之間的Jaccard相似度了。由於S2和S4對應的列向量完全一樣,所以可以估計SIM(S1,S4)=1;同理可得SIM(S1,S3) = 0.5;


局部敏感哈希算法(LSH)

 

         通過上面的方法處理過后,一篇文檔可以用一個很小的簽名矩陣來表示,節省下很多內存空間;但是,還有一個問題沒有解決,那就是如果有很多篇文檔,那么如果要找出相似度很高的文檔,其中一種辦法就是先計算出所有文檔的簽名矩陣,然后依次兩兩比較簽名矩陣的兩兩;這樣做的缺點是當文檔數量很多時,要比較的次數會非常大。那么我們可不可以只比較那些相似度可能會很高的文檔,而直接忽略過那些相似度很低的文檔。接下來我們就討論這個問題的解決方法。

 

         首先,我們可以通過上面的方法得到一個簽名矩陣,然后把這個矩陣划分成b個行條(band),每個行條由r行組成。對於每個行條,存在一個哈希函數能夠將行條中的每r個整數組成的列向量(行條中的每一列)映射到某個桶中。可以對所有行條使用相同的哈希函數,但是對於每個行條我們都使用一個獨立的桶數組,因此即便是不同行條中的相同列向量,也不會被哈希到同一個桶中。這樣,只要兩個集合在某個行條中有落在相同桶的兩列,這兩個集合就被認為可能相似度比較高,作為后續計算的候選對;下面直接看一個例子:

 

例如,現在有一個12行簽名矩陣,把這個矩陣分為4個行條,每個行條有3行;為了方便,這里只寫出行條1的內容。


可以看出,行條1中第2列和第4列的內容都為[0,2,1],所以這兩列會落在行條1下的相同桶中,因此不過在剩下的3個行條中這兩列是否有落在相同桶中,這兩個集合都會成為候選對。在行條1中不相等的兩列還有另外的3次機會成為候選對,因為他們只需在剩下的3個行條中有一次相等即可。

         經過上面的處理后,我們就找出了相似度可能會很高的一些候選對,接下來我們只需對這些候選隊進行比較就可以了,而直接忽略那些不是候選對的集合

---------------------------------------------------

       那么,怎樣得到P( h(S1)=h(S2) )呢?我們僅需要進行N次哈希運算模擬N次隨機行打亂,然后統計|h(S1)=h(S2)|,就有 P=|h(S1)=h(S2)| / N 了。有了上一章節的證明,我們就可以通過多次進行最小哈希運算,來構造新的特征向量,也就是完成了降維,得到的新矩陣稱為最小哈希簽名矩陣。舉一個例子,假設進行2次最小哈希運算,h1(x)=(x+1) mod 5,h2(x) = (3*x+1) mod 5,可以得到簽名矩陣SIG:

       計算得到sim(S1,S4)=1,sim(S1,S3)=0.5。當然本例數據量太小,簽名矩陣的估計值跟真實Jaccard誤差較大。

       這里提供一種僅掃描一次就可以得到最小簽名矩陣的算法:

       令SIG(i,c)表示簽名矩陣中第i個哈希函數在第c列上的元素。開始時,將所有的SIG(i,c)初始化為Inf(無窮大),然后對第r行進行如下處理:
1. 計算h1(r), h2(r)…hn(r);
2. 對於每一列c:
       a) 如果c所在的第r行為0,則什么都不做;
       b) 如果c所在的第r行為1,則對於每個i=1,2…n,將SIG(i,c)=min(SIG(i,c),hi(r))。

       再看不懂的可以參考minHash(最小哈希)和LSH(局部敏感哈希)

MinHash的應用

       MinHash可以應用在推薦系統中,將上述0-1矩陣的橫軸看成商品,豎軸看成用戶,有成千上萬的用戶對有限的商品作出購買記錄,具體可以參考基於協同過濾,NMF和Baseline的推薦算法一文。MinHash也可以應用在自然語言處理的文本聚類中,將上述0-1矩陣的橫軸看成文檔,豎軸看成詞匯或n-gram。這里我提出一種基於依賴樹的同義詞聚類算法:

       假設現有沒有語法錯誤的文本集,我們使用依賴樹工具得到上圖的邊,先用TF-IDF逆文檔頻率過濾得到我們想要聚類的詞匯,然后用倒排索引建立類似ESA的詞匯-概念向量,例如:

       發展:nsubj(~,交通),advmod(~,比較),relcl(地方,~),mark(~,的)

       發達:nsubj(~,交通),advmod(~,比較),relcl(地方,~),mark(~,的)

       這樣,就有待聚類的詞匯有限,概念數量龐大的情形,應用minHash完成降維,再來聚類,具體可以參考從n-gram中文文本糾錯,到依存樹中文語法糾錯以及同義詞查找一文。

LSH局部敏感哈希

       我們得到簽名矩陣后,對集合還是需要進行兩兩比較,假如集合數量也極度龐大的話,我們希望僅比較那些相似度可能很高的集合,而直接忽略那些相似度很低的集合,LSH就可以用來解決該問題。

       LSH用到“桶”的概念,直接舉一個例子,現有一個12行的簽名矩陣,我們設置桶大小為3,則可分為4個桶,如下圖:

       對於S2,我們僅需要尋找那些桶相同的集合來計算相似度,例如:

       我們僅需要計算sim(S2, S3),sim(S2, S4),sim(S2, S5),因為這些集合出現過與S2桶相同的情況。再不懂可以看minHash(最小哈希)和LSH(局部敏感哈希)一文。

Reference

minHash(最小哈希)和LSH(局部敏感哈希)

MinHash (最小哈希)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM