El objetivo de esta lección es entender como funcionan distintos métodos para hacer recomendaciones.
Nota: Esta lección está basada en el Capítulo 9 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.
El objetivo de un sistema de recomendación es poder predecir elementos que podrían gustar a un usuario dadas sus preferencias.
Existen dos tipos principales de sistemas de recomendación:
Para poder hacer recomendaciones de acuerdo al contenido de los elementos es necesario crear un perfil para cada uno de los elementos.
Estos perfiles son definidos a partir de las características de los elementos. Por ejemplo:
Existen otras características que no son tan evidentes pero que se pueden obtener de conjuntos como colecciones de artículos o de imágenes.
Una posibilidad para extraer las palabras que caracterizan a un documento es utilizar las palabras con mayor coeficiente TF.IDF para las palabras de un documento.
El coeficiente TF.IDF nos da la relación entre la frecuencia con la que aparecen los términos en un documento (TF) y el inverso de la frecuencia con la que aparece dicho término en todos los documentos (IDF).
$$\textbf{TF}_{ij} = \frac{f_{ij}}{\text{max}_k f_{kj}}$$$$\textbf{IDF}_{i} = \text{log}\frac{N}{n_i}$$La distancia entre estas características, puede ser la distancia de Jaccard o distancia Coseno
Otra forma de describir los elementos en una colección es mediante el uso de etiquetas definidas por los usuarios. Un caso ejemplar es el uso que netflix hace de las categorías generales para recomendar las películas streaming en contraste con el sistema de recomendación que tenían para las películas por DVD.
Para representar los perfiles de usuario utilizamos vectores de elementos.
Para crear un perfil de usuario promediammos los componentes de los vectores que representan los perfiles de elementos, para aquellos elementos por los que el usuario tiene preferencias.
Para predecir si un usuario está interesado en un elemento calculamos la distancia coseno ente el vector que representa el perfil de usuario y los vectores que representan a los elementos.
Como se vió en las lecciones anteriores es posible utilizar técnicas de LSH para encontrar los elementos cercanos.
$$u(x,i) = cos(x,i) = \frac{x\cdot i}{||x||\cdot|||i|}$$Es importante notar que este método solo va a generar recomendaciones para los elementos contenidos en el perfil de cada usuario.
Si bien por un lado este enfoque nos permite generar recomendaciones para elementos nuevos no nos permite generar recomendaciones para usuarios nuevos.
Es posible aprovechar la información generada por las preferencias de más de un usuario, a este enfoque se le conoce como filtrado colaborativo ya que las preferencias de múltiples usuarios colaboran para generar una recomendacion.
En general en los sistemas de recomendación encontraremos dos tipos de elementos: usuarios y elementos.
Para cada par usuario-elemento, la matriz de utilidad tiene una entrada que representa la preferencia del usuario por dicho elemento.
En en el siguiente ejemplo podemos observar las preferencias de los usuarios ${A \ldots B}$ respecto a las películas ${P_1 \ldots P_5}$
$P_1$ | $P_2$ | $P_3$ | $P_4$ | $P_5$ | $P_6$ | $P_7$ | |
---|---|---|---|---|---|---|---|
A | 4 | 5 | 1 | ||||
B | 5 | 5 | 4 | ||||
C | 2 | 4 | 5 | ||||
D | 3 | 3 |
Esta matriz generalemente es muy rala ya que los usuarios solo tienen preferencias definidas para un número muy pequeño de los elementos.
Otro tipo de matriz es aquel en el que los usuarios no definen un valor numérico sino que se consideran sus acciones de forma implicita (compra / no compra).
$P_1$ | $P_2$ | $P_3$ | $P_4$ | $P_5$ | |
---|---|---|---|---|---|
A | 1 | 0 | 0 | 1 | 1 |
B | 1 | 1 | 1 | 1 | 0 |
C | 1 | 0 | 0 | 0 | 1 |
D | 0 | 1 | 0 | 0 | 0 |
In [27]:
from math import sqrt
def cos(a,b):
asq = sqrt(sum([e * e for e in a]))
bsq = sqrt(sum([e * e for e in b]))
num = sum([l * m for (l,m) in zip(a,b)])
return num / (asq * bsq)
Una forma muy simple de medir la similitud sería utilizando la distancia de Jaccard entre los conjuntos de cosas compradas, sin embargo este enfoque nos limita a no considerar las calificaciones entre los elementos.
B | C | D | |
---|---|---|---|
A | 4/5 | 2/4 | 0 |
B | 0 | 3/4 | |
C | 0 |
Esto nos genera una percepción equivocada ya que no obstante $A$ y $B$ tenían preferencias similares en términos de distancia se encuentran más lejanos que $A$ y $C$.
Podemos utilizar distancia coseno si asignamos a las opciones en blanco un valor cero, bajo este modelo tenemos las siguientes distancias:
B | C | D | |
---|---|---|---|
A | 0.38 | 0.322 | 0 |
B | 0 | .435 | |
C | 0 |
Es importante considerar que en este caso:
Se puede compensar este último efecto si consideramos un umbral $t$ y convertimos en 1 los elementos mayor o igual de este umbral y en blanco los que estén debajo. Tomemos $t=3$
$P_1$ | $P_2$ | $P_3$ | $P_4$ | $P_5$ | $P_6$ | $P_7$ | |
---|---|---|---|---|---|---|---|
A | 1 | 1 | |||||
B | 1 | 1 | 1 | ||||
C | 1 | 1 | |||||
D | 1 | 1 |
Aplicando distancia Coseno o Jacard sobre estos elementos nos da el mismo resultado:
B | C | D | |
---|---|---|---|
A | 3/4 | 1 | 0 |
B | 0 | 3/4 | |
C | 0 |
Hasta ahora esta matriz es la que nos da un resultado intuitivamente mejor.
Podemos también normalizar las calificaciones de cada usuario si a cada entrada le restamos la media de sus calificaciones. Esto nos permite centrar las calificaciones y convertir las calificaciones altas vs bajas de cada usuario en opuestas.
$P_1$ | $P_2$ | $P_3$ | $P_4$ | $P_5$ | $P_6$ | $P_7$ | |
---|---|---|---|---|---|---|---|
A | 2/3 | 5/3 | -7/3 | ||||
B | 1/3 | 1/3 | -2/3 | ||||
C | -5/3 | 1/3 | 4/3 | ||||
D | 0 | 0 |
Utilizando esta matriz encontramos resultados que son más consistentes con la intuición que teníamos:
B | C | D | |
---|---|---|---|
A | 0.092 | -0.559 | 0 |
B | 0 | 0 | |
C | 0 |
En general el problema de la normalización nos sirve para tratar con el uso heterogeneo de las escalas numéricas por parte de los usuarios, por ejemplo las personas pueden ser:
Más allá de poder recomendar ciertos elementos dadas las preferencias de un usuario, nos gustaría poder recomendar a los usuarios a partir de los gustos / preferencias de otros usuarios.
Si tomamos la matriz del ejemplo anterior tenemos:
$P_1$ | $P_2$ | $P_3$ | $P_4$ | $P_5$ | $P_6$ | $P_7$ | |
---|---|---|---|---|---|---|---|
A | 4 | 5 | 1 | ||||
B | 5 | 5 | 4 | ||||
C | 2 | 4 | 5 | ||||
D | 3 | 3 |
Podemos observar que esta matriz es rala, nuestro objetivo es encontrar un modelo que pueda predecir los valores no observados en el modelo.
Una de las formas más populares de filtrado colaborativo es la factorización de matrices. En este modelo construimos una aproximación de la matriz de bajo rango.
La matriz $M$ contienen las calificaciones para los usuarios (renglones) y elementos (columnas). $M$ se puede aproximar como el producto de un modelo de usuarios $W$ y un modelo para los elementos $V$.
Cada renglón $W[i]$ es un vector que representa los factores latentes del usuario $i$ y cada renglón en $V[j]$ representa los factores latentes del elemento $j$.
El producto de $W[i] \cdot V[j]^T$ es un escalar que aproxima la calificación $R_{i,j}$. En general podemos decir que $M \approx W \cdot V^T$.
Las matrices $W$ y $V$ se pueden construir resolviendo el siguiente problema de optimización, donde el objetivo es minimizar el error cuadrático entre la matriz original y la aproximación, para aquellos elementos que son observados.
$$(W,V) = \text{arg min}_{W,V} \sum_{(ij)\in E}{(M_{ij} - W_i \cdot V_j^T)^2} + ||W||_2 + ||V||_2$$