Tutoriel pour débutants : Systèmes de recommandation en Python

Source

Le but de ce tutoriel n’est pas de faire de vous un expert dans la construction de modèles de systèmes de recommandation. Au lieu de cela, le motif est de vous faire démarrer en vous donnant un aperçu du type de systèmes de recommandation qui existent et comment vous pouvez en construire un par vous-même

Dans ce tutoriel, vous apprendrez à construire un modèle de base de systèmes de recommandation simples et basés sur le contenu. Bien que ces modèles seront loin d’atteindre la norme de l’industrie en termes de complexité, de qualité ou de précision, cela vous aidera à commencer à construire des modèles plus complexes qui produisent des résultats encore meilleurs.

Les systèmes de recommandation font partie des applications les plus populaires de la science des données aujourd’hui. Ils sont utilisés pour prédire la « note » ou la « préférence » qu’un utilisateur donnerait à un article. Presque toutes les grandes entreprises technologiques les ont appliqués sous une forme ou une autre. Amazon s’en sert pour suggérer des produits aux clients, YouTube l’utilise pour décider de la vidéo suivante en lecture automatique, et Facebook l’utilise pour recommander des pages à aimer et des personnes à suivre.

Plus encore, pour certaines entreprises comme Netflix, Amazon Prime, Hulu et Hotstar, le modèle économique et son succès tournent autour de la puissance de leurs recommandations. Netflix a même offert un million de dollars en 2009 à quiconque pourrait améliorer son système de 10%.

Il existe également des systèmes de recommandation populaires pour des domaines comme les restaurants, les films et les rencontres en ligne. Des systèmes de recommandation ont également été développés pour explorer des articles de recherche et des experts, des collaborateurs et des services financiers. YouTube utilise le système de recommandation à grande échelle pour vous suggérer des vidéos en fonction de votre historique. Par exemple, si vous regardez beaucoup de vidéos éducatives, il vous suggérerait ces types de vidéos.

Mais quels sont ces systèmes de recommandation ?

Grandement, les systèmes de recommandation peuvent être classés en 3 types :

  • Recommandateurs simples : offrent des recommandations généralisées à chaque utilisateur, basées sur la popularité et/ou le genre des films. L’idée de base de ce système est que les films plus populaires et acclamés par la critique auront une probabilité plus élevée d’être aimés par le public moyen. Un exemple pourrait être le Top 250 d’IMDB.

  • Recommandeurs basés sur le contenu : suggèrent des articles similaires basés sur un article particulier. Ce système utilise les métadonnées de l’élément, comme le genre, le réalisateur, la description, les acteurs, etc. pour les films, pour faire ces recommandations. L’idée générale qui sous-tend ces systèmes de recommandation est que si une personne aime un article particulier, elle aimera également un article qui lui est similaire. Et pour recommander cela, le système utilisera les métadonnées des articles passés de l’utilisateur. Un bon exemple pourrait être YouTube, où sur la base de votre historique, il vous suggère de nouvelles vidéos que vous pourriez potentiellement regarder.
  • Moteurs de filtrage collaboratif : ces systèmes sont largement utilisés, et ils essaient de prédire la note ou la préférence qu’un utilisateur donnerait à un élément en se basant sur les notes et les préférences passées des autres utilisateurs. Les filtres collaboratifs ne nécessitent pas de métadonnées d’élément comme ses homologues basés sur le contenu.

Commandants simples

Comme décrit dans la section précédente, les recommandeurs simples sont des systèmes de base qui recommandent les meilleurs éléments en fonction d’une certaine métrique ou d’un score. Dans cette section, vous allez construire un clone simplifié du Top 250 des films d’IMDB en utilisant les métadonnées collectées à partir d’IMDB.

Les étapes suivantes sont impliquées:

  • Décider de la métrique ou du score sur lequel évaluer les films.

  • Calculer le score pour chaque film.

  • Trier les films en fonction du score et sortir les meilleurs résultats.

À propos de l’ensemble de données

Les fichiers de l’ensemble de données contiennent les métadonnées des 45 000 films répertoriés dans le Full MovieLens Dataset. Le jeu de données est constitué de films sortis au plus tard en juillet 2017. Ce jeu de données capture des points de caractéristiques comme le casting, l’équipe, les mots-clés de l’intrigue, le budget, les recettes, les affiches, les dates de sortie, les langues, les sociétés de production, les pays, le nombre de votes TMDB et les moyennes des votes.

Ces points de caractéristiques pourraient potentiellement être utilisés pour entraîner vos modèles d’apprentissage automatique pour le contenu et le filtrage collaboratif.

Ce jeu de données se compose des fichiers suivants :

  • movies_metadata.csv : ce fichier contient des informations sur ~45 000 films figurant dans le jeu de données Full MovieLens. Les caractéristiques comprennent les affiches, les fonds de scène, le budget, le genre, les recettes, les dates de sortie, les langues, les pays de production et les sociétés.

  • keywords.csv : Contient les mots-clés de l’intrigue du film pour nos films MovieLens. Disponible sous la forme d’un objet JSON stringifié.
  • credits.csv : Consiste en des informations sur le casting et l’équipe pour tous les films. Disponible sous la forme d’un objet JSON stringifié.
  • links.csv : Ce fichier contient les ID TMDB et IMDB de tous les films figurant dans l’ensemble de données Full MovieLens.
  • links_small.csv : Contient les ID TMDB et IMDB d’un petit sous-ensemble de 9 000 films du jeu de données complet.
  • ratings_small.csv : Le sous-ensemble de 100 000 évaluations de 700 utilisateurs sur 9 000 films.

Le jeu de données complet MovieLens comprend 26 millions d’évaluations et 750 000 applications de tags, provenant de 270 000 utilisateurs sur l’ensemble des 45 000 films de ce jeu de données. Il est accessible sur le site officiel de GroupLens.

Note : Le sous-ensemble de données utilisé dans le tutoriel d’aujourd’hui peut être téléchargé ici.

Pour charger votre ensemble de données, vous utiliseriez la bibliothèque pandas DataFrame. La bibliothèque pandas est principalement utilisée pour la manipulation et l’analyse des données. Elle représente vos données dans un format ligne-colonne. La bibliothèque Pandas est soutenue par le tableau NumPy pour l’implémentation des objets de données Pandas. Le tableau pandas offre des structures de données et des opérations prêtes à l’emploi pour la manipulation de tableaux numériques, de séries chronologiques, d’images et d’ensembles de données de traitement du langage naturel. Fondamentalement, pandas est utile pour les ensembles de données qui peuvent être facilement représentés de manière tabulaire.

Avant d’effectuer l’une des étapes ci-dessus, chargeons votre ensemble de données de métadonnées de films dans un pandas DataFrame :

# Import Pandasimport pandas as pd# Load Movies Metadatametadata = pd.read_csv('movies_metadata.csv', low_memory=False)# Print the first three rowsmetadata.head(3)

.

.

adulte appartenant_à_la_collection budget genres homepage id imdb_id original_language original_title overview date de sortie recette durée d’exécution langues parlées état ligne d’étiquette titre vidéo moyenne des votes compte des votes
0 False {‘id’ : 10194, ‘name’ : ‘Toy Story Collection’, … 30000000 Released NaN Toy Story False 7.7 5415.0
1 False NaN 65000000 Released Still Yelling. Toujours en train de se battre. Toujours prêt pour… Vieux hommes bossus Faux 6,5 92,0

3 lignes × 24 colonnes

L’une des métriques les plus basiques auxquelles vous pouvez penser est le classement pour décider quels sont les 250 meilleurs films en fonction de leurs évaluations respectives.

Cependant, l’utilisation d’une cote comme métrique comporte quelques mises en garde :

  • Pour commencer, elle ne prend pas en compte la popularité d’un film. Par conséquent, un film avec une note de 9 sur 10 votants sera considéré comme « meilleur » qu’un film avec une note de 8,9 sur 10 000 votants.

    Par exemple, imaginez que vous voulez commander de la nourriture chinoise, vous avez deux options, un restaurant a une note de 5 étoiles par seulement 5 personnes tandis que l’autre restaurant a une note de 4,5 par 1000 personnes. Quel restaurant préféreriez-vous ? Le second, non ?

    Bien sûr, il pourrait y avoir une exception que le premier restaurant a ouvert il y a seulement quelques jours ; par conséquent, moins de personnes ont voté pour lui alors que, au contraire, le second restaurant est opérationnel depuis un an.

  • Sur une note connexe, cette métrique aura également tendance à favoriser les films avec un plus petit nombre de votants avec des évaluations biaisées et/ou extrêmement élevées. Au fur et à mesure que le nombre de votants augmente, la note d’un film se régularise et se rapproche d’une valeur qui reflète la qualité du film et donne à l’utilisateur une bien meilleure idée du film qu’il doit choisir. Bien qu’il soit difficile de discerner la qualité d’un film avec extrêmement peu de votants, vous pourriez avoir à considérer des sources externes pour conclure.

En tenant compte de ces lacunes, vous devez arriver à un classement pondéré qui prend en compte la note moyenne et le nombre de votes qu’elle a accumulés. Un tel système fera en sorte qu’un film avec une note de 9 de la part de 100 000 votants obtienne une note (bien) plus élevée qu’un film avec la même note mais quelques centaines de votants seulement.

Puisque vous essayez de construire un clone du Top 250 d’IMDB, utilisons sa formule de notation pondérée comme métrique/score. Mathématiquement, elle est représentée comme suit :

\begin{equation}\text Weighted Rating (\bf WR) = \left({{\bf v} \over {\bf v} + {\bf m}} \cdot R\right) + \left({{\bf m} \over {\bf v} + {\bf m}} \cdot C\right)\end{equation}

Dans l’équation ci-dessus,

  • v est le nombre de votes pour le film ;

  • m est le nombre de votes minimum requis pour être listé dans le tableau;

  • R est la note moyenne du film;

  • C est le vote moyen sur l’ensemble du rapport.

Vous avez déjà les valeurs à v (vote_count) et R (vote_average) pour chaque film dans le jeu de données. Il est également possible de calculer directement C à partir de ces données.

Déterminer une valeur appropriée pour m est un hyperparamètre que vous pouvez choisir en conséquence puisqu’il n’y a pas de bonne valeur pour m. Vous pouvez le considérer comme un filtre négatif préliminaire qui supprimera simplement les films dont le nombre de votes est inférieur à un certain seuil m. La sélectivité de votre filtre est à votre discrétion.

Dans ce tutoriel, vous utiliserez le seuil m comme le 90e percentile. En d’autres termes, pour qu’un film figure dans le palmarès, il doit avoir plus de votes qu’au moins 90% des films de la liste. (En revanche, si vous aviez choisi le 75e percentile, vous auriez considéré les 25 % des films les mieux classés en termes de nombre de votes recueillis. Au fur et à mesure que le centile diminue, le nombre de films pris en compte augmente).

Dans un premier temps, calculons la valeur de C, la note moyenne sur l’ensemble des films en utilisant la fonction pandas .mean():

# Calculate mean of vote average columnC = metadata.mean()print(C)
5.618207215133889

D’après la sortie ci-dessus, vous pouvez observer que la note moyenne d’un film sur IMDB est d’environ 5.6 sur une échelle de 10.

Puis, calculons le nombre de votes, m, reçus par un film dans le 90e percentile. La bibliothèque pandas rend cette tâche extrêmement triviale en utilisant la méthode .quantile() de pandas:

# Calculate the minimum number of votes required to be in the chart, mm = metadata.quantile(0.90)print(m)
160.0

Puisque maintenant vous avez le m, vous pouvez simplement utiliser une condition supérieure à égale à pour filtrer les films ayant un nombre de votes supérieur à égale à 160:

Vous pouvez utiliser la méthode .copy() pour vous assurer que le nouveau q_movies DataFrame créé est indépendant de votre DataFrame de métadonnées d’origine. En d’autres termes, toute modification apportée au DataFrame q_movies n’affectera pas le DataFrame de métadonnées d’origine.

# Filter out all qualified movies into a new DataFrameq_movies = metadata.copy().loc >= m]q_movies.shape
(4555, 24)
metadata.shape
(45466, 24)

D’après la sortie ci-dessus, il est clair qu’il y a environ 10% de films dont le nombre de votes est supérieur à 160 et qui se qualifient pour figurer sur cette liste.

L’étape suivante et la plus importante consiste à calculer la note pondérée pour chaque film qualifié. Pour ce faire, vous devez :

  • Définir une fonction, weighted_rating();
  • Puisque vous avez déjà calculé m et C, vous allez simplement les passer comme argument à la fonction;
  • Puis vous allez sélectionner la colonne vote_count(v) et vote_average(R) dans le cadre de données q_movies;
  • Enfin, vous allez calculer la moyenne pondérée et retourner le résultat.

Vous définirez une nouvelle caractéristique score, dont vous calculerez la valeur en appliquant cette fonction à votre DataFrame de films qualifiés :

# Function that computes the weighted rating of each moviedef weighted_rating(x, m=m, C=C): v = x R = x # Calculation based on the IMDB formula return (v/(v+m) * R) + (m/(m+v) * C)
# Define a new feature 'score' and calculate its value with `weighted_rating()`q_movies = q_movies.apply(weighted_rating, axis=1)

Enfin, trions le DataFrame par ordre décroissant en fonction de la colonne de caractéristique score et produisons le titre, le nombre de votes, la moyenne des votes et la note pondérée (score) des 20 meilleurs films.

#Sort movies based on score calculated aboveq_movies = q_movies.sort_values('score', ascending=False)#Print the top 15 moviesq_movies].head(20)

.

titre compte de votes moyenne des votes score
314 The Shawshank Redemption 8358.0 8.5 8.445869
834 Le Parrain 6024.0 8.5 8.425439
10309 Dilwale Dulhania Le Jayenge 661.0 9.1 8.421453
12481 The Dark Knight 12269.0 8.3 8.265477
2843 Fight Club 9678.0 8.3 8.256385
292 Pulp Fiction 8670.0 8.3 8.251406
522 La liste de Schindler 4436.0 8.3 8.206639
23673 Whiplash 4376.0 8.3 8.205404
5481 Spirited Away 3968.0 8.3 8.196055
2211 La vie est belle 3643.0 8.3 8.187171
1178 Le Parrain : Partie II 3418.0 8.3 8.180076
1152 La Vol au-dessus d’un nid de coucou 3001.0 8.3 8.164256
351 Forrest Gump 8147.0 8.2 8.150272
1154 L’Empire contre-attaque 5998.0 8.2 8.132919
1176 Psycho 2405.0 8.3 8,132715
18465 Les Intouchables 5410.0 8.2 8.125837
40251 Votre nom. 1030.0 8.5 8.112532
289 Leon : The Professional 4293.0 8.2 8.107234
3030 The Green Mile 4166.0 8.2 8.104511
1170 GoodFellas 3211.0 8.2 8.077459

Bien, à partir de la sortie ci-dessus, vous pouvez voir que le simple recommender a fait un excellent travail !

Puisque le tableau a beaucoup de films en commun avec le tableau du Top 250 d’IMDB : par exemple, vos deux premiers films, « Shawshank Redemption » et « Le Parrain », sont les mêmes que ceux d’IMDB et nous savons tous que ce sont effectivement des films incroyables, en fait, tous les films du top 20 méritent d’être dans cette liste, n’est-ce pas ?

Recommandateur basé sur le contenu

Recommandateur basé sur la description du plot

Dans cette section du tutoriel, vous apprendrez à construire un système qui recommande des films qui sont similaires à un film particulier. Pour ce faire, vous allez calculer des scores de similarité par paire cosine pour tous les films en fonction de leurs descriptions d’intrigue et recommander des films en fonction de ce seuil de score de similarité.

La description de l’intrigue est à votre disposition en tant que caractéristique overview dans votre ensemble de données metadata. Inspectons les intrigues de quelques films :

#Print plot overviews of the first 5 movies.metadata.head()
0 Led by Woody, Andy's toys live happily in his ...1 When siblings Judy and Peter discover an encha...2 A family wedding reignites the ancient feud be...3 Cheated on, mistreated and stepped on, the wom...4 Just when George Banks has recovered from his ...Name: overview, dtype: object

Le problème à résoudre est un problème de traitement du langage naturel. Vous devez donc extraire des caractéristiques des données textuelles ci-dessus avant de pouvoir calculer la similarité et/ou la dissimilarité entre elles. Pour faire simple, il n’est pas possible de calculer la similarité entre deux aperçus dans leur forme brute. Pour ce faire, vous devez calculer les vecteurs de mots de chaque aperçu ou document, comme on l’appellera à partir de maintenant.

Comme son nom l’indique, les vecteurs de mots sont une représentation vectorisée des mots dans un document. Les vecteurs portent avec eux une signification sémantique. Par exemple, homme & roi aura des représentations vectorielles proches les unes des autres alors que homme & femme aura une représentation éloignée les unes des autres.

Vous calculerez des vecteurs Term Frequency-Inverse Document Frequency (TF-IDF) pour chaque document. Cela vous donnera une matrice où chaque colonne représente un mot dans le vocabulaire de synthèse (tous les mots qui apparaissent dans au moins un document), et chaque colonne représente un film, comme précédemment.

Dans son essence, le score TF-IDF est la fréquence d’un mot apparaissant dans un document, pondéré de manière réduite par le nombre de documents dans lesquels il apparaît. Ceci est fait pour réduire l’importance des mots qui apparaissent fréquemment dans les aperçus de parcelles et, par conséquent, leur importance dans le calcul du score de similarité final.

Heureusement, scikit-learn vous donne une classe intégrée TfIdfVectorizer qui produit la matrice TF-IDF en quelques lignes.

  • Importez le module Tfidf en utilisant scikit-learn;
  • Supprimez les mots d’arrêt comme ‘the’, ‘an’, etc. car ils ne donnent aucune information utile sur le sujet;
  • Remplacer les valeurs non numériques par une chaîne vide;
  • Enfin, construire la matrice TF-IDF sur les données.
#Import TfIdfVectorizer from scikit-learnfrom sklearn.feature_extraction.text import TfidfVectorizer#Define a TF-IDF Vectorizer Object. Remove all english stop words such as 'the', 'a'tfidf = TfidfVectorizer(stop_words='english')#Replace NaN with an empty stringmetadata = metadata.fillna('')#Construct the required TF-IDF matrix by fitting and transforming the datatfidf_matrix = tfidf.fit_transform(metadata)#Output the shape of tfidf_matrixtfidf_matrix.shape

(45466, 75827)
#Array mapping from feature integer indices to feature name.tfidf.get_feature_names()

D’après la sortie ci-dessus, vous observez que 75 827 vocabulaires ou mots différents dans votre ensemble de données ont 45 000 films.

Avec cette matrice en main, vous pouvez maintenant calculer un score de similarité. Il existe plusieurs métriques de similarité que vous pouvez utiliser pour cela, comme les scores de similarité de manhattan, euclidienne, de Pearson et de cosinus. Encore une fois, il n’y a pas de bonne réponse à la question de savoir quel score est le meilleur. Différents scores fonctionnent bien dans différents scénarios, et c’est souvent une bonne idée d’expérimenter avec différentes métriques et d’observer les résultats.

Vous allez utiliser le cosine similarity pour calculer une quantité numérique qui dénote la similarité entre deux films. Vous utilisez le score de similarité en cosinus car il est indépendant de la magnitude et est relativement facile et rapide à calculer (surtout lorsqu’il est utilisé conjointement avec les scores TF-IDF, qui seront expliqués plus tard). Mathématiquement, il est défini comme suit :

Puisque vous avez utilisé le vectoriseur TF-IDF, le calcul du produit scalaire entre chaque vecteur vous donnera directement le score de similarité cosinus. Par conséquent, vous utiliserez sklearn's linear_kernel() au lieu de cosine_similarities() car c’est plus rapide.

Cela renverrait une matrice de forme 45466×45466, ce qui signifie que chaque film overview score de similarité en cosinus avec chaque autre film overview. Par conséquent, chaque film sera un vecteur colonne 1×45466 où chaque colonne sera un score de similarité avec chaque film.

# Import linear_kernelfrom sklearn.metrics.pairwise import linear_kernel# Compute the cosine similarity matrixcosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
cosine_sim.shape
(45466, 45466)
cosine_sim
array()

Vous allez définir une fonction qui prend en entrée un titre de film et sort une liste des 10 films les plus similaires. Tout d’abord, pour cela, vous avez besoin d’un mapping inverse des titres de films et des indices de DataFrame. En d’autres termes, vous avez besoin d’un mécanisme pour identifier l’index d’un film dans votre DataFrame metadata, étant donné son titre.

#Construct a reverse map of indices and movie titlesindices = pd.Series(metadata.index, index=metadata).drop_duplicates()
indices
titleToy Story 0Jumanji 1Grumpier Old Men 2Waiting to Exhale 3Father of the Bride Part II 4Heat 5Sabrina 6Tom and Huck 7Sudden Death 8GoldenEye 9dtype: int64

Vous êtes maintenant en bonne position pour définir votre fonction de recommandation. Voici les étapes suivantes que vous allez suivre :

  • Recevoir l’indice du film étant donné son titre.

  • Recevoir la liste des scores de similarité en cosinus pour ce film particulier avec tous les films. Convertissez-la en une liste de tuples où le premier élément est sa position, et le second est le score de similarité.

  • Triez la liste de tuples susmentionnée en fonction des scores de similarité ; c’est-à-dire le second élément.

  • Recevez les 10 premiers éléments de cette liste. Ignorez le premier élément car il se réfère à soi (le film le plus similaire à un film particulier est le film lui-même).

  • Retournez les titres correspondant aux indices des premiers éléments.

# Function that takes in movie title as input and outputs most similar moviesdef get_recommendations(title, cosine_sim=cosine_sim): # Get the index of the movie that matches the title idx = indices # Get the pairwsie similarity scores of all movies with that movie sim_scores = list(enumerate(cosine_sim)) # Sort the movies based on the similarity scores sim_scores = sorted(sim_scores, key=lambda x: x, reverse=True) # Get the scores of the 10 most similar movies sim_scores = sim_scores # Get the movie indices movie_indices = for i in sim_scores] # Return the top 10 most similar movies return metadata.iloc
get_recommendations('The Dark Knight Rises')
12481 The Dark Knight150 Batman Forever1328 Batman Returns15511 Batman: Under the Red Hood585 Batman21194 Batman Unmasked: The Psychology of the Dark Kn...9230 Batman Beyond: Return of the Joker18035 Batman: Year One19792 Batman: The Dark Knight Returns, Part 13095 Batman: Mask of the PhantasmName: title, dtype: object
get_recommendations('The Godfather')
1178 The Godfather: Part II44030 The Godfather Trilogy: 1972-19901914 The Godfather: Part III23126 Blood Ties11297 Household Saints34717 Start Liquidation10821 Election38030 A Mother Should Be Loved17729 Short Sharp Shock26293 Beck 28 - FamiljenName: title, dtype: object

Vous voyez que, bien que votre système ait fait un travail décent pour trouver des films avec des descriptions d’intrigues similaires, la qualité des recommandations n’est pas si grande. « The Dark Knight Rises » renvoie tous les films Batman alors qu’il est plus probable que les personnes qui ont aimé ce film soient plus enclines à apprécier d’autres films de Christopher Nolan. C’est quelque chose qui ne peut pas être capturé par votre système actuel.

Credits, Genres, and Keywords Based Recommender

La qualité de votre recommender serait augmentée avec l’utilisation de meilleures métadonnées et en capturant plus de détails plus fins. C’est précisément ce que vous allez faire dans cette section. Vous allez construire un système de recommandation basé sur les métadonnées suivantes : les 3 principaux acteurs, le réalisateur, les genres connexes et les mots-clés de l’intrigue du film.

Les mots-clés, les données sur les acteurs et l’équipe ne sont pas disponibles dans votre ensemble de données actuel, la première étape serait donc de les charger et de les fusionner dans votre DataFrame principal metadata.

# Load keywords and creditscredits = pd.read_csv('credits.csv')keywords = pd.read_csv('keywords.csv')# Remove rows with bad IDs.metadata = metadata.drop()# Convert IDs to int. Required for mergingkeywords = keywords.astype('int')credits = credits.astype('int')metadata = metadata.astype('int')# Merge keywords and credits into your main metadata dataframemetadata = metadata.merge(credits, on='id')metadata = metadata.merge(keywords, on='id')
# Print the first two movies of your newly merged metadatametadata.head(2)

.

.

jealousy toy boy tomhanks timallen donrickles …

disparition de jeux de société basée sur un livre d’enfants …

Les étapes suivantes sont les mêmes que ce que vous avez fait avec votre plot description based recommender. Une différence essentielle est que vous utilisez le CountVectorizer() au lieu du TF-IDF. C’est parce que vous ne voulez pas minimiser la présence de l’acteur/réalisateur s’il a joué ou dirigé dans relativement plus de films. Cela n’a pas beaucoup de sens intuitif de les sous-pondérer dans ce contexte.

La différence majeure entre CountVectorizer() et TF-IDF est la composante de fréquence de document inverse (IDF) qui est présente dans la dernière et pas dans la première.

# Import CountVectorizer and create the count matrixfrom sklearn.feature_extraction.text import CountVectorizercount = CountVectorizer(stop_words='english')count_matrix = count.fit_transform(metadata)
count_matrix.shape
(46628, 73881)

D’après la sortie ci-dessus, vous pouvez voir qu’il y a 73 881 vocabulaires dans les métadonnées que vous lui avez fournies.

Puis, vous utiliserez le cosine_similarity pour mesurer la distance entre les enchâssements.

# Compute the Cosine Similarity matrix based on the count_matrixfrom sklearn.metrics.pairwise import cosine_similaritycosine_sim2 = cosine_similarity(count_matrix, count_matrix)
# Reset index of your main DataFrame and construct reverse mapping as beforemetadata = metadata.reset_index()indices = pd.Series(metadata.index, index=metadata)

Vous pouvez maintenant réutiliser votre fonction get_recommendations() en passant la nouvelle matrice cosine_sim2 comme second argument.

get_recommendations('The Dark Knight Rises', cosine_sim2)
12589 The Dark Knight10210 Batman Begins9311 Shiner9874 Amongst Friends7772 Mitchell516 Romeo Is Bleeding11463 The Prestige24090 Quicksand25038 Deadfall41063 SaraName: title, dtype: object
get_recommendations('The Godfather', cosine_sim2)
1934 The Godfather: Part III1199 The Godfather: Part II15609 The Rain People18940 Last Exit34488 Rege35802 Manuscripts Don't Burn35803 Manuscripts Don't Burn8001 The Night of the Following Day18261 The Son of No One28683 In the Name of the LawName: title, dtype: object

Génial ! Vous voyez que votre recommandeur a réussi à capturer plus d’informations grâce à plus de métadonnées et vous a donné de meilleures recommandations. Il y a, bien sûr, de nombreuses façons d’expérimenter ce système pour améliorer les recommandations.

Quelques suggestions:

  • Introduire un filtre de popularité : ce recommandeur prendrait les 30 films les plus similaires, calculerait les notes pondérées (en utilisant la formule IMDB de plus haut), trierait les films en fonction de cette note, et retournerait les 10 meilleurs films.

  • Autres membres de l’équipe : d’autres noms de membres de l’équipe, comme les scénaristes et les producteurs, pourraient également être inclus.

  • Le poids croissant du réalisateur : pour donner plus de poids au réalisateur, il pourrait être mentionné plusieurs fois dans la soupe pour augmenter les scores de similarité des films avec le même réalisateur.

Filtrage collaboratif avec Python

Dans ce tutoriel, vous avez appris à construire vos propres systèmes de recommandation de films simples et basés sur le contenu. Il existe également un autre type de recommandeur extrêmement populaire connu sous le nom de filtres collaboratifs.

Les filtres collaboratifs peuvent en outre être classés en deux types :

  • User-based Filtering : ces systèmes recommandent des produits à un utilisateur que des utilisateurs similaires ont aimé. Par exemple, disons qu’Alice et Bob ont un intérêt similaire pour les livres (c’est-à-dire qu’ils aiment et n’aiment pas largement les mêmes livres). Supposons maintenant qu’un nouveau livre a été lancé sur le marché et qu’Alice l’a lu et aimé. Il est donc très probable que Bob l’aime aussi, et par conséquent, le système recommande ce livre à Bob.
  • Item-based Filtering : ces systèmes sont extrêmement similaires au moteur de recommandation de contenu que vous avez construit. Ces systèmes identifient des éléments similaires en fonction de la façon dont les gens l’ont évalué dans le passé. Par exemple, si Alice, Bob et Eve ont donné 5 étoiles au Seigneur des Anneaux et au Hobbit, le système identifie les articles comme similaires. Par conséquent, si quelqu’un achète Le Seigneur des Anneaux, le système lui recommande également Le Hobbit.

Un exemple de filtrage collaboratif basé sur un système de notation:

Vous ne construirez pas ces systèmes dans ce tutoriel, mais vous êtes déjà familier avec la plupart des idées requises pour le faire. Un bon endroit pour commencer avec les filtres collaboratifs est d’examiner le jeu de données MovieLens, qui peut être trouvé ici.

Conclusion

Félicitations pour avoir terminé ce tutoriel !

Vous avez parcouru avec succès notre tutoriel qui vous a tout appris sur les systèmes de recommandation en Python. Vous avez appris à construire des recommandeurs simples et basés sur le contenu.

Un bon exercice pour vous tous serait d’implémenter le filtrage collaboratif en Python en utilisant le sous-ensemble du jeu de données MovieLens que vous avez utilisé pour construire des recommandeurs simples et basés sur le contenu.

Si vous débutez en Python et que vous souhaitez en savoir plus, suivez le cours Introduction à la science des données en Python de DataCamp.

adulte appartenant_à_la_collection budget genres homepage id imdb_id original_language original_title overview langues parlées état ligne d’étiquette titre vidéo moyenne des votes vote_count cast crew keywords
0 False {‘id’ : 10194, ‘name’ : ‘Toy Story Collection’, … 30000000 Released NaN Toy Story False 7.7 5415.0 for feature in features : metadata = metadata.apply(literal_eval)

Puis, vous écrivez des fonctions qui vous aideront à extraire les informations requises de chaque feature.

D’abord, vous allez importer le package NumPy pour avoir accès à sa constante NaN. Ensuite, vous pourrez l’utiliser pour écrire la fonction get_director():

# Import Numpyimport numpy as np

Recevoir le nom du réalisateur à partir de la caractéristique de l’équipage. Si le réalisateur n’est pas listé, retourner NaN

def get_director(x): for i in x: if i == 'Director': return i return np.nan

Puis, vous écrirez une fonction qui retournera les 3 premiers éléments ou la liste entière, selon ce qui est le plus élevé. Ici, la liste fait référence aux cast, keywords, et genres.

def get_list(x): if isinstance(x, list): names = for i in x] #Check if more than 3 elements exist. If yes, return only first three. If no, return entire list. if len(names) > 3: names = names return names #Return empty list in case of missing/malformed data return 
# Define new director, cast, genres and keywords features that are in a suitable form.metadata = metadata.apply(get_director)features = for feature in features: metadata = metadata.apply(get_list)
# Print the new features of the first 3 filmsmetadata].head(3)

.

.

titre cast directeur mots-clés genres
0 Toy Story John Lasseter
1 Jumanji Joe Johnston
2 Grumpier Old Men Howard Deutch

L’étape suivante consisterait à convertir les noms et les instances de mots-clés en minuscules et à supprimer tous les espaces entre eux.

La suppression des espaces entre les mots est une étape importante du prétraitement. Elle est effectuée pour que votre vectoriseur ne compte pas les Johnny de « Johnny Depp » et « Johnny Galecki » comme étant les mêmes. Après cette étape de traitement, les acteurs susmentionnés seront représentés par « johnnydepp » et « johnnygalecki » et seront distincts pour votre vectoriseur.

Un autre bon exemple où le modèle pourrait sortir la même représentation vectorielle est « embouteillage de pain » et « embouteillage de circulation ». Par conséquent, il est préférable de supprimer tout espace présent.

La fonction ci-dessous le fera exactement pour vous:

# Function to convert all strings to lower case and strip names of spacesdef clean_data(x): if isinstance(x, list): return else: #Check if director exists. If not, return empty string if isinstance(x, str): return str.lower(x.replace(" ", "")) else: return ''
# Apply clean_data function to your features.features = for feature in features: metadata = metadata.apply(clean_data)

Vous êtes maintenant en mesure de créer votre « soupe de métadonnées », qui est une chaîne qui contient toutes les métadonnées que vous voulez alimenter à votre vectoriseur (à savoir les acteurs, le réalisateur et les mots-clés).

La fonction create_soup joindra simplement toutes les colonnes requises par un espace. C’est la dernière étape de prétraitement, et la sortie de cette fonction sera introduite dans le modèle de vecteur de mots.

def create_soup(x): return ' '.join(x) + ' ' + ' '.join(x) + ' ' + x + ' ' + ' '.join(x)
# Create a new soup featuremetadata = metadata.apply(create_soup, axis=1)
metadata].head(2)

soup 0 1