Modelo para 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 operació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 determinar las 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 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 combinacion 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 la 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)