Créer un moteur de recommandation avec un filtrage collaboratif

Créer un moteur de recommandation avec un filtrage collaboratif

Le filtrage collaboratif est la technique la plus couramment utilisée pour créer des systèmes de recommandation intelligents qui peuvent apprendre à donner 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 recommandateurs qui donnent des suggestions à un utilisateur sur la base des goûts et des aversions d’utilisateurs similaires.

*Dans cet article, vous découvrirez:*
  • Filtrage collaboratif et types informatiques

  • Données nécessaires pour créer un recommandeur

  • Bibliothèques disponibles en Python pour construire des recommandateurs

  • Cas d’utilisation et défis du filtrage collaboratif

    *Bonus gratuit:* lien: [Cliquez ici pour accéder à un chapitre de Python Tricks: The Book] qui vous montre les meilleures pratiques de Python avec des exemples simples que vous pouvez appliquer instantanément pour écrire du code Pythonic plus beau +.

Qu’est-ce que le filtrage collaboratif?

Le filtrage collaboratif est une technique qui peut filtrer les éléments qu’un utilisateur pourrait aimer sur la base des réactions d’utilisateurs similaires.

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

Il existe de nombreuses façons de décider quels utilisateurs sont similaires et de combiner leurs choix pour créer une liste de recommandations. Cet article vous montrera comment faire cela avec Python.

L’ensemble de données

Pour tester 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 éléments.

La réaction peut être explicite (évaluation sur une échelle de 1 à 5, j’aime ou n’aime pas) ou implicite (visualiser 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 la forme d’une matrice constituée des réactions données par un ensemble d’utilisateurs à certains éléments d’un ensemble d’éléments. Chaque ligne contiendrait les notes données par un utilisateur et chaque colonne contiendrait les notes reçues par un élément. Une matrice avec cinq utilisateurs et cinq éléments pourrait ressembler à ceci:

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

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

De nombreux ensembles de données ont été collectés et mis à la disposition du public pour la recherche et l’analyse comparative. Voici une list de sources de données de haute qualité parmi lesquelles vous pouvez choisir.

Le meilleur moyen de commencer serait l’ensemble de données MovieLens collecté par GroupLens Research. En particulier, le MovieLens 100k dataset est un ensemble de données de référence stable avec 100 000 évaluations données par 943 utilisateurs pour 1682 films, chaque utilisateur ayant évalué au moins 20 films.

Cet ensemble de données se compose de nombreux fichiers qui contiennent des informations sur les films, les utilisateurs et les notes attribuées par les utilisateurs aux films qu’ils ont regardés. Celles qui sont intéressantes sont les suivantes:

  • + u.item +: la liste des films

  • + u.data +: la liste des évaluations données par les utilisateurs

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

Comme indiqué ci-dessus, le fichier indique la note attribuée par un utilisateur à 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 des autres utilisateurs, la première étape consiste à rechercher des utilisateurs ou des éléments similaires. La deuxième étape consiste à prédire les notes des articles qui ne sont pas encore notées par un utilisateur. Vous aurez donc besoin des réponses à ces questions:

  • Comment déterminez-vous quels utilisateurs ou éléments sont similaires les uns aux autres?

  • Étant donné que vous savez quels utilisateurs sont similaires, comment déterminez-vous la note qu’un utilisateur attribuerait à un élément en fonction des notes d’utilisateurs similaires? *Comment mesurez-vous l’exactitude des notes 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 façons de calculer la note en fonction des notes d’utilisateurs similaires. Selon les choix que vous faites, vous vous retrouvez avec un type d’approche de filtrage collaboratif. Vous découvrirez les différentes approches permettant de trouver des similitudes et de prédire les notes dans cet article.

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

La troisième question sur la façon de mesurer la précision de vos prédictions a également plusieurs réponses, qui incluent des techniques de calcul d’erreur qui peuvent être utilisées à de nombreux endroits et pas seulement des recommandations basées sur un filtrage collaboratif.

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

Une autre mesure pour mesurer la précision est l’erreur absolue moyenne (MAE), dans laquelle vous trouvez l’ampleur de l’erreur en trouvant 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 MAE à ce stade car ils sont facilement disponibles dans le cadre de divers packages en Python, et vous les verrez plus loin 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 des données pour calculer les prédictions.

Pour trouver la note* R qu’un utilisateur U donnerait à un élément I *, l’approche comprend:

*Recherche d'utilisateurs similaires à* U *qui ont évalué l'article* I *
*Calcul de la note* R *en fonction des notes des utilisateurs trouvées à l'étape précédente

Vous les verrez chacun en détail dans les sections suivantes.

Comment trouver des utilisateurs similaires sur la base des évaluations

Pour comprendre le concept de similitude, créons d’abord un jeu de données simple.

Les données incluent quatre utilisateurs* A , *B , C et D , qui ont évalué deux films. Les classements sont stockés dans des listes, et chaque liste contient deux chiffres indiquant le classement de chaque film:

*Les notes par* A * sont `+ [1.0, 2.0] +`.
*Les notes par* B * sont `+ [2.0, 4.0] +`.
*Les notes par* C * sont `+ [2.5, 4.0] +`.
*Les notes par* D *sont `+ [4.5, 5.0] +`.

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

Dans le graphique ci-dessus, chaque point représente un utilisateur et est tracé en fonction des notes attribuées à deux films.

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

>>>

>>> from scipy import spatial

>>> a = [1, 2]
>>> b = [2, 4]
>>> c = [2.5, 4]
>>> d = [4.5, 5]

>>> spatial.distance.euclidean(c, a)
2.5
>>> spatial.distance.euclidean(c, b)
0.5
>>> spatial.distance.euclidean(c, d)
2.23606797749979

Comme indiqué ci-dessus, vous pouvez utiliser + scipy.spatial.distance.euclidean + pour calculer la distance entre deux points. L’utiliser pour calculer la distance entre les notes de* A , *B et D à celle de C nous montre qu’en termes de distance, les notes de C sont les plus proches de celles de B .

Vous pouvez voir que l’utilisateur C est le plus proche de B même en regardant le graphique. Mais sur A et D seulement, qui est le plus proche de C ?

On pourrait dire que C est plus proche de D en termes de distance. Mais en regardant le classement, il semblerait que les choix de C correspondraient à ceux de A plus que D parce que les deux A et C aiment le deuxième film presque deux fois plus qu’ils aiment le premier film, mais D aime également les deux films.

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 jeter un œil à l’angle entre les lignes joignant l’origine du graphique aux points respectifs comme indiqué:

Deux vecteurs dimensionnels tracés sur un graphique pour expliquer l’angle comme une métrique de distance

Le graphique montre quatre lignes joignant chaque point à l’origine. Les lignes pour A et B coïncident, rendant l’angle entre elles nul.

Vous pouvez considérer que si l’angle entre les lignes augmente, la similitude diminue et si l’angle est nul, les utilisateurs sont très similaires.

Pour calculer la similitude à l’aide de l’angle, vous avez besoin d’une fonction qui renvoie une similitude plus élevée ou une distance plus petite pour un angle inférieur et une similitude inférieure ou une distance plus grande 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 similitude entre deux utilisateurs. Plus l’angle est élevé, plus le cosinus sera faible et donc, plus la similitude des utilisateurs sera faible. Vous pouvez également inverser la valeur du cosinus de l’angle pour obtenir la distance cosinus entre les utilisateurs en la soustrayant de 1.

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

>>>

>>> from scipy import spatial
>>> a = [1, 2]
>>> b = [2, 4]
>>> c = [2.5, 4]
>>> d = [4.5, 5]

>>> spatial.distance.cosine(c,a)
0.004504527406047898

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

>>> spatial.distance.cosine(c,d)
0.015137225946083022

>>> spatial.distance.cosine(a,b)
0.0

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

*Remarque:* Dans l'exemple ci-dessus, seuls deux films sont pris en compte, ce qui facilite la visualisation des vecteurs de notation en deux dimensions. Cela n'est fait que pour rendre l'explication plus facile.

Les cas d’utilisation réels avec plusieurs éléments impliqueraient plus de dimensions dans les vecteurs d’évaluation. Vous voudrez peut-être aussi entrer dans les mathématiques de cosine similarity.

Notez que les utilisateurs A et B sont considérés comme absolument similaires dans la métrique de similitude cosinus, bien qu’ils aient des notes différentes. Il s’agit en fait d’un phénomène courant dans le monde réel, et les utilisateurs comme l’utilisateur A sont ce que vous pouvez appeler des évaluateurs difficiles . Un exemple serait un critique de cinéma qui donne toujours des notes inférieures à la moyenne, mais le classement des éléments de leur liste serait similaire aux évaluateurs moyens comme B .

Pour prendre en compte ces préférences utilisateur individuelles, vous devrez amener tous les utilisateurs au même niveau en supprimant leurs biais. Vous pouvez le faire en soustrayant la note moyenne donnée par cet utilisateur à tous les articles de chaque article évalué par cet utilisateur. Voici à quoi cela ressemblerait:

*Pour l'utilisateur* A *, le vecteur de notation `+ [1, 2] +` a la moyenne `+ 1,5 +`. En soustrayant `+ 1.5 +` de chaque note, vous obtiendrez le vecteur `+ [- 0.5, 0.5] +`.
*Pour l'utilisateur* B *, le vecteur de notation `+ [2, 4] +` a la moyenne `+ 3 +`. En soustrayant `+ 3 +` de chaque note, vous obtiendrez le vecteur `+ [- 1, 1] +`.

En faisant cela, vous avez changé la valeur de la note moyenne donnée par chaque utilisateur à 0. Essayez de faire de même pour les utilisateurs C et D , et vous verrez que les notes sont désormais ajustées pour donner une moyenne de 0 pour 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 normalement utilisée lorsqu’il y a beaucoup de valeurs manquantes dans les vecteurs, et vous devez placer une valeur commune pour remplir les valeurs manquantes.

Remplir les valeurs manquantes dans la matrice de notation avec une valeur aléatoire pourrait entraîner des inexactitudes. Un bon choix pour remplir les valeurs manquantes pourrait être la note moyenne de chaque utilisateur, mais les moyennes originales de l’utilisateur A et B sont respectivement + 1,5 + et + 3 +, et en remplissant tous les espaces vides les valeurs de A avec + 1.5 + et celles de B avec + 3 + feraient d’eux des utilisateurs différents.

Mais après avoir ajusté les valeurs, la moyenne centrée des deux utilisateurs est + 0 +, ce qui vous permet de capturer plus précisément l’idée que l’élément est supérieur ou inférieur à la moyenne pour les deux utilisateurs avec toutes les valeurs manquantes dans les vecteurs des deux utilisateurs ayant la même valeur + 0 +.

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

*Remarque:* La formule du cosinus centré est la même que celle du coefficient de corrélation de Pearson. Vous constaterez que de nombreuses ressources et bibliothèques sur les recommandateurs font référence à l'implémentation du cosinus centré sous le nom de corrélation de Pearson.

Comment calculer les évaluations

Après avoir déterminé une liste d’utilisateurs similaires à un utilisateur U , vous devez calculer la note R que U donnerait à un certain élément I . Encore une fois, tout comme la similitude, vous pouvez le faire de plusieurs manières.

Vous pouvez prévoir que la note d’un utilisateur R pour un élément I sera proche de la moyenne des notes attribuées à I par les 5 ou 10 premiers utilisateurs les plus similaires à U . La formule mathématique pour la note moyenne donnée par les utilisateurs n ressemblerait à ceci:

Formule pour la cote moyenne

Cette formule montre que la note moyenne donnée par les n utilisateurs similaires est égale à la somme des notes données par eux divisée par le nombre d’utilisateurs similaires, qui est n.

Il y aura des situations où les n utilisateurs similaires que vous avez trouvés ne sont pas similaires à l’utilisateur cible U . Les 3 premiers d’entre eux pourraient être très similaires, et les autres pourraient ne pas être aussi similaires à U que les 3 premiers. Dans ce cas, vous pouvez envisager une approche dans laquelle la note de l’utilisateur le plus similaire importe plus que celle du deuxième utilisateur le plus similaire, etc. La moyenne pondérée peut nous aider à y parvenir.

Dans l’approche moyenne pondérée, vous multipliez chaque note par un facteur de similitude (qui indique à quel point les utilisateurs sont similaires). En multipliant avec le facteur de similitude, vous ajoutez des pondérations aux notes. Plus le poids est lourd, plus la cote importe.

Le facteur de similitude, qui agirait comme des poids, devrait être l’inverse de la distance discutée ci-dessus, car moins de distance implique une similitude plus élevée. Par exemple, vous pouvez soustraire la distance cosinus de 1 pour obtenir une similitude cosinus.

Avec le facteur de similitude S pour chaque utilisateur similaire à l’utilisateur cible U , vous pouvez calculer la moyenne pondérée à l’aide de cette formule:

Formule pour la moyenne pondérée

Dans la formule ci-dessus, chaque note est multipliée par le facteur de similitude de l’utilisateur qui a donné la note. La note finale prévue par l’utilisateur U sera égale à la somme des notes pondérées divisée par la somme des poids.

*Remarque:* Si vous vous demandez pourquoi la somme des notes pondérées est divisée par la somme des poids et non par _n_, considérez ceci: dans la formule précédente de la moyenne, où vous avez divisé par _n_, la valeur de le poids était de 1.

Le dénominateur est toujours la somme des poids quand il s’agit de trouver des moyennes, et dans le cas de la moyenne normale, le poids étant 1 signifie que le dénominateur serait égal à n.

Avec une moyenne pondérée, vous accordez plus d’attention aux évaluations d’utilisateurs similaires par ordre de similitude.

Maintenant, vous savez comment trouver des utilisateurs similaires et comment calculer les notes en fonction de leurs notes. Il existe également une variante du filtrage collaboratif où vous prédisez les notes en trouvant des éléments similaires les uns aux autres au lieu des utilisateurs et en calculant les notes. Vous découvrirez cette variante dans la section suivante.

Filtrage collaboratif basé sur l’utilisateur vs basé sur l’élément

La technique dans les exemples expliqués ci-dessus, où la matrice de notation est utilisée pour trouver des utilisateurs similaires en fonction des notes qu’ils donnent, est appelée filtrage collaboratif basé sur l’utilisateur ou utilisateur-utilisateur. Si vous utilisez la matrice de notation pour rechercher des éléments similaires en fonction des notes qui leur sont attribuées par les utilisateurs, l’approche est appelée filtrage collaboratif par élément ou 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 se comparent:

  • Basé sur l’utilisateur: Pour un utilisateur U , avec un ensemble d’utilisateurs similaires déterminés sur la base de vecteurs de notation composés de notes d’articles données, la note d’un article I , qui n’a pas été évalué, est trouvée en sélectionnant sur N utilisateurs de la liste de similarité qui ont évalué l’article I et calculant la note sur la base de ces N notes.

  • Basé sur un article: Pour un article I , avec un ensemble d’articles similaires déterminés sur la base de vecteurs de notation composés de notes d’utilisateurs reçues, la note d’un utilisateur U , qui ne l’a pas évalué, est trouvée en sélectionnant sur N éléments de la liste de similitude qui ont été notés par U et calculant la note sur la base de ces N notes.

Le filtrage collaboratif basé sur les éléments a été développé par Amazon. Dans un système où il y a plus d’utilisateurs que d’éléments, le filtrage basé sur les éléments est plus rapide et plus stable que celui basé sur les utilisateurs. Il est efficace car, généralement, la note moyenne reçue par un élément ne change pas aussi rapidement que la note moyenne attribuée par un utilisateur à différents éléments. Il est également connu pour être plus performant que l’approche basée sur l’utilisateur lorsque la matrice de notation est rare.

Bien que l’approche basée sur les éléments fonctionne mal pour les ensembles de données avec des éléments liés à la navigation ou au divertissement tels que MovieLens, où les recommandations qu’elle donne semblent très évidentes pour les utilisateurs cibles. De tels ensembles de données obtiennent de meilleurs résultats avec les techniques de factorisation matricielle, que vous verrez dans la section suivante, ou avec des recommandateurs hybrides qui prennent également en compte le contenu des données comme le genre en utilisant https://en.wikipedia.org/wiki/Recommender_system # Content-based_filtering [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 loin dans l’article.)

Basé sur le modèle

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

Réduction de la dimensionnalité

Dans la matrice utilisateur-élément, il existe deux dimensions:

  1. Le nombre d’utilisateurs

  2. Le nombre d’articles

Si la matrice est principalement vide, la réduction des dimensions peut améliorer les performances de l’algorithme en termes d’espace et de temps. Vous pouvez utiliser différentes méthodes comme la factorisation matricielle ou les encodeurs automatiques pour ce faire.

*La factorisation matricielle* peut être considérée comme décomposant une grande matrice en un produit de plus petites. Ceci est similaire à la factorisation des entiers, où «+ 12 +» peut être écrit comme «+6 x 2 +» ou «+4 x 3 +». Dans le cas des matrices, une matrice *A* de dimensions `+ m x n +` peut être réduite à un produit de deux matrices *X* et *Y* de dimensions `+ m x p +` et `+ p x n +` respectivement.
*Remarque:* Dans la multiplication matricielle, une matrice *X* peut être multipliée par *Y* uniquement si le nombre de colonnes dans *X* est égal au nombre de lignes dans *Y* . Par conséquent, les deux matrices réduites ont une dimension commune *p* .

Selon l’algorithme utilisé pour la réduction de dimensionnalité, le nombre de matrices réduites peut également être supérieur à deux.

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

Dans l’image ci-dessus, la matrice est réduite en deux matrices. Celui de gauche est la matrice utilisateur avec m utilisateurs, et celui du haut est la matrice d’élément avec n éléments. La note + 4 + est réduite ou factorisée en:

  1. Un vecteur utilisateur + (2, -1) +

  2. Un vecteur d’élément + (2.5, 1) +

Les deux colonnes de la matrice utilisateur et les deux lignes de la matrice d’élément 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) +, + u + représente à quel point un utilisateur aime le genre Horreur et + v + représente à quel point il aime le genre Romance.

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

  • Supposons que dans un vecteur d’élément + (i, j) +, + i + représente à quel point un film appartient au genre Horreur et + j + représente à quel point ce film appartient au genre Romance. Le film + (2.5, 1) + a une cote Horreur de + 2.5 + et une note Romance de + 1 +. La multiplication par le vecteur utilisateur en utilisant des règles de multiplication matricielle vous donne + (2 2,5) + (-1 * 1) = 4 +