Hacer Recomendaciones
Beatriz Valdez
Introducción
Los sistemas de recomendación revolucionaron la forma en que se interactuaba con las páginas web, transformándolas de espacios pasivos en plataformas dinámicas y personalizadas. Estos sistemas, basados en el análisis de las acciones pasadas de los usuarios, ofrecen sugerencias de artículos, productos o contenido que podrían ser de su interés.
El pilar fundamental de los sistemas de recomendación radica en la comprensión del comportamiento de los usuarios. Al analizar sus interacciones previas, como compras, visualizaciones o búsquedas, estos sistemas identifican patrones y relaciones que permiten inferir sus preferencias. Por ejemplo, si un usuario "A" compra un producto "X" y luego otro usuario "C" adquiere el mismo producto, el sistema infiere que ambos usuarios comparten un gusto similar. En este escenario, el sistema podría recomendar el producto "Y", adquirido por el usuario "A", al usuario "C", basándose en su afinidad por el producto "X".
Algoritmos de recomendación:
Existen diversos algoritmos que sustentan los sistemas de recomendación, cada uno con sus propias ventajas y desventajas. Entre los más comunes destacan:
- Filtros colaborativos: Estos algoritmos se basan en la idea de que los usuarios con comportamientos similares tienden a tener preferencias similares. Para ello, se analiza la matriz de interacciones entre usuarios y productos, identificando grupos de usuarios con patrones de interacción semejantes. De esta manera, el sistema puede recomendar a un usuario productos que han sido valorados positivamente por otros usuarios del mismo grupo.
- Filtros basados en contenido: A diferencia de los filtros colaborativos, que se centran únicamente en las interacciones entre usuarios y productos, los filtros basados en contenido consideran atributos tanto de los usuarios como de los productos. Por ejemplo, se puede analizar la edad, sexo, intereses o historial de compras de un usuario para crear un perfil que lo caracterice. De igual manera, se pueden analizar las características de los productos, como su categoría, precio o descripción. Con base en esta información, el sistema puede recomendar productos que compartan características similares a aquellos que el usuario ha valorado previamente.
Tipos de sistemas de recomendación:
Los sistemas de recomendación pueden clasificarse en dos categorías principales:
- Sistemas basados en memoria: Estos sistemas almacenan un registro histórico de las interacciones entre usuarios y productos, utilizando esta información para generar recomendaciones. La ventaja de este enfoque radica en su simplicidad y eficiencia, sin embargo, puede presentar limitaciones en cuanto a la capacidad de procesar grandes volúmenes de datos.
- Sistemas basados en modelos: A diferencia de los sistemas basados en memoria, estos sistemas construyen modelos estadísticos o de aprendizaje automático a partir de las interacciones entre usuarios y productos. Estos modelos permiten realizar recomendaciones más precisas y personalizadas, adaptándose a las preferencias y comportamientos cambiantes de los usuarios. Sin embargo, su implementación puede ser más compleja y requerir mayor potencia de procesamiento.
En la medida en que la tecnología ha avanzado tanto en capacidad de procesamiento como por el desarrollo o mejoramiento de nuevos algoritmos, conjuntamente con las huellas digitales que dejan las personas en la internet, estos sistemas se vuelvan aún más sofisticados y precisos, ofreciendo una experiencia de usuario cada vez más relevante y atractiva, pero al mismo tiempo, y de acuerdo con algunas voces críticas, una creciente invasión a la privacidad y una mayor capacidad de manipulación. Voy a reproducir un ejemplo del libro Collective Intelligence de Toby Segaran, elaborado originalmente en python. Correré el ejemplo usando R.
Recomendando películas
Supongamos que tengo un listado de personas que han calificado un grupo de películas:
persona | Lady | Snakes | Just | Superman | You | Night |
---|---|---|---|---|---|---|
Lisa | 2.5 | 3.5 | 3.0 | 3.5 | 2.5 | 3.0 |
Gene | 3.0 | 3.5 | 1.5 | 5.0 | 3.5 | 3.0 |
Michael | 2.5 | 3.0 | 0.0 | 3.5 | 0.0 | 4.0 |
Claudia | 0.0 | 3.5 | 3.0 | 4.0 | 2.5 | 4.5 |
Mick | 3.0 | 4.0 | 2.0 | 3.0 | 2.0 | 3.0 |
Jack | 3.0 | 4.0 | 0.0 | 5.0 | 3.5 | 3.5 |
Toby | 0.0 | 4.5 | 0.0 | 4.0 | 1.0 | 0.0 |
Por las características de esta matriz, observo que no tengo variables adicionales ni sobre las películas ni sobre los críticos, por consiguiente, puedo construir un sistema de recomendación colaborativo basado en memoria. El sistema que construya, por un lado me debe indicar qué críticos son similares tomando como base las calificaciones que le asignaron a las películas que hayan visto en común. Con esta similitud se puede, entonces, recomendar una película a los críticos que no hayan visto o calificado alguna película.
Lo primero que debemos hacer es obtener una vía para obtener la similitud entre los críticos. En principio, si tomo en cuenta las puntuaciones básicas que cada uno de ellos ha asignado, puedo obtener un espacio de preferencia y tener una primera aproximación de la similitud entre ellos.
dispersion_gr <- function(x, y, palabras = NULL,
ejex = "", ejey = "",
titulo = ""){
plot(x, y, type = "n",
xlab= ejex, title = titulo,
ylab = ejey)
text(x, y, as.character(palabras),
cex = 0.7)
}
dispersion_gr(criticos$You,
criticos$Snakes,
criticos$persona,
"You, Me, and Dupree",
"Snakes on the Plane",
"Puntuaciones")
El gráfico nos indica que Claudia y Lisa le dieron la misma puntuación a dos películas. Mick y Jack puntearon de forma similar a "Snakes on the Plane", pero diferente a "You, Me, and Dupree". Toby y Michael se parecen menos a cualquier otro de los cinéfilos. Toby puntean con la mayor calificación a "Snakes on the Plane", y sólo le otorga 1 a "You, Me, and Dupree". Michael no vió esta última, y le dió 3 puntos a la primera. Entre más cerca están las personas en este espacio, más similares son en sus preferencias.
Si quiero saber la distancia entre Toby y Mick, resto las puntuaciones que dieron a cada película, las elevo al cuadrado, sumo el resultado y obtengo la raíz cuadrada. Es decir, estoy aplicando la distancia euclídea:
# toby <- c(4.5, 1)
# Mick <- c(4, 2)
sqrt((4.5-4)^2 + (1-2)^2)
## [1] 1.118034
Entre más cercana son las personas, más pequeña es la distancia:
# Michael y Toby
sqrt((3-4.5)^2 + (0-1)^2)
## [1] 1.802776
El resultado indica que Toby y Mick están más cercanos entre sí en comparación con Toby y Michael. Algo que el espacio de preferencias indica con claridad.
Pero si quiero saber no tanto la distancia sino la similaridad, hay que darle valores altos a las personas que son más parecidas. Para ello se agrega 1 a la función y se la invierte:
# Toby y Mick
1/(1 +sqrt((4.5-4)^2 + (1-2)^2))
## [1] 0.472136
# Toby y Michael
1/(1+sqrt((3-4.5)^2 + (0-1)^2))
## [1] 0.3567892
El resultado indica que Toby y Mick son más similares entre sí que Toby y Michael al valorar las dos películas seleccionadas. El resultado de este modelo estará siempre entre 0 y 1. Con una función puedo acelar el proceso de inspección de similitud con base en toda la data.
Algunas distancias. Ejemplos
usuario_usuario <- function(matriz, personas = c(""))
{
# selecciono los usuarios
seleccion <- matriz %>%
filter(persona %in% personas)
productos <- select_if(seleccion, is.numeric)
usuarios <- select_if(seleccion, is.character)
distancia <- dist(productos,
method = "euclidean")
similitud <- round(1/(1+distancia), 4)
paste("La similitud entre:",
personas[1], "y",
personas[2],"es = ", similitud)
}
usuario_usuario(criticos, c("Toby", "Michael"))
## [1] "La similitud entre: Toby y Michael es = 0.1646"
usuario_usuario(criticos, c("Toby", "Lisa"))
## [1] "La similitud entre: Toby y Lisa es = 0.1595"
El resultado nos indica que hay mayor similitud entre Toby y Michael en sus forma de calificar las películas que entre Toby y Lisa en la valoración de todas las películas.
Además de la distancia euclìdea puedo usar muchas otras mejor adaptada el tipo de data de la matriz de incidencia. Por ejemplo la correlación de Pearson ha demostrado ser una mejor medida de distancia en casos en los que las puntuaciones varían sustancialmente: algunos críticos son mucho más estrictos que otros en su puntuación.
usuario_pearson <- function(matriz, personas = c(""))
{
# extraigo las persona que han evaluado
seleccion <- matriz %>%
filter(persona %in% personas)
# obtengo las peliculas
productos <- seleccion %>%
gather(pelicula, puntuacion, -persona) %>%
filter(puntuacion > 0) %>%
group_by(pelicula) %>%
count(pelicula) %>%
filter(n > 1)
#spread(pelicula, puntuacion)
# encontrar la correlacion de Pearson entre los
# criticos
a <- unname(unlist(productos$pelicula))
b <- seleccion[, a]
c <- t(b)
n <- ncol(c)
sumx <- sum(c[,1])
sumy <- sum(c[,2])
xy <- sum(c[,1]*c[,2])
x2 <- sum(c[,1]^2)
y2 <- sum(c[,2]^2)
sumx2 <- sumx^2
sumy2 <- sumy^2
num <- (n*xy) - (sumx*sumy)
denx <- (n*x2-sumx2)
deny <- (n*y2-sumy2)
denxy <- denx * deny
raiz <- sqrt(denxy)
r = num/raiz
#usuarios <- select_if(seleccion, is.character)
return(r)
}
usuario_pearson(criticos, c("Toby", "Lisa"))
## [1] -1.210091
Ahora busco la forma de poder obtenercon un crítico dado, de modo que, si éste está interesado, pueda revisar en primer lugar las opiniones que emiten aquellos que han punteado las pelìculas de manera similar a como las ha evaluado él
criticos_recomendados <- function(matriz, critico,
n= 3){
# hallar la correlacion entre los criticos
a <- cor(t(criticos[,2:7]))
diag(a)<-0
colnames(a) <- criticos$persona
rownames(a) <- criticos$persona
a <- data.frame(a)
# seleccionar el critico de interes
sort(a[critico,], decreasing = T)[1:n]
# obtener los tres que mas se le parecen
}
Aplico la funcion para tres criticos
criticos_recomendados(criticos, "Toby")
## Lisa Gene Mick
## Toby 0.7957438 0.7038607 0.6408284
criticos_recomendados(criticos, "Gene")
## Jack Toby Michael
## Gene 0.9415184 0.7038607 0.5310078
Toby debería leer las opiniones de Lisa, Gene y Mick; Gene, de Jack, Toby y Michael.
A continuación, habría que recomendarle películas a quien no las haya visto. Creo la función para medir la similitud entre las películas
evaluar_tambien <- function(similares, matriz){
buscar <- c(rownames(similares),
colnames(similares))
criticos %>%
filter(persona %in% buscar) %>%
gather(pelicula, puntuacion,
-persona) -> pa_recomendar
recomendar <- pa_recomendar %>%
filter(puntuacion == 0)
recomendar %<>%
group_by(pelicula) %>%
count(pelicula)
vio <- pa_recomendar %>%
filter(puntuacion > 0,
persona %in% rownames(similares))
paste("Las personas que evaluaron:", vio$pelicula,
"tambien evaluaron:", recomendar$pelicula)
}
Pruebo la funcion
a <- criticos_recomendados(criticos, "Gene")
evaluar_tambien(a, criticos)
## [1] "Las personas que evaluaron: Lady tambien evaluaron: Just"
## [2] "Las personas que evaluaron: Snakes tambien evaluaron: Lady"
## [3] "Las personas que evaluaron: Just tambien evaluaron: Night"
## [4] "Las personas que evaluaron: Superman tambien evaluaron: You"
## [5] "Las personas que evaluaron: You tambien evaluaron: Just"
## [6] "Las personas que evaluaron: Night tambien evaluaron: Lady"
a <- criticos_recomendados(criticos, "Toby")
recomienda_producto <- function(criticosRecomendados, df){
# extraigo al deseado
mi_critico <- rownames(criticosRecomendados)
# obtengo los criticos similares a mi_critico
buscar <- c(colnames(a))
# elimino el nombre de mi_critico de la data
rownames(buscar) <- NULL
# selecciono las recomendaciones hechas por los criticos
# similares
recomendaciones <- criticos %>%
filter(persona %in% buscar)
numericas <- select_if(recomendaciones, is.numeric)
# eliminar valores ceros
numericas * t(criticosRecomendados) -> pesos
total <- rowSums(criticosRecomendados)
columnas <- colSums(numericas)
sim.sum <- total/columnas[columnas != 0]
sim.sum<-sort(sim.sum, decreasing = T)
return(sim.sum)
}
recomienda_producto(a, criticos)
## Just You Lady Night Snakes Superman
## 0.3292974 0.2675541 0.2518156 0.2378259 0.1945848 0.1861246
Ahora mezclo todos los conceptos vistos y elaboro una función que me permita recomendar productos, tomando en cuenta, en este caso, al crítico más parecido a un crítico pre-seleccionado
obtener_recomendacion <- function(matriz, miPersona, n = nrow(matriz)){
#extraer el critico deseado
mi_critico <- matriz %>%
filter(persona %in% miPersona)
# veo que peliculas no ha evaluado
no_vistas <- mi_critico %>%
gather(pelicula, puntuacion, -persona) %>%
filter(puntuacion == 0) %>%
spread(pelicula, puntuacion)
# si el critico ha punteado todo,no hay nada que recomendar
mensaje <- "Por ahora no hay recomendacion"
if(ncol(no_vistas) == 1){
return(mensaje)
} else {
# busco las personas mas similares a mi_critico
criticos.sim <- criticos_recomendados(matriz, miPersona,
n = n)
# busco los criticos que no son mi_critico
seleccion <- matriz %>%
filter(!persona %in% miPersona)
# selecciono de ese df las que mi_critico no ha visto
para_ver <- seleccion[, colnames(no_vistas)]
# anulo nombre de filas
rownames(criticos.sim) <- NULL
# elimino de los criticos el nombre del critico seleccionado
score <- t(criticos.sim)
score <-score[which(rownames(score)!= miPersona),]
# elimino caracteres
numericas <- select_if(seleccion, is.numeric)
# obtengo los pesos
numericas * t(score) -> pesos
# Obtengo la sumatoria de las similitudes
total <- sum(score)
# Obtengo la sumatoria de las peliculas
columnas <- colSums(numericas)
# obtengo los valores de la pelicula de acuerdo con los
# criticos mas parecidos al critico seleccinado
sim.sum <- total/columnas[columnas != 0]
# ordeno de mayor a menor y obtengo las dos primeras
# recomendaciones mas altos
sim.sum<-sort(sim.sum, decreasing = T)[1:2]
return(sim.sum)
}
}
Pruebo
obtener_recomendacion(criticos, "Gene")
## [1] "Por ahora no hay recomendacion"
obtener_recomendacion(criticos, "Toby")
## Just Lady
## 0.3731090 0.2531811
obtener_recomendacion(criticos, "Mick")
## [1] "Por ahora no hay recomendacion"
obtener_recomendacion(criticos, "Jack")
## Just Lady
## 0.3556534 0.3071552
Hay un defecto en este recomendador y es que las películas más populares reciben siempre el primer lugar de recomendacion. Si le agrego un elemento de aleatoriedad mediante sample(1:6,1) puedo introducir la posiblidad de que no sea la película más popular la que se recomiende siempre.
Ejemplos adicionales
Trabajo un ejemplo proveniente de la página http://www.salemmarafi.com/code/collaborative-filtering-r/. Sigo el mismo procedimiento, pero empleo la data que he venido trabajando.
El primer paso consiste en crear la función para medir la distancia, En este caso, la distancia coseno.
getCosine <- function(x,y)
{
this.cosine <- sum(x*y) / (sqrt(sum(x*x)) * sqrt(sum(y*y)))
return(this.cosine)
}
Para observar qué películas son similares entre ellas, me quedo sólo con los valores de las películas, sin los usuarios
peliculas <- criticos[, 2:7]
Creo una matriz vacía que llenaré posteriormente cuando calcule la distancia coseno ya definida:
peliculas_sim <- matrix(NA,
nrow=ncol(peliculas),
ncol=ncol(peliculas),
dimnames=list(colnames(peliculas),
colnames(peliculas)))
knitr::kable(peliculas_sim,
row.names = FALSE
)
Lady | Snakes | Just | Superman | You | Night |
---|---|---|---|---|---|
NA | NA | NA | NA | NA | NA |
NA | NA | NA | NA | NA | NA |
NA | NA | NA | NA | NA | NA |
NA | NA | NA | NA | NA | NA |
NA | NA | NA | NA | NA | NA |
NA | NA | NA | NA | NA | NA |
Itero en las películas originales para aplicar la distancia a las columnas:
# Lets fill in those empty spaces with cosine similarities
# Itero entre las columnas
for(i in 1:ncol(peliculas)) {
# itero por cada culumna
for(j in 1:ncol(peliculas)) {
# relleno con la distancia coseno
peliculas_sim[i,j] <- getCosine(as.matrix(peliculas[i]),as.matrix(peliculas[j]))
}
}
# Transformo la matriz en data.frame
peliculas_sim <- as.data.frame(peliculas_sim)
knitr::kable(peliculas_sim)
Lady | Snakes | Just | Superman | You | Night | |
---|---|---|---|---|---|---|
Lady | 1.0000000 | 0.8156887 | 0.5815915 | 0.8364864 | 0.8163351 | 0.8423369 |
Snakes | 0.8156887 | 1.0000000 | 0.7025733 | 0.9798781 | 0.8767683 | 0.8690098 |
Just | 0.5815915 | 0.7025733 | 1.0000000 | 0.6802298 | 0.7598559 | 0.7712312 |
Superman | 0.8364864 | 0.9798781 | 0.6802298 | 1.0000000 | 0.9153023 | 0.8995283 |
You | 0.8163351 | 0.8767683 | 0.7598559 | 0.9153023 | 1.0000000 | 0.8435202 |
Night | 0.8423369 | 0.8690098 | 0.7712312 | 0.8995283 | 0.8435202 | 1.0000000 |
Para seleccionar las películas, de acuerdo con la similitud, ordeno los vecinos más próximos de cada película. Para ello creo una matriz en la que luego se coloca la información
pelis <- peliculas_sim
diag(peliculas_sim) <- 0
peliculas_vec <- matrix(NA,
nrow=ncol(peliculas_sim), ncol= 6, dimnames=list(colnames(peliculas_sim)))
Itero, para obtener la data
for(i in 1:ncol(peliculas_sim))
{
peliculas_vec[i,] <- t(rownames(peliculas_sim[order(
peliculas_sim[,i],
decreasing=TRUE),][i]))
}
knitr::kable(peliculas_vec)
Lady | Night | Superman | You | Snakes | Just | Lady |
Snakes | Superman | You | Night | Lady | Just | Snakes |
Just | Night | You | Snakes | Superman | Lady | Just |
Superman | Snakes | You | Night | Lady | Just | Superman |
You | Superman | Snakes | Night | Lady | Just | You |
Night | Superman | Snakes | You | Lady | Just | Night |
Quien vea la película Lady, se le puede recomendar las peliculas Night y Superman; a quien le guste la película Snakes, se le puede recomendar las películas Superman y You, y así sucesivamente.
Puedo crear una funcion con todo el procedimiento y obtener así un rcomendador para productos:
productos <- function(dato, n = 5){
getCosine <- function(x,y)
{
this.cosine <- sum(x*y) / (sqrt(sum(x*x)) *
sqrt(sum(y*y)))
return(this.cosine)
}
peliculas_sim <- matrix(NA,
nrow=ncol(dato),
ncol=ncol(dato),
dimnames=list(colnames(dato),
colnames(dato)))
for(i in 1:ncol(dato)) {
# Loop through the columns for each column
for(j in 1:ncol(dato)) {
# Fill in placeholder with cosine similarities
peliculas_sim[i,j] <- getCosine(as.matrix(dato[i]),
as.matrix(dato[j]))
}
}
diag(peliculas_sim)<-0
peliculas_sim <- as.data.frame(peliculas_sim)
peliculas_vec <- matrix(NA,
nrow=ncol(peliculas_sim),
ncol= n,
dimnames=list(colnames(peliculas_sim)))
for(i in 1:ncol(peliculas_sim))
{
peliculas_vec[i,] <- t(head(n = n,
rownames(peliculas_sim[order(
peliculas_sim[,i],
decreasing=TRUE),][i])))
}
colnames(peliculas_vec) <- paste0("opcion_", 1:n)
peliculas_vec <- as.data.frame(peliculas_vec)
return( peliculas_vec)
}
Fue necesario refinar el procedimiento para evitar que una película que ya he visto me sean recomendadas. Esto ocurría porque la diagonal no se había llevado a 0, por tanto, la primera opción eran la mismas películas, puesto que la mayor similitud es 1.
Aplico
productos(criticos[,2:7])
## opcion_1 opcion_2 opcion_3 opcion_4 opcion_5
## Lady Night Superman You Snakes Just
## Snakes Superman You Night Lady Just
## Just Night You Snakes Superman Lady
## Superman Snakes You Night Lady Just
## You Superman Snakes Night Lady Just
## Night Superman Snakes You Lady Just
Analizo ahora las recomendaciones para quienes no hayan analizado alguna película
# Funcion para calcular las puntuaciones
getScore <- function(history, similarities)
{
x <- sum(history * similarities)/sum(similarities)
x
}
Genero una matriz para ingresar luego las puntuaciones
peliculas_sim <- pelis
# A placeholder matrix
holder <- matrix(NA, nrow = nrow(criticos),
ncol = ncol(criticos)-1,
dimnames=list((criticos$persona),
colnames(criticos[-1])))
# Loop through the users (rows)
for(i in 1:nrow(holder))
{
# itero (columns)
for(j in 1:ncol(holder))
{
# Obtengo el nombre de la película y del crítico
user <- rownames(holder)[i]
product <- colnames(holder)[j]
# para no recomendar una película ya vista por ambas parte
# creo una cadena vacía en la que guardo el nombre de la pelicula vista
if(as.integer(criticos[criticos$persona==user,
product]) == 1)
{
holder[i,j]<-""
} else {
# Obtengo las películas con mayor similaridad
topN<-((head(n=3,(peliculas_sim[order(peliculas_sim[,
product],decreasing=TRUE),][product]))))
topN.names <- as.character(rownames(topN))
topN.similarities <- as.numeric(topN[,1])
# elimino filas
topN.similarities<-topN.similarities[-1]
topN.names<-topN.names[-1]
# obtengo el historial de las peliculas
topN.purchases<- criticos[,
c("persona",
topN.names)]
topN.userPurchases<-topN.purchases[topN.purchases$user==user,]
topN.userPurchases <- as.numeric(topN.userPurchases[!(names(topN.userPurchases) %in% c("user"))])
# calculo la puntuación del usuario y de la pelicula
holder[i,j]<-getScore(similarities=topN.similarities,history=topN.userPurchases)
} # cierre de else
} # cierre del loop for
} # cierre for loop para los usuarios
criticos.scores <- holder
# 10 vecinos en orden de acuerdo con la similaridad
topN<-((head(n=6,(peliculas_sim[order(
peliculas_sim[,product],decreasing=TRUE),
][product]))))
topN
## Night
## Night 1.0000000
## Superman 0.8995283
## Snakes 0.8690098
## You 0.8435202
## Lady 0.8423369
## Just 0.7712312
topN.names <- as.character(rownames(topN))
topN.similarities <- as.numeric(topN[,1])
topN.similarities
## [1] 1.0000000 0.8995283 0.8690098 0.8435202 0.8423369 0.7712312
# topN.similarities<-topN.similarities[-1]
#topN.names<-topN.names[-1]
# We then get the user's purchase history for those 10 items
topN.purchases<- criticos[,c("persona",topN.names)]
topN.purchases
## # A tibble: 7 x 7
## persona Night Superman Snakes You Lady Just
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Lisa 3 3.5 3.5 2.5 2.5 3
## 2 Gene 3 5 3.5 3.5 3 1.5
## 3 Michael 4 3.5 3 0 2.5 0
## 4 Claudia 4.5 4 3.5 2.5 0 3
## 5 Mick 3 3 4 2 3 2
## 6 Jack 3.5 5 4 3.5 3 0
## 7 Toby 0 4 4.5 1 0 0
topN.userPurchases<-topN.purchases[topN.purchases$persona==user,]
topN.userPurchases
## # A tibble: 1 x 7
## persona Night Superman Snakes You Lady Just
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Toby 0 4 4.5 1 0 0
topN.userPurchases <- as.numeric(topN.userPurchases[!(names(topN.userPurchases) %in% c("user"))])
topN.userPurchases
## [1] NA 0.0 4.0 4.5 1.0 0.0 0.0
holder[i,j]<-getScore(similarities=topN.similarities,
history=topN.userPurchases)
# Lets make our recommendations pretty
criticos.scores.holder <- matrix(NA,
nrow=nrow(criticos.scores),
ncol=6,
dimnames=list(
rownames( criticos.scores)
))
for(i in 1:nrow(criticos.scores))
{
criticos.scores.holder[i,] <- names(head(n=6,
(criticos.scores[, order(criticos.scores.holder[i,],
decreasing=TRUE)])[i,]))
}
Medidas de similitud
x1 <- rnorm(30)
x2 <- rnorm(30)
Euc_dist = dist(rbind(x1,x2) ,method="euclidean")
vec1 = c( 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 )
vec2 = c( 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 )
library(lsa)
cosine(vec1,vec2)
## [,1]
## [1,] 0.2357023
Coef = cor(mtcars, method="pearson")
R cuenta con el paquete recommenderlab para analizar y hacer recomendaciones. Nos ahorramos todos estos pasos que hemos seguido hasta aquí.
No hay comentarios.:
Publicar un comentario