Objetivo: Realizar un análisis de correlación de datos entre las características de películas para recomendar películas a ver, conforme a las películas que un usuario ha visto anteriormente

Procedimiento

Modelo par recomendar películas

  • Identificar el usuario (persona) que se desea recomendar películas.
  • Identificar las película que ha visto éste usuario o persona.
  • Determinar un vector con las correlaciones mas fuertes de cada película que ha visto el usuario. Esta operción se hace por medio de un ciclo que va desde la primera hasta la última película vista por el usuario.
  • Ordenar el vector de acuerdo a la correlación de mayor a menor y determinr los tres primeras más altas relaciones
  • Se podría pensar en tres ALGORITMOS para recomendar películas:
  • Opción 1: Aquellas que aparecen con mayor frecuencia en el vector de correlaciones. Opción 2: Aquellas que tienen las relaciones más altas.
  • Opción 3. Combinar la opción 1 con la opción 2.
  • Finalmente, generar una lista de películas que se recomiendan al usuario o persona.

Las librerías

library(readr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

Las peliculas

peliculas <- read.csv("https://raw.githubusercontent.com/rpizarrog/Curso-Titulacion-Data-Science-/master/2019/Datos/catalogo%20de%20peliculas.csv", header = TRUE)
head(peliculas)
##   movieId                              title
## 1       1                   Toy Story (1995)
## 2       2                     Jumanji (1995)
## 3       3            Grumpier Old Men (1995)
## 4       4           Waiting to Exhale (1995)
## 5       5 Father of the Bride Part II (1995)
## 6       6                        Heat (1995)
##                                        genres
## 1 Adventure|Animation|Children|Comedy|Fantasy
## 2                  Adventure|Children|Fantasy
## 3                              Comedy|Romance
## 4                        Comedy|Drama|Romance
## 5                                      Comedy
## 6                       Action|Crime|Thriller

Las películas que un usuario ha visto

peliculasVistas <- read.csv("https://raw.githubusercontent.com/rpizarrog/Curso-Titulacion-Data-Science-/master/2019/Datos/preferencias%20de%20peliculas%20por%20usuarios.csv", header = TRUE)

head(peliculasVistas)
##   userId movieId rating
## 1      1       1      4
## 2      1       3      4
## 3      1       6      4
## 4      1      47      5
## 5      1      50      5
## 6      1      70      3

Los valores 0 y 1 para cada película

llenadoPeliculas <- read.csv("https://raw.githubusercontent.com/rpizarrog/Curso-Titulacion-Data-Science-/master/2019/Datos/representacion%20vectorial%20todas%20las%20peliculas.csv", header = TRUE)

llenadoPeliculas <- t(llenadoPeliculas) # Transponer la matriz

head(llenadoPeliculas)
##           [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
## movieId      1    2    3    4    5    6    7    8    9    10    11    12
## Action       0    0    0    0    0    1    0    0    1     1     0     0
## Adventure    1    1    0    0    0    0    0    1    0     1     0     0
## Animation    1    0    0    0    0    0    0    0    0     0     0     0
## Children     1    1    0    0    0    0    0    1    0     0     0     0
## Comedy       1    0    1    1    1    0    1    0    0     0     1     1
##           [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22]
## movieId      13    14    15    16    17    18    19    20    21    22
## Action        0     0     1     0     0     0     0     1     0     0
## Adventure     1     0     1     0     0     0     0     0     0     0
## Animation     1     0     0     0     0     0     0     0     0     0
## Children      1     0     0     0     0     0     0     0     0     0
## Comedy        0     0     0     0     0     1     1     1     1     0
##           [,23] [,24] [,25] [,26] [,27] [,28] [,29] [,30] [,31] [,32]
## movieId      23    24    25    26    27    28    29    30    31    32
## Action        1     0     0     0     0     0     0     0     0     0
## Adventure     0     0     0     0     0     0     1     0     0     0
## Animation     0     0     0     0     0     0     0     0     0     0
## Children      0     0     0     0     1     0     0     0     0     0
## Comedy        0     0     0     0     0     0     0     0     0     0
##           [,33] [,34] [,35] [,36] [,37] [,38] [,39] [,40] [,41] [,42]
## movieId      34    36    38    39    40    41    42    43    44    45
## Action        0     0     0     0     0     0     1     0     1     0
## Adventure     0     0     0     0     0     0     0     0     1     0
## Animation     0     0     0     0     0     0     0     0     0     0
## Children      1     0     1     0     0     0     0     0     0     0
## Comedy        0     0     1     1     0     0     0     0     0     1
##           [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50] [,51] [,52]
## movieId      46    47    48    49    50    52    53    54    55    57
## Action        0     0     0     0     0     0     0     0     0     0
## Adventure     0     0     0     0     0     0     1     0     0     0
## Animation     0     0     1     0     0     0     0     0     0     0
## Children      0     0     1     0     0     0     0     1     0     0
## Comedy        0     0     0     0     0     1     0     1     0     0
##           [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62]
## movieId      58    60    61    62    63    64    65    66    68    69
## Action        0     0     0     0     0     0     0     1     0     0
## Adventure     0     1     0     0     0     0     0     0     0     0
## Animation     0     0     0     0     0     0     0     0     0     0
## Children      0     1     0     0     0     0     0     0     0     0
## Comedy        1     0     0     0     1     1     1     0     1     1
##           [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72]
## movieId      70    71    72    73    74    75    76    77    78    79
## Action        1     1     0     0     0     0     1     0     1     0
## Adventure     0     0     0     0     0     0     0     0     0     0
## Animation     0     0     0     0     0     0     0     0     0     0
## Children      0     0     0     0     0     0     0     0     0     0
## Comedy        1     0     1     0     0     1     0     0     0     0
##           [,73] [,74] [,75] [,76] [,77] [,78] [,79] [,80] [,81] [,82]
## movieId      80    81    82    83    85    86    87    88    89    92
## Action        0     0     0     0     0     1     0     0     1     0
## Adventure     0     0     0     0     0     1     0     0     0     0
## Animation     0     0     0     0     0     0     0     0     0     0
## Children      1     0     0     0     0     0     1     0     0     0
## Comedy        0     0     1     0     0     0     1     1     0     0
##           [,83] [,84] [,85] [,86] [,87] [,88] [,89] [,90] [,91] [,92]
## movieId      93    94    95    96    97    99   100   101   102   103
## Action        0     0     1     0     0     0     0     0     0     0
## Adventure     0     0     1     0     0     0     0     1     0     0
## Animation     0     0     0     0     0     0     0     0     0     0
## Children      0     0     0     0     0     0     0     0     0     0
## Comedy        1     1     0     1     0     0     0     1     1     0
##           [,93] [,94] [,95] [,96] [,97] [,98] [,99] [,100]
## movieId     104   105   106   107   108   110   111    112
## Action        0     0     0     0     0     1     0      1
## Adventure     0     0     0     1     0     0     0      1
## Animation     0     0     0     0     0     0     0      0
## Children      0     0     0     1     0     0     0      0
## Comedy        1     0     1     1     0     0     0      1

La correlación estadística entre cada película

La matriz de correlación la genera son el renglón de movieid [-1,]

correlacionPeliculas <- data.frame(cor(llenadoPeliculas[-1,]))
# head(correlacionPeliculas) # Primeros seis

Poner nombres de columnas y nombres de filas a las matriz de correlación así como el idmovie como nueva columna con los valores de cada película

idpeliculas <- peliculas$movieId
colnames(correlacionPeliculas) <- idpeliculas
rownames(correlacionPeliculas) <- idpeliculas
correlacionPeliculas <- mutate(correlacionPeliculas, movieid = idpeliculas)
head(correlacionPeliculas[,1:10]) # Primeros seis. Ya con columnas nombres y columna movieid y las primeras 10 columnas
##             1          2          3           4          5          6
## 1  1.00000000  0.7125253  0.1528942  0.02159168  0.3829708 -0.3238751
## 2  0.71252530  1.0000000 -0.1815683 -0.23076923 -0.1240347 -0.2307692
## 3  0.15289416 -0.1815683  1.0000000  0.78679579  0.6831301 -0.1815683
## 4  0.02159168 -0.2307692  0.7867958  1.00000000  0.5374838 -0.2307692
## 5  0.38297084 -0.1240347  0.6831301  0.53748385  1.0000000 -0.1240347
## 6 -0.32387514 -0.2307692 -0.1815683 -0.23076923 -0.1240347  1.0000000
##            7           8           9          10
## 1  0.1528942  0.56061191 -0.17407766  0.02159168
## 2 -0.1815683  0.78679579 -0.12403473  0.17948718
## 3  1.0000000 -0.14285714 -0.09759001 -0.18156826
## 4  0.7867958 -0.18156826 -0.12403473 -0.23076923
## 5  0.6831301 -0.09759001 -0.06666667 -0.12403473
## 6 -0.1815683 -0.18156826  0.53748385  0.58974359
tail(correlacionPeliculas[,91:100]) # Últimos seis. Ya con columnas nombres y columna movieid y las últimas columnas
##             102        103         104         105         106        107
## 95   0.68313005 -0.1815683  0.68313005  0.42857143  1.00000000  0.2182179
## 96   0.44721360 -0.2773501  0.44721360 -0.21821789  0.21821789  1.0000000
## 97  -0.06666667 -0.1240347 -0.06666667 -0.09759001 -0.09759001 -0.1490712
## 98  -0.12403473 -0.2307692 -0.12403473  0.30261377  0.30261377 -0.2773501
## 99  -0.12403473  0.1794872 -0.12403473  0.30261377  0.30261377 -0.2773501
## 100  0.44721360 -0.2773501  0.44721360 -0.21821789  0.21821789  0.3333333
##             108         110         111         112
## 95  -0.09759001  0.30261377  0.30261377  0.21821789
## 96  -0.14907120 -0.27735010 -0.27735010  0.33333333
## 97   1.00000000 -0.12403473 -0.12403473 -0.14907120
## 98  -0.12403473  1.00000000  0.17948718  0.09245003
## 99  -0.12403473  0.17948718  1.00000000  0.09245003
## 100 -0.14907120  0.09245003  0.09245003  1.00000000

Cuales películas se le recomienda ver al usuario

Primero, ¿cuáles películas ha visto el usuario ?

usuario <- 38 # Aqu se define cual usuario, del 1 al 610
pelVistaUsuario <- filter(peliculasVistas, userId == usuario)
pelVistaUsuario  # Son las peliculas vistas por el usuario
##   userId movieId rating
## 1     38      11      5
## 2     38      17      3
## 3     38      21      3
## 4     38      39      3
## 5     38      48      3
## 6     38      50      5
## 7     38      62      3
## 8     38     105      3
## 9     38     110      5

Ahora sacar las correlaciones de cada pelicula vista del usuario

Determinar las mejores 3 correlaciones de cada película

Ordenando las correlaciones

Generando un data frame nuevo con las mejores 3 recomendaciones de cada película que el usuario ha visto

# Generamos un dtaframe vacío 
# El datafrme de recomendaciones lo iniciamos vacio 
recomendaciones <- data.frame(NA, NA, NA) # Vacio
recomendaciones <- recomendaciones[-1,] # Vacio
colnames(recomendaciones) <- c("Vista", "Recomendada", "Correlación")
recomendaciones # Está vacío el data frame
## [1] Vista       Recomendada Correlación
## <0 rows> (or 0-length row.names)
# Un ciclo para recorrer cada película vista por el usaurio
# y generar sus recomendaciones, las tres más altas correlaciones
for (peli in 1:nrow(pelVistaUsuario)) {
  # print(pelVistaUsuario[peli,2])


  # Se determina las películas recomendadas según las correlaciones más altas. 
  #Las tres primeras de cada película vista por el usuario
  recomendadas <- filter(correlacionPeliculas, movieid == pelVistaUsuario[peli,2])
  # Quitar la misma pelicula vista con correlacion igual a 1
  recomendadas <- recomendadas[,-which(colnames(recomendadas) == pelVistaUsuario[peli,2])]
  recomendadas <- sort(recomendadas, decreasing = TRUE)
  recomendadas <- recomendadas[1,3:5] # Las tres mejores
  rownames(recomendadas) <- pelVistaUsuario[peli,2] # Conservar el nombre de la fila
  

# Generamos las recomendaciones de cada película, tres columnas. La primera columna es la película que el usuario ya vió; la segunda columna es la película recomenda con valor de correlación más alto y la tercera columna es el valor de la correlación de la película recomendada.

    peliVista <- as.numeric(rep(rownames(recomendadas), 3))
    peliVista
    peliRecomendada <- as.numeric(colnames(recomendadas[1,1:3]))
    peliRecomendada
    peliCorrelacionada <- as.numeric(recomendadas[1,1:3])
    peliCorrelacionada
    pelisRecomendadas <- data.frame(peliVista, peliRecomendada, peliCorrelacionada)

# Poner nombres de columnas al dataframe que se va generando
    colnames(pelisRecomendadas) <- c("Vista", "Recomendada", "Correlacion")
    
                         
    recomendaciones <- rbind(recomendaciones, pelisRecomendadas)
    
  }
   recomendaciones <- arrange(recomendaciones, desc(Correlacion))
   recomendaciones
##    Vista Recomendada Correlacion
## 1     17          28   1.0000000
## 2     17          46   1.0000000
## 3     17          49   1.0000000
## 4     39           7   1.0000000
## 5     39          64   1.0000000
## 6     39          68   1.0000000
## 7     62          26   1.0000000
## 8     62          31   1.0000000
## 9     62          40   1.0000000
## 10   105          25   1.0000000
## 11   105          28   1.0000000
## 12   105          46   1.0000000
## 13    11          52   1.0000000
## 14    11          58   1.0000000
## 15    11          94   1.0000000
## 16   110          73   0.7867958
## 17    21          20   0.7125253
## 18    50          22   0.7125253
## 19    21           6   0.5897436
## 20    21          23   0.5897436
## 21    50           6   0.5897436
## 22    50          21   0.5897436
## 23   110          42   0.5897436
## 24   110          86   0.5897436
## 25    48          25   0.5606119
## 26    48          27   0.5606119
## 27    48          28   0.5606119

Ahora determinar las frecuencias

Por medio de table que es una función que identifica frecuencias

masFrecuentes <- table(recomendaciones$Recomendada)
masFrecuentes <- sort(masFrecuentes, decreasing = TRUE)
masFrecuentes <- data.frame(masFrecuentes)
colnames(masFrecuentes) <- c("Recomendada", "Frecuencia")
masFrecuentes <-  filter(masFrecuentes, Frecuencia > 1)
masFrecuentes
##   Recomendada Frecuencia
## 1          28          3
## 2           6          2
## 3          25          2
## 4          46          2

Finalmente traemos solo el nombre de las películas recomendadas

Para este usuario. Que fue el usuario

Se utiliza una combinacipn de filter, select ambos combiandos con %>%

Se utiliza rbind para ir agregando el resultado del filter y el select juntos

nomPelicula <- NULL # Vector vacio
if (nrow(masFrecuentes) > 0) {
for (p in 1:nrow(masFrecuentes)) {
  nomPelicula <- rbind(nomPelicula, filter (peliculas, movieId == masFrecuentes[p,1])  %>%
    select(title))
  
  }
  nomPelicula <- c(nomPelicula)  

} else {
  print("No hay frecuencia de recomendaciones mayor 1. O Sea que hay muy pocas recomendaciones para el usuario. Se le debe elegir recomendar solo las películas con correlación más alta.")
  recomendaciones
  for (p in 1:nrow(recomendaciones)) {
  nomPelicula <- rbind(nomPelicula, filter (peliculas, movieId == recomendaciones[p,2])  %>%
    select(title))
  
  }
  nomPelicula
}

Ahora solo resta agregar al columna a dataframe masFrecuente o a recomendaciones en caso de poca frecuencia

if (nrow(masFrecuentes) > 0) {
  masFrecuentes <- mutate(masFrecuentes, nomPelicula$title) #Agregar el nombre
  masFrecuentes <- masFrecuentes[,-2] # quitar la columna dos
  colnames(masFrecuentes) <- c("Recomendada", "Nombre")
  masFrecuentes
} else {
  print("No hay frecuencia de recomendaciones mayor 1. O Sea que hay muy pocas recomendaciones. Elegir otro usuario. Se muestran las películas con correlaciones más altas")
  recomendaciones <- recomendaciones[,-1] # quitar la columna 1 y 3 
  recomendaciones <- recomendaciones[,-2] # quitar la columna 1 y 3 
  recomendaciones <- data.frame(recomendaciones)
    recomendaciones <- mutate(recomendaciones, nomPelicula$title) #Agregar el nombre
   colnames(recomendaciones) <- c("Recomendada", "Nombre")
  recomendaciones
}
##   Recomendada                               Nombre
## 1          28                    Persuasion (1995)
## 2           6                          Heat (1995)
## 3          25             Leaving Las Vegas (1995)
## 4          46 How to Make an American Quilt (1995)