Juan David Velásquez Henao
jdvelasq@unal.edu.co
Universidad Nacional de Colombia, Sede Medellín
Facultad de Minas
Medellín, Colombia
[Licencia]
[Readme]
Software utilizado.
Este es un documento interactivo escrito como un notebook de Jupyter, en el cual se presenta un tutorial sobre regresión logistica usando R en el contexto de aprendizaje de maquinas. Los notebooks de Jupyter permiten incoporar simultáneamente código, texto, gráficos y ecuaciones. El código presentado en este notebook puede ejecutarse en los sistemas operativos Linux y OS X.
Haga click aquí para obtener instrucciones detalladas sobre como instalar Jupyter en Windows y Mac OS X.
Haga clic [aquí] para ver la última versión de este documento en nbviewer.
Descargue la última versión de este documento a su disco duro; luego, carguelo y ejecutelo en línea en Try Jupyter!
Haga clic aquí para ver el tutorial de visualización y gráficas.
Las recomendaciones se han convertido en uno de los insumos básicos de servicios de comercio y servicios en línea. Recomendar libros, articulos, peliculas o canciones puede estimular el consumo y, por tanto, la venta de este. Este tipo de sistema automatizado puede proporcionar a cada usuario una lista personalizada de sugerencias (ya sea una lista de productos para la compra, características de uso, o nuevas conexiones). Los sistemas de recomendaciones aplican estadística y técnicas de descubrimiento de conocimiento para predecir recomendaciones basados en data ya recolectada.
Existen dos tipos de sistemas de recomendación: Basados en contenido y filtrado colaborativo.
El primero tipo de enofque se basa en la idea de que si se puede obtener la estructura de las preferencias de un usuario en cuanto a un producto, entonces podemos recomendar otros productos con los atributos similares a los más preferidos por el usuario.
El segundo tipo de sistema de recomendación está basado en los aportes de los consumidores a menudo recibe el nombre filtrado colaborativo, debido a que los usuarios colaboran a través del sistema para encontrar los mejores artículos para los demas consumidores. La idea es que dado los datos de calificaciones de los usuarios a los items se pueden encontrar usuarios similiares que le gusten cierto tipo de producto, o ciertos tipos de productos que le gusten a la misma persona.
Son algoritmos basados en memoria que intenta imitar el boca a boca mediante el análisis de los datos de calificación de muchos individuos. El supuesto es que los usuarios con preferencias similares se calificaría productos (items) de manera similar. Por lo tanto, las calificaciones faltantes para un usuario se puede predecir mediante la búsqueda de una vecindad primaria entre los usuarios y similares y por último se agregan las calificaciones de estos usuarios para formar una predicción.
Las vecindades se definen en términos de similaridad y algortimos de clustering como k-means, k-medians u otro tipo de modelo de agrupación. Es de recordar que la medidad de distancia es importante dentro del modelo ya que se pueden usar distancias euclidianas, correlaciones, coseno o manhattan.
Luego de realizar la segmentación, los ratings son agregados para calcular el valor de predicción por el algoritmo como la media del rating dentro del cluster para el item.
$$ \hat{r_{aj}} = \frac{1}{| N(a) |} \sum_{i \in N(a)} r_{ij} $$Donde $ \hat{r_{aj}} $ es la predicción del cluster a al item j, $ N(a) $ es el conjunto de usuarios en el cluster a y $r_{ij}$ es la calificación del usuario i al item j
Usualmente normalizar los datos antes de aplicar los algortimos pueden mejorar el sesgo del modelo, ya que tienden a darle menos peso a aquellos usuarios que siempre están calificando alto o siempre califican bajo a los items. Para esto se puede utilizar las técnicas de normalización ya vistas en el Notebook de Clustering.
Es un enfoque basado en los modelos que produce recomendaciones basadas en la relación entre los elementos parecidos e inferidas a partir de la matriz de calificación. La suposición detrás de este enfoque es que los usuarios preferirán artículos que son similares a otros artículos que les gusta.
Este algoritmo calcula la similaridad entre todos los items utilizando una medida de distancia, es decir, calcula clusters dentro de los items.
Para hacer recomendaciones, se calcula la suma ponderada de las calificaciones para los items similares.
$$ \hat{r_{ai}} = \frac{1}{\sum_{j \in S(i) \cap \{l;r_{ai}\neq?\}} s_{ij}} \sum_{j \in S(i) \cap \{l;r_{ai}\neq?\}} s_{ij} r_{aj}$$Donde $ \hat{r_{aj}} $ es la predicción del cluster a al usuario i, $ S(i) $ es el conjunto de items en el cluster i, $r_{aj}$ es la calificación del cluster a al item j, $s_{ij}$ es la similaridad (suma ponderada) del usuario i al item j.
En 2006, Netflix publicó una base de datos con un gran número de calificaciones de peliculas por parte de los clientes para realizar un desafío público. El objetivo era mejorar en su algoritmo interno para la predicción de calificaciones. Desafortunadamente, por razones legales, el conjunto de datos que se habilitó para desarrollar el Premio Netflix ya no está disponible. Sin embargo, se utilizará un conjunto de dato académicos con características similares. Estos datos provienen del grupo Lens (GroupLens), un laboratorio de investigación de la Universidad de Minnesota.
In [1]:
## Cargue las librerías necesarias
library(recommenderlab)
library(ggplot2)
## Cargue la data de MovieLense
data(MovieLense)
## Vista de los primeros registros de la data
head(as(MovieLense[1,], "list")[[1]])
In [2]:
## Visualice parte de la matriz
options(repr.plot.width=10, repr.plot.height=5)
image(MovieLense[1:100,1:100])
Puede observar que existe una lista del nombre de las peliculas con las calificaciones asignadas por cada usuario. Existen muchos usuarios que no califican los filmes, por eso en la imagen de la matriz puede observar tanto espacio blanco. A este tipo de matriz se le conoce como sparse.
In [3]:
# Estructura de la data
str(MovieLense)
Dentro de la estructura observe que en Dimnames están los nombres y en x se encuentran las calificaciones de las peliculas.
In [4]:
## Histograma del número de calificaciones por usuario
options(repr.plot.width=10, repr.plot.height=5)
hist(rowCounts(MovieLense))
La gráfica anterior muestra que la mayoría de los usuarios ha calificado entre 0-50 veces y esta tendencencia disminuye a medida que el número de calificaciones aumenta. Es decir, que un usuario no califica muchas películas.
In [5]:
## Histograma del número de calificaciones por película
options(repr.plot.width=10, repr.plot.height=5)
hist(colCounts(MovieLense))
Similarmente, observe que una pelicula es más probable de tener entre 0-50 calificaciones, donde se evidencia una tendencia más marcada a disminuir la cantidad de peliculas cuando aumenta la cantidad de calificaciones. Es decir, existen pocas películas con una gran cantidad de calificación.
In [6]:
## Resumen e histograma de las calificaciones
## Histograma
options(repr.plot.width=10, repr.plot.height=5)
qplot(getRatings(MovieLense), # Data
binwidth = 1, # Amplitud de la barra
main = "Histogram of ratings", # Titulo del grafico
xlab = "Rating") # Título del eje x
## Resumen
summary(getRatings(MovieLense))
Observe del histograma que la calificación que más se repite es '4', donde la distribución está más sesgada hacia la derecha, es decir, hacia calificaciones positivas. Esto se observa en resumen donde la media corresponde a 3.53 y la mediana es 4.
In [7]:
## Calificación media (del promedio de calificación de cada usuario)
mean(rowMeans(MovieLense))
Este dato muestra que en promedio, la calificación promedio de un usuario entre todas las peliculas que ve, es de 3.58. Difiere del promedio de todas las calificaciones que se vió anteriormente (3.53)
In [8]:
## Normalice la data
Norm <- normalize(MovieLense)
head(as(Norm[1,], "list")[[1]])
Ya que los métodos de recomendación se basan en los métodos de clustering, como se vió en el Notebook de Clustering, es de suma importancia normalizar la data para poder tener medidas de distancias comparables y poder calcular cercanías. Por esto, normalice la data en distribución normal estándar (restando la media y diviendiendo sobre la desviación estándar).
In [9]:
## Imagen de la matriz sparse de las calificaciones sin normalizar
image(MovieLense, main = "Raw Ratings")
In [10]:
## Imagen de la matriz sparse de las calificaciones con normalización
image(Norm, main = "Normalized Ratings")
Las dos imagenes anteriores dejan claro, la forma de una matriz sparse ya que cada punto negro representa una calificación de un usuario a una pelicula (item). Note que la esquina superior derecha no presenta calificaciones, ya que pueden ser peliculas no tan populares dentro de los visitantes.
In [11]:
# Primeros seis filas de la matriz sparse normalizada.
head(getRatingMatrix(Norm))
Note como dentro de los 6 primeros registros de la matriz sparse existen muchos valores en 0 (.)
In [12]:
## Datos de entrenamiento. (900 usuarios)
train <- MovieLense[1:900]
## Visualizamos la matriz de entrenamiento
head(getRatingMatrix(train))
Dentro del ejemplo, utilice la matriz sin normalizar para realizar el recomendador. Puede utilizar la matriz normalizada para mirar como cambian los resultados.
In [13]:
### Recomendador basado en filtrado colaborativo basado en usuarios
rec <- Recommender(train, # Datos de entrenamiento
method = "UBCF") # Metodo: Basado en Usuarios
rec # Objeto recomendador
In [14]:
### Recomendador basado en filtrado colaborativo basado en items
rec1<-Recommender(train, # Datos de entrenamiento
"IBCF") # Metodo: Basado en Usuarios
rec1 # Objeto recomendador
Se entrenan los dos modelos, basados en usuarios e items.
In [15]:
### Realice las N recomendaciones para los otros usuarios con el metodo de usuarios
pre <- predict(rec, # Recomendador
MovieLense[901:943], # Datos de evaluación
n = 5) # Número de recomendaciones por usuario
pre # Objeto de recomendaciones
## Visualizamos las 5 recomendaciones para cada usuario
as(pre, # Recomendaciones
"list") # como lista
In [16]:
### Realice las N recomendaciones para los otros usuarios con el metodo de items
pre1 <- predict(rec1, # Recomendador
MovieLense[901:943], # Datos de evaluación
n = 5) # Número de recomendaciones por usuario
pre1 # Objeto de recomendaciones
## Visualizamos las 5 recomendaciones para cada usuario
as(pre1, # Recomendaciones
"list") # como lista
Se calculan las predicciones como las 5 recomendaciones para cada usuario. Recuerde que este algoritmo coloca a cada usuario en un cluster y realiza una recomendaciones basado en la media de los ratings de cada cluster.
In [17]:
## Observe las posibilidades que se tienen para estimar los recomendadores
recommenderRegistry$get_entries(dataType = "realRatingMatrix")
Observe que existen varios métodos para estimar los recomendadores. Entre estos están los más populares basados en usuarios e items. No obstante se encuentran los ALS, SVD, aleatorio, popular o el re-recomendar.
In [18]:
## Crear un esquema para evaluar los diferentes algoritmos
scheme <- evaluationScheme(MovieLense, # Datos
method = "split", # Dividir la data
train = .9, # 90% de entrenamiento y 10 de validación
k = 1, # Numero de veces para correr la evaluación
given = 10, # Número de items para cada observación
goodRating = 4) # Límite inferiro donde se considera un buen rating
scheme
In [19]:
## Algoritmos a evaluar con sus parámetros
algorithms <- list(
"random items" = list(name="RANDOM", # Algoritmo Random
param=list(normalize = "Z-score")), # Normalización Z-score
"popular items" = list(name="POPULAR", # Algoritmo Popular
param=list(normalize = "Z-score")), # Normalización Z-score
"user-based CF" = list(name="UBCF", # Algoritmo Usuario
param=list(normalize = "Z-score", # Normalizacion Z-score
method="Cosine", # Distancias metodo coseno
nn=50)), # Numero de clusters
"item-based CF" = list(name="IBCF", # Algortimo Items
param=list(normalize = "Z-score")) # Normalización Z-score
)
Para mirar el performance de los diferentes algoritmos, utilizamos un esquema de evaluación para entrenar y medir los algortimos de User, Item, Popular y Aleatorio
In [20]:
# Correr los algoritmos con n recomendaciones de peliculas
results <- evaluate(scheme, # Esquema de evaluación
algorithms, # Algoritmos
n=c(1, 3, 5, 10, 15, 20)) # n recomendaciones
# Visualice resultados
head(results)
In [21]:
# Grafique la curva ROC
options(repr.plot.width=10, repr.plot.height=5)
plot(results, # Resultados del esquema
annotate = 1:4, # Poner recomendaciones en las lineas
legend="topleft") # Leyenda
In [22]:
## Observe la relación entre precision y recall
options(repr.plot.width=10, repr.plot.height=5)
plot(results, # Resultados del esquema de evaluación
"prec/rec", # Precisión - Recall
annotate=1:4) # Poner recomendaciones en las lineas
Puede observar que dentro de las metricas que se evaluaron el algortimo que mayor tuvo desemepeño es el User-based, ya que es aquel que tiene mejor relación entre TPR y FPR. Además, es aquel que tiene mejor relación entre precision-recall.
Es interesante que note cómo el algortimo de Popular supera al algoritmo basado en items. Esto puede deberse a que cierto tipos de algoritmos funcionan mejor abarcando un tipo de problema especifico que otros.
Recuerde que las metricas ROC se definen de la siguiente manera.
Ejercicio.-- Utilice los del restaurante Entree de Chicago. En esta data un cliente puede usar un restaurante de cualquier ciudad y siempre recibirán recomendaciones de los restaurantes. El cliente puede calificar el restaurante. Su objetivo es utilizar este dataset para contruir el mejor recomendador que permita recomendarle a un cliente cualquiera el (los) restaurante(s) que debe ir.
In [ ]: