Lección 3 - Locality Sensitive Hashing - Teoría

Objetivo

El objetivo de esta lección es entender la teoría detrás de los métodos sensibles a la localidad.

Nota: Esta lección está basada en el Capítulo 3 del libro Mining of Massive Datasets. Rajaraman, Leskovec and Ullman 2012 y en las notas del curso de Métodos Analíticos del 2013 por Felipe Gonzalez.

Locality Sensitive Hashing

Familias de funciones sensibles a la localidad

Una familia $\textbf{F}$ de funciones es $(d_1, d_2, p_1, p_2)-sensible$ si para cada $f$ en $\textbf{F}$:

  1. Si $d(x,y) \le d_1$, entonces $P[f(x) = f(y)] \ge p_1$.
  2. Si $d(x,y) \ge d_2$, entonces $P[f(x) = f(y)] \le p_2$.

$f(x) = f(y)$ es una notación para "$x$ y $y$ son pares candidatos (generan el mismo valor) dada la función $f$".

Localidad en este contexto significa que puntos cercanos tienen alta probabilidad de generar el mismo valor y puntos lejanos tienen baja probabilidad de generar el mismo valor.


In [94]:
from IPython.display import Image
Image(filename='figs/lsh.png')


Out[94]:

La Figura 1 ilustra el comportamiento esperado de una función $(d_1, d_2, p_1, p_2)-sensible$

Minhash es una familia sensible a la localidad

La familia de funciones minhash es una familia $(d_1, d_2, (1 - d_1), (1 - d_2))-sensible$ para cualquier $d_1$ y $d_2$ dado $d_1 < d_2$.

Sabemos que la similitud de Jaccard entre dos elementos $x$ y $y$ es igual a la probabilidad de que tengan el mismo valor minhash $Sim(x,y) = P[h(x) = h(y)]$ y que dicha similitud es igual a $Sim(x,y) = 1 - d(x,y)$ donde $d$ es la distancia de Jaccard.

Por lo tanto, si $d(x,y) \le d_1$ entonces $P[h(x) = h(y)] = 1 - d(x,y) \ge 1 - d_1$.

Por ejemplo para $d_1 = 1/3$ y $d_2 = 3/4$ tenemos una familia $(1/3, 3/4, 2/3, 1/4)-sensible$, es decir:

  • Si la distancia de Jaccard entre $d(x,y) < 1/3$, entonces la probabilidad de que la función minhash asigne valores iguales a $x$ y $y$ es al menos $P[h(x) = h(y)] = 2/3$
  • De la misma manera si $d(x,y) > 3/4$, entonces la probabilidad de que la función minhash asigne valores iguales a $x$ y $y$ es a lo más $P[h(x) = h(y)] = 1/4$

In [4]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib

In [91]:
figure()
s = arange(0,1,0.01)
plot(s, s, 'g')
#axvline(x=.33, ls=':', color='r')
xlabel('Similitud (1-distancia)')
ylabel('Probabilidad de ser candidato')
title('Sim(x,y)=P[h(x)=h(y)]')
show()


Amplificación de una familia sensible a la localidad

Nos gustaría tener una función que con una cantidad de información limitada nos permita saber de manera aproximada cuales son los pares candidatos arriba de un umbral de similitud.

Idealmente esta función nos diría con un 100% de certeza que un par de elementos son candidatos si están arriba de ese umbral y que no son candidatos si están debajo.


In [95]:
Image(filename='figs/scurve.png')


Out[95]:

Podemos aproximar una curva de este tipo, amplificando una familia $(d_1, d_2, p_1, p_2)-sensible$ para que de una mayor o menor probabilidad de ser candidato a un par de elementos.

La $construccion-AND$ nos permite construir una nueva familia $\textbf{F}'$ a partir de una familia $(d_1, d_2, p_1, p_2)-sensible$ $\textbf{F}$.

Construimos una familia $\textbf{F}'$ a partir de $r$ funciones provenientes de la familia $\textbf{F}$.

  • Si $f$ proviene de $\textbf{F}'$, dadas $r$ funciones $f_1,\ldots,f_r$ provenientes de $\textbf{F}$ decimos que $f(x) = f(y)$ si y solo si $f_i(x) = f_i(y)$ para toda $i=1,2,\ldots,r$.
  • Dado que las $f_i$ son independientes decimos que $\textbf{F}'$ es $(d_1, d_2, (p_1)^r, (p_2)^r)-sensible$.

Recordemos que $f(x) = f(y)$ quiere decir que $x$ y $y$ son candidatos dada la función $f$.

La $construccion-OR$ nos permite construir una nueva familia $\textbf{F}'$ a partir de una familia $(d_1, d_2, p_1, p_2)-sensible$ $\textbf{F}$.

Construimos una familia $\textbf{F}'$ a partir de $b$ funciones provenientes de la familia $\textbf{F}$.

  • Si $f$ proviene de $\textbf{F}'$, dadas $b$ funciones $f_1,\ldots,f_b$ provenientes de $\textbf{F}$ decimos que $f(x) = f(y)$ si y solo si $f_i(x) = f_i(y)$ para al menos una $i=1,2,\ldots,r$.
  • Dado que las $f_i$ son independientes decimos que $\textbf{F}'$ es $(d_1, d_2, 1 - (1- p_1)^b, 1 - (1 - p_2)^b)-sensible$.

Veamos cual es el efecto de variar estos parámetros:


In [12]:
figure()
s = arange(0,1,0.01)
for r in range(1,10):
    plot(s, (s ** r), 'b')
xlabel('Similitud')
ylabel('Probabilidad de ser candidato')
title('AND r=1..10, b=1')
show()



In [26]:
figure()
s = arange(0,1,0.01)
for b in range(1,10):
    plot(s, 1 - (1 - s) ** b, 'b')
xlabel('Similitud')
ylabel('Probabilidad de ser candidato')
title('OR r=1, b=1..10')
show()


Podemos observar que estas construcciones modifican la probabilidad de declarar pares candidatos.

La $construccion-AND$ reduce la probabilidad de declarar un par de elementos pares candidatos.

Mientras que la $construccion-OR$ aumenta a probabilidad de declarar un par de elementos pares candidatos.

Es posible concatenar construcciones $AND$ y $OR$ para disminuir la probabilidad similitudes bajas y aumentarla para similitudes altas, como lo hicimos en LSH para la función minhash.


In [104]:
figure()
s = arange(0,1,0.01)
for r, b in [(2,10), (5,10), (10,5), (10,2)]:
    plot(s, 1 - (1 - s ** r) ** b, 'b')
    plot(s, (1 - (1 - s) ** b) ** r, 'r')
xlabel('Similitud')
ylabel('Probabilidad de ser candidato')
title('AND-OR OR-AND (r,b) = (2,10), (5,10), (10,5), (10,2)')
show()


Observamos la influencia de $r$ y $b$ para distintos valores de similitud conforme $r$ es mayor que $b$ y vice versa.

La gráfica también nos muestra que componer las funciones distinto orden afecta la probabilidad con la que la nueva familia declara un par como candidato.

La eficiencia con la que este procedimiento puede cambiar la probabilidad de que un par de elementos sean candidatos depende de los parámetros $r$ y $b$ seleccionados y de la forma en la que se concatenen las construcciones $AND$ y $OR$.

Por ejemplo, si definimos $r=4$ y $b=4$ utilizando la construcción $AND-OR$, esta configuración nos da un umbral apróximado $t=0.72$, veamos que tal aproxima en comparación con la familia de minhash.


In [101]:
figure()
s = arange(0,1,0.01)
r = 4
b = 4
plot(s, 1 - (1 - s ** r) ** b, 'b')
plot(s, s, 'g')
axvline(x=.72, color='r')
xlabel('Similitud')
ylabel('Probabilidad de ser candidato')
title('AND-OR r=4, b=4')
show()


Podemos observar que esta nueva familia reduce la probabilidad de observar tanto falsos positivos como falsos negativos.

  • Sin embargo aun queda una región abajo de la curva y a la izquierda del umbral en la que esta familia de funciones generará pares candidatos que no deberían de serlo (falsos positivos).
  • Y una región sobre la curva a la derecha del ubral donde esta familia no generara pares candidato que deberían de serlo (falsos negativos).

Por útlimo, podemos observar que la configuración arriba definida transforma una familia $(0.2, 0.8, 0.8, 0.2)-sensible$ en una familia $(.2,.8,0.8785,0.0064)-sensible$.


In [99]:
figure()
s = arange(0,1,0.01)
r = 4
b = 4
plot(s, 1 - (1 - s ** r) ** b, 'b')
axvline(x=.8, ls=':')
axhline(y=.878, ls=':')
axvline(x=.2, ls=':')
axhline(y=.0076, ls=':')
xlabel('Similitud')
ylabel('Probabilidad de ser candidato')
title('AND-OR r=4, b=4')
show()


Familias sensibles a la localidad para otras distancias

Hasta ahora solo hemos analizado las familias sensibles a la localidad relacionadas con la distancia de Jaccard. Sin embargo existen otras distancias para las que se pueden derivar familias sensibles a la localidad. Por ejemplo:

Distancia Coseno

La distancia Coseno es el ángulo entre dos vectores en un espacio de dimensión $d$.

Podemos construir una familia sensible a la localidad $\textbf{H}$ de la siguiente manera:

  • Tomamos un vector unitario al azar $r$, (por ejemplo, simulando bajo $N(0,1)$ las componentes de manera independiente y normalizando).
  • Definimos $h_r \in \textbf{H}$ asociada a $r$ con $h_r(x) = 1$ si $x \cdot r \ge 0$ y $h(x) = -1$ en otro caso.

Dos vectores $x$ y $y$ son asignados al mismo valor si y solo si los productos punto entre $r\cdot x$ y $r\cdot y$ tienen el mismo signo.

En la siguiente figura podemos observar que entre mayor sea el ángulo entre dos vectores menor será la probabilidad de que ambos vectores se encuentren del mismo lado de la perpendicular y por tanto el producto de cada vectores con $r$ tenga el mismo signo.

De forma análoga a la distancia de Jaccard, si la probabilidad de que los dos vectores tengan el mismo hash es $P[h(x) = h(y)] = 1 - d(x,y)$ entonces tenemos que $\textbf{H}$ es una familia $(d_1, d_2, (1 - d_1), (1 - d_2))-sensible$.


In [102]:
Image(filename='figs/angles.png')


Out[102]:

Para aplicar las construcciones de amplificación seleccionamos el número de funciones $N = r * b$ y generamos una firma de tamaño $N$ con $+1$ y $-1$ correspondiente al resultado de aplicar cada vector.

Por último, para hacer este calculo más eficiente es suficiente con utilizar vectores $r$ que solo contengan $+1$ y $-1$. Entonces $h_r(x)$ es el signo de la suma de las componentes de $x$ multiplicadas por $+1$ o $-1$.

Distancia Euclidiana

La distancia Euclidiana es la distancia entre dos puntos en un espacio de dimensión $d$.

Podemos construir una familia sensible a la localidad para distancia Euclideana usando la misma idea de proyecciones sobre vectores aleatorios.

Las funciones hash corresponden a una linea seleccionada al azar. Dividimos esta línea en segmentos de longitud $a$. Mapeamos cada punto a la cubeta que contiene su proyección en la línea.

Si la distancia entre dos puntos es pequeña comparada con $a$, la probabilidad de que mapeen a la misma cubeta es alta.

Si el ángulo entre la línea seleccionada al azar y la línea que conecta los puntos es alta, la probabilidad es incluso mayor. Si $d$ es más grande que $a$ entonces necesitamos $d \text{ cos } \theta \le a$

Si bien no podemos calcular de forma sencilla, cual es la probabilidad $p_1$ de que dos puntos estén a una distancai $d_1$, sí sabemos que es mayour que la probabilidad $p_2$ de que dos puntos a una distancia $d_2$ mapeen al mismo segmento de línea.

Por lo tanto podemos decir que existe una familia $(d_1, d_2, p_1, p_2)-sensible$ para cualquier número de dimensiones.


In [ ]: