El dataframe generado contiene información acerca de las preferencias y recomendaciones de películas de alumnos del ITESM Campus MTY, donde 1 indica que la película es poco recomendable y 5 significa que es altamente recomendable. Con el propósito de ejemplificar el funcionamiento de los modelos de recomendación, algunos datos aparecerán vacíos. Esto simula que, en ocasiones, no todos los usuarios califican todos los ítems.
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.2
## Warning: package 'ggplot2' was built under R version 4.3.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.2 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(recommenderlab)
## Warning: package 'recommenderlab' was built under R version 4.3.2
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
##
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
##
## Loading required package: arules
## Warning: package 'arules' was built under R version 4.3.2
##
## Attaching package: 'arules'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following objects are masked from 'package:base':
##
## abbreviate, write
##
## Loading required package: proxy
##
## Attaching package: 'proxy'
##
## The following object is masked from 'package:Matrix':
##
## as.matrix
##
## The following objects are masked from 'package:stats':
##
## as.dist, dist
##
## The following object is masked from 'package:base':
##
## as.matrix
##
## Registered S3 methods overwritten by 'registry':
## method from
## print.registry_field proxy
## print.registry_entry proxy
library(proxy)
MR <- data.frame(
Spiderman = c(5, NA, 3, 4),
Juegos_del_Hambre = c(NA, 4, 1, 2),
Sonido_de_Libertad = c(3, NA, NA, 3),
Coco = c(2, 5, 4, 5),
Take_The_Ball_Pass_The_Ball = c(1, NA, 5, NA),
Inception = c(4, 2, NA, NA),
Interestelar = c(3, 5, 3, NA)
)
rownames(MR) <- c('Daniel', 'Luis', 'Gera', 'Cris')
View(MR)
cosine_similarity <- function(vec_1, vec_2) {
vec_len <- length(vec_1)
# Reemplazar NA con 0
vec_1[is.na(vec_1)] <- 0
vec_2[is.na(vec_2)] <- 0
# Denominador
vec_1_denom <- sqrt(sum(vec_1^2))
vec_2_denom <- sqrt(sum(vec_2^2))
denominator <- vec_1_denom * vec_2_denom
# Numerador
tib = tibble(vec_1 = vec_1, vec_2 = vec_2)
tib <- tib %>% mutate(products = vec_1 * vec_2)
numerator <- sum(tib$products)
# Coseno de similaridad
return (numerator / denominator)
}
#Similiaridad entre amigos
Daniel <- as.numeric(as.vector(MR['Daniel',]))
Luis <- as.numeric(as.vector(MR['Luis',]))
Gera <- as.numeric(as.vector(MR['Gera',]))
Cris <- as.numeric(as.vector(MR['Cris',]))
MR_Similaridad <- data.frame(
cosine_similarity = c(cosine_similarity(Daniel, Luis), cosine_similarity(Daniel, Gera), cosine_similarity(Daniel, Cris))
)
rownames(MR_Similaridad) <- c('Luis', 'Gera', 'Cris')
MR_Similaridad
## cosine_similarity
## Luis 0.4930318
## Gera 0.5970849
## Cris 0.6634035
#Utilizamos el coseno de simalirad, para realizar una de Prediccion Pelis Nuevas
MR_prom <- function(movie, friends) {
denominator <- 0
numerator <- 0
for (friend in friends) {
Mr_sim <- MR_Similaridad[friend, 'cosine_similarity']
Mr_calif <- MR[friend, movie]
if (!is.na(Mr_calif)) {
denominator <- denominator + Mr_sim
numerator <- numerator + (Mr_sim * Mr_calif)
}
}
if (denominator == 0) {
return(NA)
}
return(numerator / denominator)
}
friend_names <- c('Luis', 'Gera', 'Cris')
MR_Nuevo <- c('Spiderman', 'Juegos_del_Hambre', 'Sonido_de_Libertad')
MR_Pred_Nuevo <- tibble(movie = MR_Nuevo, Pred_calif = sapply(MR_Nuevo, function(n) MR_prom(n, friend_names)))
MR_Pred_Nuevo
## # A tibble: 3 × 2
## movie Pred_calif
## <chr> <dbl>
## 1 Spiderman 3.53
## 2 Juegos_del_Hambre 2.22
## 3 Sonido_de_Libertad 3
# convert the movie ratings data frame to a matrix
rmat <- as.matrix(MR)
# convert matrix to a recommenderlab realRatingMatrix
rmat <- as(rmat, "realRatingMatrix")
MR_Normalizado <- Recommender(rmat, "UBCF",
param=list(normalize = "center", method="Cosine"))
MR_Normalizado_Pred <- predict(MR_Normalizado, rmat, type="ratings")
MR
## Spiderman Juegos_del_Hambre Sonido_de_Libertad Coco
## Daniel 5 NA 3 2
## Luis NA 4 NA 5
## Gera 3 1 NA 4
## Cris 4 2 3 5
## Take_The_Ball_Pass_The_Ball Inception Interestelar
## Daniel 1 4 3
## Luis NA 2 5
## Gera 5 NA 3
## Cris NA NA NA
MR_Normalizado_Pred@data
## 4 x 7 sparse Matrix of class "dgCMatrix"
## Spiderman Juegos_del_Hambre Sonido_de_Libertad Coco
## Daniel . 1.55337 . .
## Luis 4.293013 . 3.536385 .
## Gera . . 2.747675 .
## Cris . . . .
## Take_The_Ball_Pass_The_Ball Inception Interestelar
## Daniel . . .
## Luis 5.412718 . .
## Gera . 1.627089 .
## Cris 4.093292 2.509024 3.801305
Dada la naturaleza de la base de datos generada y los posibles desafíos de datos dispersos y valores faltantes, se utilizó un modelo basado en la similitud coseno con valores normalizados. De esta manera, se obtendrá un mejor análisis, ya que el conjunto de datos no es muy grande; un modelo más simple será más fácil de entender e implementar. Asimismo, debido a que la normalización de valores y el uso de la similitud coseno pueden ser útiles cuando los datos son dispersos y hay valores faltantes.