Construire un moteur de recommandation avec filtrage collaboratif – Real Python

By | juillet 10, 2019

python pour débutant

Le filtrage collaboratif est la technique la plus couramment utilisée pour créer des systèmes de recommandation intelligents pouvant apprendre à fournir de meilleures recommandations à mesure que davantage d'informations sur les utilisateurs sont collectées.

La plupart des sites Web comme Amazon, YouTube et Netflix utilisent le filtrage collaboratif dans le cadre de leurs systèmes de recommandation sophistiqués. Vous pouvez utiliser cette technique pour créer des recommandations qui donnent des suggestions à un utilisateur sur la base des goûts et dégoûts d’utilisateurs similaires.

Dans cet article, vous apprendrez:

  • Filtrage collaboratif et types
  • Données nécessaires pour créer un programme de recommandation
  • Bibliothèques disponibles en Python pour générer des recommandateurs
  • Cas d'utilisation et défis du filtrage collaboratif

Qu'est-ce que le filtrage collaboratif?

Le filtrage collaboratif est une technique permettant de filtrer les éléments qu'un utilisateur pourrait aimer en fonction des réactions d'utilisateurs similaires.

Cela fonctionne en recherchant un grand groupe de personnes et en trouvant un plus petit groupe d'utilisateurs ayant des goûts similaires à ceux d'un utilisateur particulier. Il examine les éléments qu’ils apprécient et les combine pour créer une liste classée de suggestions.

Il existe de nombreuses façons de choisir les utilisateurs similaires et de combiner leurs choix pour créer une liste de recommandations. Cet article va vous montrer comment faire cela avec Python.

Le jeu de données

Pour expérimenter des algorithmes de recommandation, vous aurez besoin de données contenant un ensemble d'éléments et un ensemble d'utilisateurs qui ont réagi à certains des articles.

La réaction peut être explicite (note sur une échelle de 1 à 5, aime ou n'aime pas) ou implicite (voir un article, l'ajouter à une liste de souhaits, le temps passé sur un article).

Lorsque vous travaillez avec de telles données, vous les verrez principalement sous forme de matrice consistant en les réactions données par un ensemble d'utilisateurs à certains éléments d'un ensemble d'éléments. Chaque ligne contiendrait les évaluations attribuées par un utilisateur, et chaque colonne contiendrait les évaluations reçues par un élément. Une matrice avec cinq utilisateurs et cinq éléments pourrait ressembler à ceci:

Matrice d'évaluation des éléments d'utilisateur utilisée dans les systèmes de recommandation
Matrice d'évaluation

La matrice présente cinq utilisateurs qui ont classé certains éléments sur une échelle de 1 à 5. Par exemple, le premier utilisateur a attribué la note 4 au troisième élément.

Dans la plupart des cas, les cellules de la matrice sont vides, les utilisateurs ne notant que quelques éléments. Il est très peu probable que chaque utilisateur évalue ou réagisse à chaque élément disponible. On appelle une matrice avec des cellules pour la plupart vides clairsemé, et l’inverse (une matrice principalement remplie) s’appelle dense.

De nombreux ensembles de données ont été collectés et mis à la disposition du public à des fins de recherche et d'analyse comparative. Voici une liste de sources de données de haute qualité parmi lesquelles vous pouvez choisir.

Le meilleur moyen de commencer est l’ensemble de données MovieLens collecté par GroupLens Research. L'ensemble de données MovieLens 100k est notamment un ensemble de données de référence stable avec 100 000 notes attribuées par 943 utilisateurs pour 1682 films, chaque utilisateur ayant classé au moins 20 films.

Cet ensemble de données comprend de nombreux fichiers contenant des informations sur les films, les utilisateurs et les notes attribuées par les utilisateurs aux films qu'ils ont visionnés. Ceux qui sont d'intérêt sont les suivants:

  • u.item: la liste des films
  • u.data: la liste des notes attribuées par les utilisateurs

Le fichier u.data qui contient les évaluations est une liste d'ID utilisateur, ID d'élément, évaluation et horodatage, séparés par des tabulations. Les premières lignes du fichier ressemblent à ceci:

Les cinq premières lignes du jeu de données movielens 100k
5 premières lignes de données MovieLens 100k

Comme indiqué ci-dessus, le fichier indique le classement qu'un utilisateur a attribué à un film particulier. Ce fichier contient 100 000 classements de ce type, qui seront utilisés pour prédire les classements des films non vus par les utilisateurs.

Étapes impliquées dans le filtrage collaboratif

Pour créer un système capable de recommander automatiquement des éléments aux utilisateurs en fonction des préférences d’autres utilisateurs, la première étape consiste à rechercher des utilisateurs ou des éléments similaires. La deuxième étape consiste à prévoir les évaluations des éléments qui n'ont pas encore été évalués par un utilisateur. Donc, vous aurez besoin des réponses à ces questions:

  • Comment déterminez-vous quels utilisateurs ou éléments sont similaires?
  • Étant donné que vous savez quels utilisateurs sont similaires, comment déterminez-vous l'évaluation qu'un utilisateur attribuerait à un élément en fonction des évaluations d'utilisateurs similaires?
  • Comment mesurez-vous l'exactitude des cotes que vous calculez?

Les deux premières questions n’ont pas de réponse unique. Le filtrage collaboratif est une famille d'algorithmes où il existe plusieurs façons de trouver des utilisateurs ou des éléments similaires et plusieurs méthodes pour calculer une note basée sur les notes d'utilisateurs similaires. En fonction des choix que vous faites, vous vous retrouvez avec une approche de filtrage collaboratif. Vous découvrirez les différentes approches permettant de rechercher des similarités et de prédire les notations dans cet article.

Il est important de garder à l'esprit que dans une approche purement basée sur un filtrage collaboratif, la similarité n'est pas calculée à l'aide de facteurs tels que l'âge des utilisateurs, le genre du film ou toute autre donnée relative à des utilisateurs ou à des éléments. Il est calculé uniquement sur la base de l'évaluation (explicite ou implicite) qu'un utilisateur attribue à un élément. Par exemple, deux utilisateurs peuvent être considérés comme similaires s'ils attribuent les mêmes cotes d'écoute à dix films, malgré une grande différence d'âge.

La troisième question, relative à la mesure de la précision de vos prévisions, comporte également de nombreuses réponses, notamment des techniques de calcul d'erreur pouvant être utilisées à de nombreux endroits, et pas seulement des recommandations basées sur le filtrage collaboratif.

L'une des approches permettant de mesurer la précision de vos résultats est l'erreur fondamentale quadratique (RMSE), dans laquelle vous prédisez les notations d'un jeu de données test de paires utilisateur-article dont les valeurs de notations sont déjà connues. La différence entre la valeur connue et la valeur prédite serait l’erreur. Mettez en carré toutes les valeurs d'erreur pour l'ensemble de tests, trouvez la moyenne (ou la moyenne), puis prenez la racine carrée de cette moyenne pour obtenir le RMSE.

Une autre mesure permettant de mesurer la précision est l'erreur absolue moyenne (MAE), dans laquelle vous recherchez l'ampleur de l'erreur en recherchant sa valeur absolue, puis en prenant la moyenne de toutes les valeurs d'erreur.

Vous n'avez pas à vous soucier des détails de RMSE ou de MAE à ce stade, car ils sont facilement disponibles dans le cadre de divers packages en Python et vous les verrez plus tard dans l'article.

Voyons maintenant les différents types d’algorithmes de la famille du filtrage collaboratif.

Basé sur la mémoire

La première catégorie comprend des algorithmes basés sur la mémoire, dans lesquels des techniques statistiques sont appliquées à l'ensemble du jeu de données pour calculer les prévisions.

Pour trouver le classement R qu'un utilisateur U donnerait à un article je, l'approche comprend:

  • Trouver des utilisateurs similaires à U qui ont évalué l'article je
  • Calcul de la note R sur la base des évaluations des utilisateurs trouvés à l'étape précédente

Vous verrez chacune d’elles en détail dans les sections suivantes.

Comment trouver des utilisateurs similaires sur la base des évaluations

Pour comprendre le concept de similarité, commençons par créer un jeu de données simple.

Les données incluent quatre utilisateurs UNE, B, C, et , qui ont évalué deux films. Les notes sont stockées dans des listes et chaque liste contient deux chiffres indiquant la note de chaque film:

  • Notes par UNE sont [1.0, 2.0].
  • Notes par B sont [2.0, 4.0].
  • Notes par C sont [2.5, 4.0].
  • Notes par sont [4.5, 5.0].

Pour commencer avec un indice visuel, tracez les cotes de deux films donnés par les utilisateurs sur un graphique et cherchez un motif. Le graphique ressemble à ceci:

Points représentés sur un graphique pour visualiser la distance euclidienne

Dans le graphique ci-dessus, chaque point représente un utilisateur et est comparé aux cotes attribuées à deux films.

Regarder la distance entre les points semble être un bon moyen d'estimer la similarité, non? Vous pouvez trouver la distance en utilisant la formule de distance euclidienne entre deux points. Vous pouvez utiliser la fonction disponible dans scipy comme indiqué dans le programme suivant:

>>>

>>> de scipy importation spatial

>>> une = [[[[1, 2]
>>> b = [[[[2, 4]
>>> c = [[[[2,5, 4]
>>>  = [[[[4,5, 5]

>>> spatial.distance.euclidien(c, une)
2,5
>>> spatial.distance.euclidien(c, b)
0.5
>>> spatial.distance.euclidien(c, )
2.23606797749979

Comme indiqué ci-dessus, vous pouvez utiliser scipy.spatial.distance.euclidean calculer la distance entre deux points. L’utiliser pour calculer la distance entre les évaluations de UNE, B, et pour lequel C nous montre qu'en termes de distance, les évaluations de C sont les plus proches de ceux de B.

Vous pouvez voir cet utilisateur C est le plus proche de B même en regardant le graphique. Mais hors de UNE et seulement qui est C plus proche de?

Tu pourrais dire C est plus proche de en termes de distance. Mais en regardant les classements, il semblerait que les choix de C serait aligner avec celui de UNE plus que parce que les deux UNE et C comme le deuxième film presque deux fois plus que le premier film, mais aime les deux films également.

Alors, que pouvez-vous utiliser pour identifier de tels modèles que la distance euclidienne ne peut pas? L'angle entre les lignes joignant les points à l'origine peut-il être utilisé pour prendre une décision? Vous pouvez regarder l'angle entre les lignes joignant l'origine du graphique aux points respectifs, comme indiqué:

Vecteurs à deux dimensions tracés sur un graphique pour expliquer l'angle en tant que métrique de distance

Le graphique montre quatre lignes joignant chaque point à l'origine. Les lignes pour UNE et B sont coïncidents, rendant l'angle entre eux zéro.

Vous pouvez considérer que, si l'angle entre les lignes est augmenté, la similarité diminue et si l'angle est égal à zéro, les utilisateurs sont très similaires.

Pour calculer la similarité en utilisant l’angle, vous avez besoin d’une fonction qui renvoie un plus grande similitude ou petite distance pour un angle inférieur et un plus faible similitude ou plus grande distance pour un angle plus élevé. Le cosinus d'un angle est une fonction qui diminue de 1 à -1 lorsque l'angle augmente de 0 à 180.

Vous pouvez utiliser le cosinus de l'angle pour trouver la similarité entre deux utilisateurs. Plus l'angle est élevé, plus le cosinus est bas et, par conséquent, plus la similarité des utilisateurs est basse. Vous pouvez également inverser la valeur du cosinus de l'angle pour obtenir la distance de cosinus entre les utilisateurs en la soustrayant de 1.

scipy a une fonction qui calcule la distance cosinus de vecteurs. Il retourne une valeur plus élevée pour un angle plus élevé:

>>>

>>> de scipy importation spatial
>>> une = [[[[1, 2]
>>> b = [[[[2, 4]
>>> c = [[[[2,5, 4]
>>>  = [[[[4,5, 5]

>>> spatial.distance.cosinus(c,une)
0.004504527406047898

>>> spatial.distance.cosinus(c,b)
0.004504527406047898

>>> spatial.distance.cosinus(c,)
0.015137225946083022

>>> spatial.distance.cosinus(une,b)
0.0

L'angle inférieur entre les vecteurs de C et UNE donne une valeur de distance cosinus inférieure. Si vous souhaitez classer les similitudes d'utilisateurs de cette manière, utilisez la distance cosinus.

Notez que les utilisateurs UNE et B sont considérés comme absolument similaires dans la métrique de similarité de cosinus malgré des cotes différentes. C’est en fait un phénomène courant dans le monde réel, et les utilisateurs aiment cet utilisateur. UNE sont ce que vous pouvez appeler noteurs difficiles. Un exemple serait un critique de cinéma qui donne toujours des cotes inférieures à la moyenne, mais le classement des éléments de sa liste serait similaire à celui du film. Noteurs moyens comme B.

Pour prendre en compte de telles préférences utilisateur, vous devez amener tous les utilisateurs au même niveau en supprimant leurs biais. Vous pouvez le faire en soustrayant l’évaluation moyenne donnée par cet utilisateur à tous les éléments de chaque élément évalué par cet utilisateur. Voici à quoi cela ressemblerait:

  • Pour utilisateur UNE, le vecteur de notation [1, 2] a la moyenne 1,5. Soustraction 1,5 de chaque cote vous donnerait le vecteur [-0.5, 0.5].
  • Pour utilisateur B, le vecteur de notation [2, 4] a la moyenne 3. Soustraction 3 de chaque cote vous donnerait le vecteur [-1, 1].

Ce faisant, vous modifiez la valeur de la note moyenne attribuée par chaque utilisateur à 0. Faites de même pour les utilisateurs. C et et vous verrez que les cotes sont maintenant ajustées pour donner une moyenne de 0 à tous les utilisateurs, ce qui les amène tous au même niveau et supprime leurs biais.

Le cosinus de l'angle entre les vecteurs ajustés est appelé cosinus centré. Cette approche est généralement utilisée lorsque les vecteurs contiennent un grand nombre de valeurs manquantes et que vous devez définir une valeur commune pour remplir les valeurs manquantes.

Remplir les valeurs manquantes dans la matrice de cotes avec une valeur aléatoire peut entraîner des inexactitudes. Un bon choix pour renseigner les valeurs manquantes pourrait être la note moyenne de chaque utilisateur, mais les moyennes originales de l'utilisateur UNE et B sont 1,5 et 3 respectivement, et en remplissant toutes les valeurs vides de UNE avec 1,5 et ceux de B avec 3 en feraient des utilisateurs différents.

Mais après ajustement des valeurs, le centré la moyenne des deux utilisateurs est 0, ce qui vous permet de saisir l’idée que l’élément est au-dessus ou au-dessous de la moyenne avec plus de précision pour les deux utilisateurs, toutes les valeurs manquantes dans les vecteurs des deux utilisateurs ayant la même valeur 0.

La distance euclidienne et la similarité cosinus sont quelques-unes des approches que vous pouvez utiliser pour trouver des utilisateurs similaires les uns aux autres, voire des éléments similaires les uns aux autres. (La fonction utilisée ci-dessus calcule la distance en cosinus. Pour calculer la similarité en cosinus, soustrayez la distance de 1.)

Comment calculer les cotes

Après avoir déterminé une liste d'utilisateurs similaire à un utilisateur U, vous devez calculer la note R cette U donnerait à un certain article je. Encore une fois, tout comme la similarité, vous pouvez le faire de plusieurs façons.

Vous pouvez prédire que la note d'un utilisateur R pour un article je sera proche de la moyenne des notes attribuées à je par le top 5 ou le top 10 des utilisateurs les plus similaires à U. La formule mathématique pour la note moyenne donnée par n les utilisateurs ressembleraient à ceci:

Formule pour note moyenne

Cette formule montre que la note moyenne attribuée par le n utilisateurs similaires est égal à la somme des notes attribuées par eux, divisée par le nombre d'utilisateurs similaires, ce qui est n.

Il y aura des situations où le n les utilisateurs similaires que vous avez trouvés ne sont pas également similaires à l'utilisateur cible U. Le top 3 d’entre eux pourrait être très similaire, et le reste pourrait ne pas être aussi semblable à U 3. Dans ce cas, vous pouvez envisager une approche dans laquelle la notation de l'utilisateur le plus similaire compte plus que celle du deuxième utilisateur le plus similaire, etc. La moyenne pondérée peut nous aider à atteindre cet objectif.

Dans l'approche de la moyenne pondérée, vous multipliez chaque note par un facteur de similarité (qui indique le degré de similarité des utilisateurs). En multipliant par le facteur de similarité, vous ajoutez des poids aux évaluations. Plus le poids est lourd, plus la note importera.

Le facteur de similarité, qui agirait comme une pondération, devrait être l'inverse de la distance évoquée ci-dessus car moins de distance implique une similarité plus grande. Par exemple, vous pouvez soustraire la distance cosinus de 1 pour obtenir la similarité cosinus.

Avec le facteur de similarité S pour chaque utilisateur similaire à l'utilisateur cible U, vous pouvez calculer la moyenne pondérée en utilisant cette formule:

Formule pour la note moyenne pondérée

Dans la formule ci-dessus, chaque note est multipliée par le facteur de similarité de l'utilisateur qui a donné la note. Le résultat prévisionnel final par utilisateur U sera égal à la somme des notes pondérées divisée par la somme des poids.

Avec une moyenne pondérée, vous accordez plus d'importance aux évaluations d'utilisateurs similaires par ordre de similarité.

Maintenant, vous savez comment trouver des utilisateurs similaires et comment calculer des évaluations en fonction de leurs évaluations. Il existe également une variante du filtrage collaboratif dans laquelle vous prédisez les notations en recherchant des éléments similaires les uns aux autres au lieu d’utilisateurs et en calculant les notations. Vous en apprendrez plus sur cette variante dans la section suivante.

Filtrage collaboratif basé sur l'utilisateur ou basé sur l'élément

La technique décrite dans les exemples ci-dessus, dans laquelle la matrice de classement est utilisée pour rechercher des utilisateurs similaires en fonction des classements qu’ils attribuent, est appelée filtrage collaboratif utilisateur / utilisateur. Si vous utilisez la matrice de classement pour rechercher des éléments similaires en fonction des notations attribuées par les utilisateurs, l'approche est appelée filtrage collaboratif basé sur élément ou élément par élément.

Les deux approches sont mathématiquement assez similaires, mais il existe une différence conceptuelle entre les deux. Voici comment les deux comparent:

  • Basé sur l'utilisateur: Pour un utilisateur U, avec un ensemble d’utilisateurs similaires déterminés sur la base de vecteurs d’évaluation consistant en des évaluations d’éléments donnés, l’évaluation pour un élément je, qui n’a pas été évalué, est trouvé en sélectionnant N utilisateurs de la liste de similarité qui ont évalué l’article je et calculer la note en fonction de ces N notes.

  • Basé sur les articles: Pour un article je, avec un ensemble d’articles similaires déterminés sur la base de vecteurs d’évaluation constitués des évaluations d’utilisateur reçues, l’évaluation par un utilisateur. U, qui ne l’a pas noté, est trouvé en choisissant N éléments de la liste de similarité qui ont été évalués par U et calculer la note en fonction de ces N notes.

Le filtrage collaboratif basé sur les éléments a été développé par Amazon. Dans un système où le nombre d'utilisateurs est supérieur au nombre d'éléments, le filtrage basé sur les éléments est plus rapide et plus stable que celui basé sur l'utilisateur. C’est efficace car, en général, la note moyenne reçue par un élément ne change pas aussi rapidement que la note moyenne donnée par un utilisateur à différents articles. Il est également connu que ses performances sont meilleures que l’approche basée sur l’utilisateur lorsque la matrice de notation est peu développée.

Bien que l'approche basée sur les éléments fonctionne mal pour les ensembles de données contenant des éléments liés à la navigation ou au divertissement tels que MovieLens, pour lesquels les recommandations émises semblent très évidentes pour les utilisateurs cibles. De tels jeux de données obtiennent de meilleurs résultats avec les techniques de factorisation matricielle, décrites dans la section suivante, ou avec des recommandeurs hybrides prenant également en compte le contenu des données comme le genre en utilisant un filtrage basé sur le contenu.

Vous pouvez utiliser la bibliothèque Surprise pour expérimenter rapidement différents algorithmes de recommandation. (Vous en saurez plus à ce sujet plus tard dans l'article.)

Basé sur le modèle

La deuxième catégorie couvre les approches basées sur un modèle, qui impliquent une étape de réduction ou de compression de la matrice volumineuse mais peu volumineuse. Pour comprendre cette étape, une compréhension de base de la réduction de dimensionnalité peut être très utile.

Réduction de la dimensionnalité

Dans la matrice d'éléments d'utilisateur, il y a deux dimensions:

  1. Le nombre d'utilisateurs
  2. Le nombre d'articles

Si la matrice est généralement vide, la réduction des dimensions peut améliorer les performances de l'algorithme en termes d'espace et de temps. Pour ce faire, vous pouvez utiliser différentes méthodes telles que la factorisation matricielle ou les auto-encodeurs.

Factorisation matricielle peut être vu comme décomposer une grande matrice en un produit de plus petites. Ceci est similaire à la factorisation d’entiers, où 12 peut être écrit comme 6 x 2 ou 4 x 3. Dans le cas des matrices, une matrice UNE avec les dimensions m x n peut être réduit à un produit de deux matrices X et Y avec les dimensions m x p et p x n respectivement.

Les matrices réduites représentent en fait les utilisateurs et les éléments individuellement. le m les lignes de la première matrice représentent la m les utilisateurs, et le p les colonnes vous renseignent sur les caractéristiques ou les caractéristiques des utilisateurs. Il en va de même pour la matrice d'objets avec n articles et p les caractéristiques. Voici un exemple de la factorisation matricielle:

Une matrice factorisée en deux matrices utilisant la réduction de dimensionnalité
Factorisation Matricielle

Dans l'image ci-dessus, la matrice est réduite à deux matrices. Celui de gauche est la matrice utilisateur avec m les utilisateurs, et celui du dessus est la matrice d'éléments avec n articles. La cote 4 est réduite ou factorisée en:

  1. Un vecteur utilisateur (2, -1)
  2. Un vecteur d'article (2.5, 1)

Les deux colonnes de la matrice utilisateur et les deux lignes de la matrice d'éléments sont appelées facteurs latents et indiquent les caractéristiques cachées des utilisateurs ou des éléments. Une interprétation possible de la factorisation pourrait ressembler à ceci:

  • Supposons que dans un vecteur utilisateur (u, v), vous représente combien un utilisateur aime le genre Horror, et v représente à quel point ils aiment le genre roman.

  • Le vecteur utilisateur (2, -1) représente donc un utilisateur qui aime les films d’horreur et les classe positivement, et qui n'aime pas les films romantiques et qui les classe négativement.

  • Supposons que dans un vecteur d'élément (i, j), je représente combien un film appartient au genre Horror, et j représente combien ce film appartient au genre Romance.

  • Le film (2.5, 1) a une cote d'horreur de 2,5 et une note romantique de 1. Le multiplier par le vecteur utilisateur en utilisant les règles de multiplication de matrice vous donne (2 * 2,5) + (-1 * 1) = 4.

  • Donc, le film appartenait au genre Horror, et l'utilisateur aurait pu le noter 5, mais la légère inclusion de Romance a fait chuter la note finale à 4.

Les matrices de facteurs peuvent fournir de telles informations sur les utilisateurs et les éléments, mais en réalité, elles sont généralement beaucoup plus complexes que l'explication donnée ci-dessus. Le nombre de ces facteurs peut aller de un à des centaines voire des milliers. Ce nombre est l’une des choses à optimiser lors de la formation du modèle.

Dans l'exemple, vous aviez deux facteurs latents pour les genres de films, mais dans des scénarios réels, ces facteurs latents ne doivent pas être trop analysés. Ce sont des modèles dans les données qui joueront automatiquement leur rôle, que vous en déchiffriez ou non la signification sous-jacente.

Le nombre de facteurs latents affecte les recommandations de manière à ce que plus les facteurs sont nombreux, plus les recommandations deviennent personnalisées. Mais trop de facteurs peuvent conduire à une sur-adaptation dans le modèle.

Algorithmes de factorisation matricielle

L'un des algorithmes populaires pour factoriser une matrice est l'algorithme de décomposition en valeurs singulières (SVD). La SVD a été mise à l'honneur lorsque la factorisation matricielle s'est bien comportée dans le cadre du concours du prix Netflix. D'autres algorithmes incluent PCA et ses variations, NMF, etc. Les auto-encodeurs peuvent également être utilisés pour la réduction de la dimensionnalité si vous souhaitez utiliser des réseaux de neurones.

Vous pouvez trouver les implémentations de ces algorithmes dans diverses bibliothèques pour Python. Vous n'avez donc pas à vous soucier des détails à ce stade. Mais au cas où vous voudriez lire plus, le chapitre sur la réduction de la dimensionnalité dans le livre Exploitation de jeux de données massifs vaut la peine d'être lu.

Utiliser Python pour créer des recommandations

Python contient de nombreuses bibliothèques et boîtes à outils qui fournissent des implémentations de divers algorithmes que vous pouvez utiliser pour créer un programme de recommandation. Mais celui que vous devriez essayer tout en comprenant les systèmes de recommandation est la surprise.

Surprise est un SciKit Python fourni avec divers algorithmes de recommandation et métriques de similarité facilitant la création et l'analyse de recommandations.

Voici comment l’installer à l’aide de pip:

$ pip installer numpy
$ pip installer scikit-surprise

Voici comment l’installer avec conda:

$ conda installer -c conda-forge scikit-surprise

Pour utiliser Surprise, vous devez d'abord connaître certains des modules et des classes de base disponibles:

  • le Ensemble de données module est utilisé pour charger des données à partir de fichiers, de cadres de données Pandas ou même de jeux de données intégrés disponibles pour l’expérimentation. (MovieLens 100k est l'un des jeux de données intégrés à Surprise.) Pour charger un jeu de données, voici certaines des méthodes disponibles:

    • Dataset.load_builtin ()
    • Dataset.load_from_file ()
    • Dataset.load_from_df ()
  • le Lecteur La classe est utilisée pour analyser un fichier contenant des évaluations. Le format par défaut dans lequel il accepte les données est que chaque évaluation est stockée sur une ligne distincte dans l'ordre. cote de l'utilisateur. Cet ordre et le séparateur peuvent être configurés à l'aide de paramètres:

    • line_format est une chaîne qui stocke l'ordre des données avec des noms de champs séparés par un espace, comme dans "cote utilisateur de l'article".
    • SEP est utilisé pour spécifier un séparateur entre les champs, tel que ','.
    • échelle de notation est utilisé pour spécifier l'échelle d'évaluation. La valeur par défaut est (1, 5).
    • skip_lines est utilisé pour indiquer le nombre de lignes à ignorer au début du fichier. La valeur par défaut est 0.

Voici un programme que vous pouvez utiliser pour charger des données à partir d’un cadre de données Pandas ou du jeu de données intégré de MovieLens 100k:

# load_data.py

importation pandas comme pd
de surprise importation Ensemble de données
de surprise importation Lecteur

# Ce sont les mêmes données qui ont été tracées pour la similitude plus tôt
# avec un nouvel utilisateur "E" qui a classé uniquement le film 1
rating_dict = 
    "article": [[[[1, 2, 1, 2, 1, 2, 1, 2, 1],
    "utilisateur": [[[['UNE', 'UNE', 'B', 'B', 'C', 'C', 'RÉ', 'RÉ', 'E'],
    "évaluation": [[[[1, 2, 2, 4, 2,5, 4, 4,5, 5, 3],


df = pd.Trame de données(rating_dict)
lecteur = Lecteur(échelle de notation=(1, 5))

# Charge le cadre de données Pandas
Les données = Ensemble de données.load_from_df(df[[[[[[[["utilisateur", "article", "évaluation"]], lecteur)
# Charge les données intégrées Movielens-100k
movielens = Ensemble de données.load_builtin('ml-100k')

Dans le programme ci-dessus, les données sont stockées dans un dictionnaire chargé dans un cadre de données Pandas, puis dans un objet Ensemble de données de Surprise.

Algorithmes basés sur les voisins les plus proches de K (k-NN)

Le choix de l'algorithme pour la fonction de recommandation dépend de la technique que vous souhaitez utiliser. Pour les approches basées sur la mémoire décrites ci-dessus, l'algorithme qui convient au projet de loi est k-NN centré car il est très proche de la formule de similarité en cosinus centrée expliquée ci-dessus. Il est disponible dans Surprise comme KNNWithMeans.

Pour trouver la similarité, il vous suffit de configurer la fonction en transmettant un dictionnaire en tant qu'argument à la fonction de recommandation. Le dictionnaire doit avoir les clés requises, telles que:

  • prénom contient la métrique de similarité à utiliser. Les options sont cosinus, msd, Pearson, ou pearson_baseline. La valeur par défaut est msd.
  • basé sur l'utilisateur est un booléen cela indique si l'approche sera basée sur l'utilisateur ou sur l'élément. La valeur par défaut est Vrai, ce qui signifie que l’approche basée sur l’utilisateur sera utilisée.
  • min_support est le nombre minimum d'éléments communs nécessaires entre les utilisateurs pour les considérer comme similaires. Pour l'approche basée sur les éléments, cela correspond au nombre minimum d'utilisateurs communs pour deux éléments.

Le programme suivant configure le KNNWithMeans une fonction:

# recommender.py

de surprise importation KNNWithMeans

# Pour utiliser la similarité de cosinus basée sur les éléments
sim_options = 
    "prénom": "cosinus",
    "user_based": Faux,  # Calculer les similitudes entre les éléments

algo = KNNWithMeans(sim_options=sim_options)

La fonction de recommandation du programme ci-dessus est configurée pour utiliser la similarité de cosinus et pour rechercher des éléments similaires à l'aide de l'approche basée sur les éléments.

Pour essayer cette recommandation, vous devez créer un Trainet de Les données. Trainet est construit en utilisant les mêmes données mais contient plus d’informations sur les données, telles que le nombre d’utilisateurs et d’éléments (n_users, n_items) utilisés par l’algorithme. Vous pouvez le créer en utilisant l'intégralité des données ou une partie des données. Vous pouvez également diviser les données en plis où certaines données seront utilisées pour la formation et d’autres pour les tests.

Voici un exemple pour savoir comment l'utilisateur E serait évaluer le film 2:

>>>

>>> de load_data importation Les données
>>> de conseiller importation algo

>>> formationSet = Les données.build_full_trainset()

>>> algo.en forme(formationSet)
Calcul de la matrice de similarité cosinus ...
Terminé l'informatique matrice de similarité.


>>> prédiction = algo.prédire('E', 2)
>>> prédiction.est
4.15

L'algorithme prédit que l'utilisateur E le film 4.15, qui pourrait être assez élevé pour être présenté comme une recommandation.

Vous devriez essayer différents algorithmes basés sur k-NN ainsi que différentes options de similarité et algorithmes de factorisation de matrice disponibles dans la bibliothèque Surprise. Essayez-les sur le jeu de données MovieLens pour voir si vous pouvez battre certains points de repère. La section suivante explique comment utiliser Surprise pour déterminer les paramètres les plus performants pour vos données.

Réglage des paramètres de l'algorithme

Surprise fournit un GridSearchCV classe analogue à GridSearchCV de scikit-learn.

Avec un dict de tous les paramètres, GridSearchCV essaie toutes les combinaisons de paramètres et affiche les meilleurs paramètres pour toute mesure de précision

Par exemple, vous pouvez vérifier quelle métrique de similarité convient le mieux à vos données dans les approches basées sur la mémoire:

de surprise importation KNNWithMeans
de surprise importation Ensemble de données
de surprise.model_selection importation GridSearchCV

Les données = Ensemble de données.load_builtin("ml-100k")
sim_options = 
    "prénom": [[[["msd", "cosinus"],
    "min_support": [[[[3, 4, 5],
    "user_based": [[[[Faux, Vrai],


param_grid = "sim_options": sim_options

gs = GridSearchCV(KNNWithMeans, param_grid, les mesures=[[[["rmse", "mae"], CV=3)
gs.en forme(Les données)

impression(gs.meilleur score[[[["rmse"])
impression(gs.best_params[[[["rmse"])

Le résultat du programme ci-dessus est le suivant:

0,9434791128171457
'sim_options': 'name': 'msd', 'min_support': 3, 'user_based': False

Ainsi, pour le jeu de données MovieLens 100k, l'algorithme Centered-KNN fonctionne mieux si vous utilisez une approche basée sur les éléments et utilisez msd comme métrique de similarité avec une prise en charge minimale 3.

De même, pour les approches basées sur des modèles, nous pouvons utiliser Surprise pour vérifier quelles valeurs pour les facteurs suivants fonctionnent le mieux:

  • n_epochs est le nombre d'itérations de SGD, qui est essentiellement une méthode itérative utilisée dans Statistics pour minimiser une fonction.
  • lr_all est le taux d'apprentissage de tous les paramètres, paramètre qui détermine le degré de réglage des paramètres à chaque itération.
  • reg_all est le terme de régularisation pour tous les paramètres, qui est un terme de pénalité ajouté pour éviter les sur-ajustements.

Le programme suivant vérifiera les meilleures valeurs pour l'algorithme SVD, qui est un algorithme de factorisation matricielle:

de surprise importation SVD
de surprise importation Ensemble de données
de surprise.model_selection importation GridSearchCV

Les données = Ensemble de données.load_builtin("ml-100k")

param_grid = 
    "n_epochs": [[[[5, dix],
    "lr_all": [[[[0,002, 0,005],
    "reg_all": [[[[0.4, 0.6]

gs = GridSearchCV(SVD, param_grid, les mesures=[[[["rmse", "mae"], CV=3)

gs.en forme(Les données)

impression(gs.meilleur score[[[["rmse"])
impression(gs.best_params[[[["rmse"])

Le résultat du programme ci-dessus est le suivant:

0.9642278631521038
'n_epochs': 10, 'lr_all': 0,005, 'reg_all': 0,4

Donc, pour le jeu de données MovieLens 100k, le SVD L'algorithme fonctionne mieux si vous utilisez 10 époques et utilisez un taux d'apprentissage de 0,005 et une régularisation de 0,4.

Autres algorithmes basés sur la factorisation matricielle disponibles dans Surprise sont SVD ++ et NMF.

En suivant ces exemples, vous pouvez vous plonger dans tous les paramètres utilisables dans ces algorithmes. Vous devriez certainement vérifier les mathématiques derrière eux. Étant donné que vous n’aurez pas à vous soucier de la mise en œuvre des algorithmes au départ, les recommandations peuvent être un excellent moyen de passer au domaine de l’apprentissage automatique et de construire une application à partir de cela.

Quand utiliser le filtrage collaboratif?

Le filtrage collaboratif contourne les interactions des utilisateurs avec les éléments. Ces interactions peuvent aider à trouver des modèles que les données sur les éléments ou les utilisateurs eux-mêmes ne peuvent pas. Voici quelques points qui peuvent vous aider à décider si le filtrage collaboratif peut être utilisé:

  • Le filtrage collaboratif n’exige pas que les fonctionnalités relatives aux éléments ou aux utilisateurs soient connues. Il convient à différents types d’articles, par exemple l’inventaire d’un supermarché où des articles de différentes catégories peuvent être ajoutés. Toutefois, dans un ensemble d’articles similaires, tels que ceux d’une librairie, des fonctionnalités connues, telles que les écrivains et les genres, peuvent être utiles et peuvent bénéficier d’approches hybrides ou basées sur le contenu.

  • Le filtrage collaboratif peut aider les recommandations à ne pas surspécialiser le profil d’un utilisateur et à recommander des éléments complètement différents de ce qu’ils avaient vu auparavant. If you want your recommender to not suggest a pair of sneakers to someone who just bought another similar pair of sneakers, then try to add collaborative filtering to your recommender spell.

Although collaborative Filtering is very commonly used in recommenders, some of the challenges that are faced while using it are the following:

  • Collaborative filtering can lead to some problems like cold start for new items that are added to the list. Until someone rates them, they don’t get recommended.

  • Data sparsity can affect the quality of user-based recommenders and also add to the cold start problem mentioned above.

  • Scaling can be a challenge for growing datasets as the complexity can become too large. Item-based recommenders are faster than user-based when the dataset is large.

  • With a straightforward implementation, you might observe that the recommendations tend to be already popular, and the items from the long tail section might get ignored.

With every type of recommender algorithm having its own list of pros and cons, it’s usually a hybrid recommender that comes to the rescue. The benefits of multiple algorithms working together or in a pipeline can help you set up more accurate recommenders. In fact, the solution of the winner of the Netflix prize was also a complex mix of multiple algorithms.

Conclusion

You now know what calculations go into a collaborative-filtering type recommender and how to try out the various types of algorithms quickly on your dataset to see if collaborative filtering is the way to go. Even if it does not seem to fit your data with high accuracy, some of the use cases discussed might help you plan things in a hybrid way for the long term.

Here are some resources for more implementations and further reading on collaborative filtering and other recommendation algorithms.

Libraries:

  • LightFM: a hybrid recommendation algorithm in Python
  • Python-recsys: a Python library for implementing a recommender system

Research papers:

Books: