Filtrado colaborativo en Python
Los Sistemas Recomendadores son una colección de algoritmos utilizados para sugerir temas a los usuarios basados en información tomada desde el punto de vista del usuario. Estos sistemas ubicuos pueden ser comúnmente vistos en tiendas online, bases de datos de películas y buscadores de empleos. Vamos a ver los sistemas de recomendación basados en Contenido e implementaremos una versión de filtrado colaborativo en Python y la librería Pandas.
Primero, importemos las librerías necesarias:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#librería de manipulación de dataframes
import pandas as pd
#Funciones matemáticas, necesitaremos sólo importar la función sqrt
from math import sqrt
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
[/sourcecode]
Adquisición de Datos
Para adquirir y extraer los datos, simplemente ejecuta los siguientes scripts Bash:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
!wget -O moviedataset.zip https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/moviedataset.zip
print(‘unziping …’)
!unzip -o -j moviedataset.zip
[/sourcecode]
--2020-03-06 17:12:19-- https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/moviedataset.zip Resolving s3-api.us-geo.objectstorage.softlayer.net (s3-api.us-geo.objectstorage.softlayer.net)... 67.228.254.196 Connecting to s3-api.us-geo.objectstorage.softlayer.net (s3-api.us-geo.objectstorage.softlayer.net)|67.228.254.196|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 160301210 (153M) [application/zip] Saving to: ‘moviedataset.zip’ moviedataset.zip 100%[===================>] 152.88M 19.2MB/s in 8.4s 2020-03-06 17:12:27 (18.1 MB/s) - ‘moviedataset.zip’ saved [160301210/160301210] unziping ... Archive: moviedataset.zip inflating: links.csv inflating: movies.csv inflating: ratings.csv
Ahora carguemos cada archivo dentro de su dataframe:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Guardando la información de la película dentro de un dataframe de panda
movies_df = pd.read_csv(‘movies.csv’)
#Guardando información del usuario dentro de un dataframe de panda
ratings_df = pd.read_csv(‘ratings.csv’)
[/sourcecode]
Miremos cada uno de ellos a ver cómo están organizados:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Head es una función que obtiene las primeras N filas de un dataframe. El valor por omisión de N es 5.
movies_df.head()
[/sourcecode]
movieId | title | genres | |
---|---|---|---|
0 | 1 | Toy Story (1995) | Adventure|Animation|Children|Comedy|Fantasy |
1 | 2 | Jumanji (1995) | Adventure|Children|Fantasy |
2 | 3 | Grumpier Old Men (1995) | Comedy|Romance |
3 | 4 | Waiting to Exhale (1995) | Comedy|Drama|Romance |
4 | 5 | Father of the Bride Part II (1995) | Comedy |
Cada película tiene un único ID, un título con su año de estreno (El cual puede contener caracteres unicode) y muchos géneros diferentes en el mismo campo. Saquemos el año de la columna del título y ubiquemoslo en su propia columna con la función extract que viene con Pandas.
Saquemos el año de la columna title utilizando la función de pandas replace y guardémoslo en la nueva columna year.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Utilizar expresiones regulares para encontrar un año guardado entre paréntesis
#Especificamos los paréntesis de forma tal de que no haya problemas con las películas que tiene el año en sus títulos
movies_df[‘year’] = movies_df.title.str.extract(‘(
#Sacando los paréntesis
movies_df[‘year’] = movies_df.year.str.extract(‘(\d\d\d\d)’,expand=False)
#Sacando los años de la columna ‘title’
movies_df[‘title’] = movies_df.title.str.replace(‘(
#Aplicando la función strip para sacar los espacios finales que pudiera haber
movies_df[‘title’] = movies_df[‘title’].apply(lambda x: x.strip())
[/sourcecode]
Veamos el resultado
[sourcecode language=»python» wraplines=»false» collapse=»false»]
movies_df.head()
[/sourcecode]
movieId | title | genres | year | |
---|---|---|---|---|
0 | 1 | Toy Story | Adventure|Animation|Children|Comedy|Fantasy | 1995 |
1 | 2 | Jumanji | Adventure|Children|Fantasy | 1995 |
2 | 3 | Grumpier Old Men | Comedy|Romance | 1995 |
3 | 4 | Waiting to Exhale | Comedy|Drama|Romance | 1995 |
4 | 5 | Father of the Bride Part II | Comedy | 1995 |
Luego, saquemos la columna de los géneros ya que no los necesitaremos para este sistema recomendador.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Eliminando la columna géneros
movies_df = movies_df.drop(‘genres’, 1)
[/sourcecode]
Aquí está el dataframe final:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
movies_df.head()
[/sourcecode]
movieId | title | year | |
---|---|---|---|
0 | 1 | Toy Story | 1995 |
1 | 2 | Jumanji | 1995 |
2 | 3 | Grumpier Old Men | 1995 |
3 | 4 | Waiting to Exhale | 1995 |
4 | 5 | Father of the Bride Part II | 1995 |
Ahora, veamos el dataframe de los ratings.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
ratings_df.head()
[/sourcecode]
userId | movieId | rating | timestamp | |
---|---|---|---|---|
0 | 1 | 169 | 2.5 | 1204927694 |
1 | 1 | 2471 | 3.0 | 1204927438 |
2 | 1 | 48516 | 5.0 | 1204927435 |
3 | 2 | 2571 | 3.5 | 1436165433 |
4 | 2 | 109487 | 4.0 | 1436165496 |
Cada fila en el dataframe ratings tiene un id de usuario asociado con al menos una película, un rating y una marca de tiempo que muestra cuando se revisó. No se necesitará la columna timestamp, por lo que se eliminará para ahorrar memoria.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Drop elimina una fila en particular o columna dentro de un dataframe
ratings_df = ratings_df.drop(‘timestamp’, 1)
[/sourcecode]
Asi es cómo el Dataframe definitivo se ve:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
ratings_df.head()
[/sourcecode]
userId | movieId | rating | |
---|---|---|---|
0 | 1 | 169 | 2.5 |
1 | 1 | 2471 | 3.0 |
2 | 1 | 48516 | 5.0 |
3 | 2 | 2571 | 3.5 |
4 | 2 | 109487 | 4.0 |
Filtrado Colaborativo en python
Ahora, comenzaremos el trabajo con los sistemas recomendadores.
La primer técnica que vas a ver se llama Filtrado Colaborativo, también conocido como Filtrado de Usuario a Usuario. Como lo indica su nombre alternativo, esta técnica utiliza otros usuarios para recomendar items al ingreso de datos. Se intenta encontrar usuarios que tengan preferencias y opiniones parecidas para entonces recomendar items que se hayan parecido al ingreso anterior. Existen varios métodos para encontrar usuarios parecidos (Incluso los que utilizan Machine Learning), y el método que vamos a utilizar estará basado en la Función de Correlación de Pearson.
El proceso para crear un sistema de recomendación Basado en el Usuario es el siguiente:
- Elegir un usuario con las películas que el usuario ha mirado
- Basado en su indice de selección de películas, encuentra a los primeros X vecinos
- Obtener el registro de la película que miró el usuario para cada vecino.
- Calcular un puntaje de similitud utilizando alguna fórmula
- Recomendar los ítems con los puntajes más altos
Comencemos creando un usuario a quien recomendar películas:
Nota: Para agregar más películas, aumenta la catidad de elementos en userInput. Agrega tantos como desees! Solo asegúrate de escribir en letras mayúsculas y si una película comienza con un «The», como «The Matrix» entonces escríbelo así: ‘Matrix, The’.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
userInput = [
{‘title’:’Breakfast Club, The’, ‘rating’:5},
{‘title’:’Toy Story’, ‘rating’:3.5},
{‘title’:’Jumanji’, ‘rating’:2},
{‘title’:"Pulp Fiction", ‘rating’:5},
{‘title’:’Akira’, ‘rating’:4.5}
]
inputMovies = pd.DataFrame(userInput)
inputMovies
[/sourcecode]
title | rating | |
---|---|---|
0 | Breakfast Club, The | 5.0 |
1 | Toy Story | 3.5 |
2 | Jumanji | 2.0 |
3 | Pulp Fiction | 5.0 |
4 | Akira | 4.5 |
Agregar movieId al ingreso del usuario: Con las datos ingresados completos, extraigamos los ID de las películas del dataframe de películas y agreguémosla.
Esto se logra primero sacando las filas que tienen que tienen títulos de películas y luego une este subconjunto con el dataframe de entrada. También sacamos columnas que no se necesitan para ahorrar espacio de memoria.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Filtrar las películas por título
inputId = movies_df[movies_df[‘title’].isin(inputMovies[‘title’].tolist())]
#Luego juntarlas para obtener el movieId. Implícitamente, lo está uniendo por título.
inputMovies = pd.merge(inputId, inputMovies)
#Eliminando información que no utilizaremos del dataframe de entrada
inputMovies = inputMovies.drop(‘year’, 1)
#Dataframe de entrada final
#Si una película que se agregó no se encuentra, entonces podría no estar en el dataframe
#original o podría estar escrito de otra forma, por favor revisar mayúscula o minúscula.
inputMovies
[/sourcecode]
movieId | title | rating | |
---|---|---|---|
0 | 1 | Toy Story | 3.5 |
1 | 2 | Jumanji | 2.0 |
2 | 296 | Pulp Fiction | 5.0 |
3 | 1274 | Akira | 4.5 |
4 | 1968 | Breakfast Club, The | 5.0 |
Usuarios que han visto las mismas películas: Ahora, que el ID de la película está como entrada, podemos obtener el subconjunto de usuarios que han visto o revisado las películas en nuestra entrada.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Filtrando los usuarios que han visto las películas y guardándolas
userSubset = ratings_df[ratings_df[‘movieId’].isin(inputMovies[‘movieId’].tolist())]
userSubset.head()
[/sourcecode]
userId | movieId | rating | |
---|---|---|---|
19 | 4 | 296 | 4.0 |
441 | 12 | 1968 | 3.0 |
479 | 13 | 2 | 2.0 |
531 | 13 | 1274 | 5.0 |
681 | 14 | 296 | 2.0 |
Ahora agrupamos las filas por el ID del usuario.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Groupby crea varios dataframes donde todos tienen el mismo valor para la columna especificada como parámetro
userSubsetGroup = userSubset.groupby([‘userId’])
[/sourcecode]
Miremos a uno de los usuarios, por ejemlo, el userID=1130
[sourcecode language=»python» wraplines=»false» collapse=»false»]
userSubsetGroup.get_group(1130)
[/sourcecode]
userId | movieId | rating | |
---|---|---|---|
104167 | 1130 | 1 | 0.5 |
104168 | 1130 | 2 | 4.0 |
104214 | 1130 | 296 | 4.0 |
104363 | 1130 | 1274 | 4.5 |
104443 | 1130 | 1968 | 4.5 |
Ahora hagamos ordenamiento dentro de cada grupo de forma tal que los usuarios que compartan la mayor cantidad de películas tengan prioridad. Esto brinda una recomendación mejorada ya que no será necesario pasar por todos los usuarios.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Ordenamiento de forma tal de que los usuarios con más películas en común tengan prioridad
userSubsetGroup = sorted(userSubsetGroup, key=lambda x: len(x[1]), reverse=True)
[/sourcecode]
Ahora, miremos al primer usuario
[sourcecode language=»python» wraplines=»false» collapse=»false»]
userSubsetGroup[0:3]
[/sourcecode]
[(75, userId movieId rating 7507 75 1 5.0 7508 75 2 3.5 7540 75 296 5.0 7633 75 1274 4.5 7673 75 1968 5.0), (106, userId movieId rating 9083 106 1 2.5 9084 106 2 3.0 9115 106 296 3.5 9198 106 1274 3.0 9238 106 1968 3.5), (686, userId movieId rating 61336 686 1 4.0 61337 686 2 3.0 61377 686 296 4.0 61478 686 1274 4.0 61569 686 1968 5.0)]
Similitud entre usuarios y usuarios ingresantes
Luego, compararemos a todos los usuarios (casi todos) con nuestro usuario indicado y encontraremos el que más se parece.
Encontraremos cómo cada usuario similar se relacionan entre si a través del Coeficiente de Correlación de Pearson. Se utiliza para medir la fuerza de una asociación lineal entre dos variables. La fórmula para encontrar este coeficiente entre los conjuntos X e Y con los valores de N se puede ver en la fórmula:
¿Por qué la Correlación Pearson?
La correlación Pearson no varía con la escala, ejemplo: si se multiplican todos los elementos por una constante distinta a cero o si se agrega cualquier constante a todos los elementos. Por ejemplo, si tienes dos vectores
Los valores brindados por la fórumula puede variar de
Elegiremos un subconjunto de usuarios para hacer las iteraciones. Este limite existe porque no queremos desperdiciar mucho tiempo pasando por cada usuario.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
userSubsetGroup = userSubsetGroup[0:100]
[/sourcecode]
Ahora, calculemos la Correlación Pearson entre la entrada del usuario el grupo, para almacenarlo en el diccionario, donde la clave es el Id del usuario y el valor es el coeficiente
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Guardar la Correlación Pearson en un diccionario, donde la clave es el Id del usuario y el valor es el coeficiente
pearsonCorrelationDict = {}
#Para cada grupo de usuarios en nuestro subconjunto
for name, group in userSubsetGroup:
#Comencemos ordenando el usuario actual y el ingresado de forma tal que los valores no se mezclen luego
group = group.sort_values(by=’movieId’)
inputMovies = inputMovies.sort_values(by=’movieId’)
#Obtener el N para la fórmula
nRatings = len(group)
#Obtener los puntajes de revisión para las películas en común
temp_df = inputMovies[inputMovies[‘movieId’].isin(group[‘movieId’].tolist())]
#Guardarlas en una variable temporal con formato de lista para facilitar cálculos futuros
tempRatingList = temp_df[‘rating’].tolist()
#Pongamos también las revisiones de grupos de usuarios en una lista
tempGroupList = group[‘rating’].tolist()
#Calculemos la Correlación Pearson entre dos usuarios, x e y
Sxx = sum([i**2 for i in tempRatingList]) – pow(sum(tempRatingList),2)/float(nRatings)
Syy = sum([i**2 for i in tempGroupList]) – pow(sum(tempGroupList),2)/float(nRatings)
Sxy = sum( i*j for i, j in zip(tempRatingList, tempGroupList)) – sum(tempRatingList)*sum(tempGroupList)/float(nRatings)
#Si el denominador es diferente a cero, entonces dividir, sino, la correlación es 0.
if Sxx != 0 and Syy != 0:
pearsonCorrelationDict[name] = Sxy/sqrt(Sxx*Syy)
else:
pearsonCorrelationDict[name] = 0
[/sourcecode]
[sourcecode language=»python» wraplines=»false» collapse=»false»]
pearsonCorrelationDict.items()
[/sourcecode]
dict_items([(75, 0.8272781516947562), (106, 0.5860090386731182), (686, 0.8320502943378437), (815, 0.5765566601970551), (1040, 0.9434563530497265), (1130, 0.2891574659831201), (1502, 0.8770580193070299), (1599, 0.4385290096535153), (1625, 0.716114874039432), (1950, 0.179028718509858), (2065, 0.4385290096535153), (2128, 0.5860090386731196), (2432, 0.1386750490563073), (2791, 0.8770580193070299), (2839, 0.8204126541423674), (2948, -0.11720180773462392), (3025, 0.45124262819713973), (3040, 0.89514359254929), (3186, 0.6784622064861935), (3271, 0.26989594817970664), (3429, 0.0), (3734, -0.15041420939904673), (4099, 0.05860090386731196), (4208, 0.29417420270727607), (4282, -0.4385290096535115), (4292, 0.6564386345361464), (4415, -0.11183835382312353), (4586, -0.9024852563942795), (4725, -0.08006407690254357), (4818, 0.4885967564883424), (5104, 0.7674257668936507), (5165, -0.4385290096535153), (5547, 0.17200522903844556), (6082, -0.04728779924109591), (6207, 0.9615384615384616), (6366, 0.6577935144802716), (6482, 0.0), (6530, -0.3516054232038709), (7235, 0.6981407669689391), (7403, 0.11720180773462363), (7641, 0.7161148740394331), (7996, 0.626600514784504), (8008, -0.22562131409856986), (8086, 0.6933752452815365), (8245, 0.0), (8572, 0.8600261451922278), (8675, 0.5370861555295773), (9101, -0.08600261451922278), (9358, 0.692178738358485), (9663, 0.193972725041952), (9994, 0.5030272728659587), (10248, -0.24806946917841693), (10315, 0.537086155529574), (10368, 0.4688072309384945), (10607, 0.41602514716892186), (10707, 0.9615384615384616), (10863, 0.6020183016345595), (11314, 0.8204126541423654), (11399, 0.517260600111872), (11769, 0.9376144618769914), (11827, 0.4902903378454601), (12069, 0.0), (12120, 0.9292940047327363), (12211, 0.8600261451922278), (12325, 0.9616783115081544), (12916, 0.5860090386731196), (12921, 0.6611073566849309), (13053, 0.9607689228305227), (13142, 0.6016568375961863), (13260, 0.7844645405527362), (13366, 0.8951435925492911), (13768, 0.8770580193070289), (13888, 0.2508726030021272), (13923, 0.3516054232038718), (13934, 0.17200522903844556), (14529, 0.7417901772340937), (14551, 0.537086155529574), (14588, 0.21926450482675766), (14984, 0.716114874039432), (15137, 0.5860090386731196), (15157, 0.9035841064985974), (15466, 0.7205766921228921), (15670, 0.516015687115336), (15834, 0.22562131409856986), (16292, 0.6577935144802716), (16456, 0.7161148740394331), (16506, 0.5481612620668942), (17246, 0.48038446141526137), (17438, 0.7093169886164387), (17501, 0.8168748513121271), (17502, 0.8272781516947562), (17666, 0.7689238340176859), (17735, 0.7042381820123422), (17742, 0.3922322702763681), (17757, 0.64657575013984), (17854, 0.537086155529574), (17897, 0.8770580193070289), (17944, 0.2713848825944774), (18301, 0.29838119751643016), (18509, 0.1322214713369862)])
[sourcecode language=»python» wraplines=»false» collapse=»false»]
pearsonDF = pd.DataFrame.from_dict(pearsonCorrelationDict, orient=’index’)
pearsonDF.columns = [‘similarityIndex’]
pearsonDF[‘userId’] = pearsonDF.index
pearsonDF.index = range(len(pearsonDF))
pearsonDF.head()
[/sourcecode]
similarityIndex | userId | |
---|---|---|
0 | 0.827278 | 75 |
1 | 0.586009 | 106 |
2 | 0.832050 | 686 |
3 | 0.576557 | 815 |
4 | 0.943456 | 1040 |
Ahora obtengamos los 50 primeros usuarios más parecidos a los que se ingresaron.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
topUsers=pearsonDF.sort_values(by=’similarityIndex’, ascending=False)[0:50]
topUsers.head()
[/sourcecode]
similarityIndex | userId | |
---|---|---|
64 | 0.961678 | 12325 |
34 | 0.961538 | 6207 |
55 | 0.961538 | 10707 |
67 | 0.960769 | 13053 |
4 | 0.943456 | 1040 |
Recomendemos películas al usuario de entrada puntuando a los usuarios elegidos para todas las películas
Haremos esto tomando el peso promedio de los ratings de las películas utilizando la Correlación Pearson. Pero para hacer esto, primero necesitamos que los usuarios vean las películas en nuestro pearsonDF a partir del dataframe de puntajes y luego guardar su correlación en una nueva columna llamada _similarityIndex». Estos se logra juntando estas dos tablas de debajo.
[sourcecode language=»python» wraplines=»false» collapse=»false»]
topUsersRating=topUsers.merge(ratings_df, left_on=’userId’, right_on=’userId’, how=’inner’)
topUsersRating.head()
[/sourcecode]
similarityIndex | userId | movieId | rating | |
---|---|---|---|---|
0 | 0.961678 | 12325 | 1 | 3.5 |
1 | 0.961678 | 12325 | 2 | 1.5 |
2 | 0.961678 | 12325 | 3 | 3.0 |
3 | 0.961678 | 12325 | 5 | 0.5 |
4 | 0.961678 | 12325 | 6 | 2.5 |
Ahora todo lo que se necesita hacer es multiplicar el puntaje de la película por su peso (El índice de similitud), luego se suman los nuevos puntajes y dividen por la suma de los pesos.
Esto se logra sencillamente multiplicando dos columnas, luego agrupando el dataframe por la columna movieId y luego dividiendo dos columnas:
Aqui se muestra la idea de todos los usuarios similares respecto de las películas candidatas para el usuario ingresado:
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Se multiplica la similitud de los puntajes de los usuarios
topUsersRating[‘weightedRating’] = topUsersRating[‘similarityIndex’]*topUsersRating[‘rating’]
topUsersRating.head()
[/sourcecode]
similarityIndex | userId | movieId | rating | weightedRating | |
---|---|---|---|---|---|
0 | 0.961678 | 12325 | 1 | 3.5 | 3.365874 |
1 | 0.961678 | 12325 | 2 | 1.5 | 1.442517 |
2 | 0.961678 | 12325 | 3 | 3.0 | 2.885035 |
3 | 0.961678 | 12325 | 5 | 0.5 | 0.480839 |
4 | 0.961678 | 12325 | 6 | 2.5 | 2.404196 |
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Se aplica una suma a los topUsers luego de agruparlos por userId
tempTopUsersRating = topUsersRating.groupby(‘movieId’).sum()[[‘similarityIndex’,’weightedRating’]]
tempTopUsersRating.columns = [‘sum_similarityIndex’,’sum_weightedRating’]
tempTopUsersRating.head()
[/sourcecode]
sum_similarityIndex | sum_weightedRating | |
---|---|---|
movieId | ||
1 | 38.376281 | 140.800834 |
2 | 38.376281 | 96.656745 |
3 | 10.253981 | 27.254477 |
4 | 0.929294 | 2.787882 |
5 | 11.723262 | 27.151751 |
[sourcecode language=»python» wraplines=»false» collapse=»false»]
#Se crea un dataframe vacío
recommendation_df = pd.DataFrame()
#Ahora se toma el promedio ponderado
recommendation_df[‘weighted average recommendation score’] = tempTopUsersRating[‘sum_weightedRating’]/tempTopUsersRating[‘sum_similarityIndex’]
recommendation_df[‘movieId’] = tempTopUsersRating.index
recommendation_df.head()
[/sourcecode]
weighted average recommendation score | movieId | |
---|---|---|
movieId | ||
1 | 3.668955 | 1 |
2 | 2.518658 | 2 |
3 | 2.657941 | 3 |
4 | 3.000000 | 4 |
5 | 2.316058 | 5 |
Luego, ordenémoslo y veamos las primeras 20 películas que el algoritmo recomendó!
[sourcecode language=»python» wraplines=»false» collapse=»false»]
recommendation_df = recommendation_df.sort_values(by=’weighted average recommendation score’, ascending=False)
recommendation_df.head(10)
[/sourcecode]
weighted average recommendation score | movieId | |
---|---|---|
movieId | ||
5073 | 5.0 | 5073 |
3329 | 5.0 | 3329 |
2284 | 5.0 | 2284 |
26801 | 5.0 | 26801 |
6776 | 5.0 | 6776 |
6672 | 5.0 | 6672 |
3759 | 5.0 | 3759 |
3769 | 5.0 | 3769 |
3775 | 5.0 | 3775 |
90531 | 5.0 | 90531 |
[sourcecode language=»python» wraplines=»false» collapse=»false»]
movies_df.loc[movies_df[‘movieId’].isin(recommendation_df.head(10)[‘movieId’].tolist())]
[/sourcecode]
movieId | title | year | |
---|---|---|---|
2200 | 2284 | Bandit Queen | 1994 |
3243 | 3329 | Year My Voice Broke, The | 1987 |
3669 | 3759 | Fun and Fancy Free | 1947 |
3679 | 3769 | Thunderbolt and Lightfoot | 1974 |
3685 | 3775 | Make Mine Music | 1946 |
4978 | 5073 | Son’s Room, The (Stanza del figlio, La) | 2001 |
6563 | 6672 | War Photographer | 2001 |
6667 | 6776 | Lagaan: Once Upon a Time in India | 2001 |
9064 | 26801 | Dragon Inn (Sun lung moon hak chan) | 1992 |
18106 | 90531 | Shame | 2011 |
Ventajas y Desventajas del Filtro Colaborativo en python
- Ventajas
- Tiene en cuenta el puntaje de otros usuarios
- No necesita estudiar o extraer la información del elemento recomendado
- Se adapta al interés del usuario mientras cambia
- Desventajas
- La función de aproximación puede ser lenta
- Podriá surgir una cantidad baja de usuarios para aproximar
- Temas de privacidad cuando se intenta aprender de las preferencias del usuario