Recommandation collaborative

Le dernier TP du premier semestre concernait la recommandation par contenu. Ce TP concerne l'autre approche de recommandation, la recommandation collaborative. Ce TP se veut très libre : hormis la mise en œuvre de ce type de recommandation, vous êtes invités à explorer le jeu de données, proposer des idées et les tester.

À l'issue de ce TP, vous m'envoyez par email un compte-rendu (format pdf) décrivant ce que vous avez fait.

Les données

Les données sont issues du site last.fm ; elles ont été rendues publiques à des fins de recherche et sont libres d'utilisation pour la recherche à but non lucratif. Elles respectent la RGPD, elles ne contiennent aucune information permettant d'identifier qui que ce soit parmi les utilisateurs de ce site.
Les données sont disponibles dans plusieurs fichiers inter-connectés. Elles sont relativement volumineuses. Elles sont constituées d'utilisateurs, d'artistes, de tags, de durées d'écoute, de liens entre utilisateurs. Il y a environ 2000 utilisateurs, 20.000 artistes et 90.000 informations d'écoutes, sans compter 10.000 liens entre utilisateurs et 200.000 taggages.

Préliminaires

Comme d'habitude, on commence par jeter un coup d'œil aux différents fichiers. Il faut bien comprendre comment ils sont organisés et comment ils sont reliés les uns aux autres. Les fichiers sont assez volumineux, ce qui complique les choses.
On calculera également quelques statistiques, ne serait-ce que le nombre d'utilisateurs, d'artistes, d'écoutes. On peut rechercher des utilisateurs qui écoutent beaucoup, beaucoup d'artistes différents, le nombre de liens avec d'autres utilisateurs, le nombre de tags déposés.
Il faut garder en tête l'objectif : recommander des artistes à des utilisateurs, en espérant que les recommandations vont plaire, sinon les utilisateurs vont fuir le site. Il est utile de réflêchir à la manière dont on pourrait faire de la recommandation avec ces données, en particulier de la recommandation collaborative.

Recommandation collaborative par remplissage de matrice

J'explique ici comment faire ce que l'on a vu en cours pour remplir une matrice.
On suppose donc que l'on dispose de triplets (utilisateur, produit, note) ; on suppose que la note est un entier naturel dont la valeur est comprise entre 0 et 5. Notons N le nombre de produits, M le nombre d'utilsateurs et T le nombre de triplets. On considère une matrice R dont chaque ligne correspond à un produit, chaque colonne à un utilisateur. Chaque élément de la matrice R est la note d'un artiste par un utilisateur. Typiquement, T est très très inférieur au produit N M, R est donc très creuse. On essaie d'estimer toutes les valeurs manquantes de R. La méthode traditionnelle consiste à réaliser une factorisation non négative de R. En python, on procède comme suit. Comme R est très creuse, on représente cette matrice de manière particulière : on stocke uniquement les valeurs non nulles. Ainsi, on crée 3 matrices ayant chacune T éléments. Je les note inotes, jnotes, notes. Pour un indice i donné, la note notes [i] correspond au produit inotes [i] et à l'utilisateur jnotes [i]. Ensuite, on crée un objet matrice creuse (sparse matrix en anglais) comme suit :

from scipy.sparse import csc_matrix
R = csc_matrix ((notes, (inotes, jnotes)), shape = (N, M))

R contient donc une matrice creuse avec les notes connues. Pour la factoriser, on écrit :

from sklearn.decomposition import NMF
nmf = NMF (n_components = K, init = "random", max_iter = 20000, random_state = rs)
U = nmf. fit_transform (ratings)
V = nmf.components_

K est le rang supposé de la matrice R. La matrice U est de dimensions MxK, la matrice V de dimensions KxN. Ainsi, leur produit E = U. dot (V) donne une matrice de dimensions NxM, donc qui correspond bien à une matrice de notes de chaque produit par chaque utilisateur. On peut tester plusieurs valeurs de K. Prendre K = 100 donne des résultats intéressants. E contient une estimation de chacune de ces notes.
Remarque : ça peut être long, quelques minutes.

À faire : nous ne disposons pas de notes. Nous disposons de durées d'écoute qui sont utiles : si un utilisateur écoute beaucoup un artiste, on peut imaginer qu'il lui mettrait une bonne note. Donc, réfléchissez à transformer les durées d'écoute en notes. Ensuite, réaliser une factorisation de cette matrice de notes. Comparer les notes estimées avec les notes correspondant aux durées d'écoute : qu'en pensez-vous ?

Recommandation collaborative par remplissage de matrice

Maintenant, essayez de réaliser un système de recommandation avec les données dont vous disposez.
Vous pouvez tester votre système en créant un utilisateur qui a fait certaines écoutes de certains artistes comme vous l'auriez fait vous-mêmes et regarder si les recommandations vous satisfont.
Vous pouvez aussi utiliser le jeu de données qui avait été utilisé pour le dernier TP du semestre précédent.