1. 程式人生 > >高效相似度計算 LSH minHash simHash的學習

高效相似度計算 LSH minHash simHash的學習

joey 周琦

本文首先介紹了局部敏感雜湊的概念與用處,然後介紹了常見的快速計算相似度、尋找近鄰的方法minHash, simHash

區域性敏感雜湊Locality-sensitive hashing (LSH)

定義

首先我們看看wiki上比較準確的英文描述[1]。
An LSH family F is defined for a metric space M=(M,d) , a threshold R>0 and an approximation factor c>1. This family

F is a family of functions h:MS which map elements from the metric space to a bucket sS . The LSH family satisfies the following conditions for any two points p,qM , using a function h
F
which is chosen uniformly at random:

  • if d(p,q) R, then h(p)=h(q) (i.e.,p and q collide) with probability at least P1 ,
  • if d(p,q) cR, then h(p)=h(q) with probability at most P2
    .
    A family is interesting when P1>P2 . Such a family F is called (R,cR,P1,P2) -sensitive.

wiki關於metric space給出的定義

In mathematics, a metric space is a set for which distances between all members of the set are defined. Those distances, taken together, are called a metric on the set.

根據上述資訊,我中文理解下。 區域性敏感雜湊(Locality-sensitive hashing)是為了度量空間 M=(M,d) (metric space)定義的函式族,將度量空間的不同元素對映到相應的桶(bucket)中。滿足以下性質:

  • if d(p,q) R, then h(p)=h(q) (i.e.,p and q collide) with probability at least P1 ,
  • if d(p,q) cR, then h(p)=h(q) with probability at most P2 .
    A family is interesting when P1>P2 . Such a family F is called (R,cR,P1,P2) -sensitive.

其中 R 是一個閾值, c 是一個近似因子。 d 則是度量空間的一種距離的計算方式,常見的有餘弦距離,Jaccard距離,編輯距離等。上述兩個性質可以從下圖看的更明顯。這裡寫圖片描述

橫座標表示距離,縱座標可以理解兩個點(下面用“點”來統一代替文件,item,或物品等名稱,在應用都可以視為一種東西)被放入一個桶(即認為二者較為相似)的概率。可以看出LSH可以將距離較近的點以至少概率 p1 的概率歸為類似,距離遠的點至多有概率 p2 歸為類似

意義Motivation

一個演算法或概念的意義是很重要的。我們學習這個概念演算法到底可以解決什麼問題?適用於哪些場景?
剛才看了LSH的定義,那麼這個東西有啥用,哪些場景可以用呢?如何在海量資料中找到一個高維度點相似的點集合?(搜尋中找出最相關的query, 視訊業務中找到最接近重複的視訊,等等)最簡單的方法是計算每個點與該點的距離,然後排序。然後如果面對海量資料,這種暴力計算的方法是不可取的。如果我們可以找到一類函式LSH,高效率的將任意兩個點是否很接近找出來,就可以解決上述問題。常見的LSH方案有minHash,simHash. 下面分別簡單介紹下

minHash

相關概念

  • Jaccard similarity coefficient (Jaccard係數) 是常見的衡量兩個集合相似度的度量:
    J(A,B)=|AB||AB|
  • 利用矩陣代表集合,例:有四個集合 S1={a,d} , S2={c} , S3={b,d,e} , S4={a,c,d} ,可用下圖的矩陣表示[參考2]
    這裡寫圖片描述

minHashing

minHash ( min-wise independent permutation LSH scheme) 可以快速估計兩個集合的相似度。為了minHash一個集合,首先將該集合用矩陣表示,然後隨機選取行索引的一個排列(permutation), 該集合的minHash的值是按照這個排列遇見的第一個為1的行的索引。
下面看例子,將上述矩陣的行按照一個隨機的排列如下,那麼minHash( S1 )=a, minHash( S2 )=c, minHash( S3 )=b, minHash( S4 )=a
這裡寫圖片描述

性質

對於一個隨機的排列,兩個集合的minHash相等的概率等於兩個集合的Jaccard相似度

Pr[minHash(A)=minHash(B)]=J(A,B)
證明參考[2]第三章,例子也來自於此書。

假設 {S1,...SM} M個集合共有 N 個元素,即那個矩陣有 N 行, minHash的思想是隨機選取 n 個排列(permutation) , n<<N , 那麼我們可以用minHash得到的 n 維度向量 [h1(S),...,hn(S)]T 來代替集合 S ,可以看出原來 N 維度的向量被壓縮為了 n 維度。

在現實中排列一個很大的行索引也是很慢的,所以一般用隨機的雜湊函式來替代排列.

還是依據上面的矩陣表示,我們這裡用兩個雜湊函式(x+1 mod 5 和3x+1 mod 5)代表兩個排列.
這裡寫圖片描述

對於第一個排列(x+1 mod 5)的含義,新第0行對應的第4行,新的第一行為原來的第0行,所以第一個排列的順序為[4 0 1 2 3 4], 第二個排列為[3 0 2 4 1]. 那麼根據minHash的定義,我們可以得到
這裡寫圖片描述

當然這是我們根據肉眼看的,那麼如何通過一個演算法得到呢?
若S 表示集合的矩陣表示。初始化新的minHash矩陣K, 每列代表一個集合,每行代表一個排列,矩陣每個元素初始化為 . 下面 N 代表原來的feature個數, n 代表新的排列個數, M 代表集合個數。在例項中 N=5,n=2,M=4

1 根據雜湊算出每行的 h1(i),...,hn(i).(i=1...N)
2 For i = 1:N
For c = 1:M
如果S[i,c]為0;跳過
否則;對於每個排列r=1…n, K(r,c) = min ( K(r,c), h_r(i) )
上述例子的更新過程如下面幾幅圖這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

通過上面的過程,每個集合就可以用一個 n 維向量來表示,已經大大壓縮了資料,然而面對海量資料,若要找出任意兩個點的相似度,依然是一個很大的計算量。然後在很多應用中,我們之需要找出與某點相似的點的集合即可,而不用算出每個pair對的相似度。

書[2]中描述了一種桶方式,可以高效率的找出相似的pair對。上面得到向量可以分為 b 段(桶),每個段有 r 個行,假設兩個點的Jaccard相似度為 s ,根據“minHash的值相等的概率等於Jaccard相似度”這個定理,若兩個點在某個段完全相同,則認為這兩個點為相似對。分析如下

  • 兩個點在一個段中,完全一樣的概率為 sr
  • 兩個點在一個段中,不完全一樣的概率為 1sr
  • 兩個點在所有段中,不完全一樣的概率為 (1