Systèmes de recommandation par le contenu

Ce TP concerne les systèmes de recommandation par le contenu. C'est-à-dire, on dispose d'un ensemble d'items, chaque item est décrit par un certain nombre d'attributs et on veut par exemple trouver les k items qui ressemblent le plus à un item fixé.

Table des matières :

Chargement et pré-traitement des données

On va s'intéresser à tous les morceaux de musique qui ont été classés parmi les 100 premiers du classement américain (US Billboard Hot 100) de 1960 à 2010.
Pour une étude récente [1], des propriétés musicales de la plupart de ces morceaux ont été analysés. Les données résultantes sont disponibles en libre accès.

Accès aux données

La source de données est le fichier situé à l'url http://figshare.com/articles/Main_Dataset_for_Evolution_of_Popular_Music_USA_1960_2010_/1309953.

Pré-traitement

Ce jeu de données contient de nombreuses données, chacune décrite par de nombreux attributs. On a :

S'agissant d'un si gros jeu de données, il est vraiment indispensable de passer un peu de temps pour comprendre sa structure. C'est le but des questions qui suivent.

Les attributs (numériques) 12 à 269 ont été générés par divers algorithmes à partir des signaux audio de chaque morceau. Ces attributs encodent différents aspects liés au style de musique (rythme, accords, ...).
La question que l'on va étudier ci-dessous est : si j'aime tel morceau de musique (présent dans ce jeu de données), quels autres morceaux de musique peut-on me recommander si je veux écouter le même genre de musique ?

Les attributs sont décrits sur la page web d'où vous avez téléchargé le jeu de données. Il est nécessaire de s'assurer que les attributs sont considérés comme il faut par R. Quand on charge des attributs de divers types, il est rare que R interprête toutes les valeurs comme on le voudrait, qu'il distingue bien les chaînes de caractères, des facteurs, des dates, ...
Assurez-vous des points suivant :

Exploration du jeu de données

Avant d'étudier le problème qui nous intéresse ici, il faut toujours commencer par passer un peu de temps à regarder le jeu de données. Cela passe souvent par la réalisation de graphiques, leur observation et leur interprêtation.

Recommandation

Décrit par plus de 250 attributs numériques, chaque morceau de musique peut être vu comme un point dans un espace géométrique ayant plus de 250 dimensions.
Dans cet espace, on peut considérer la distance euclidienne et déterminer les points/items les plus proches d'un item donné.

  1. Avant d'aborder la recommandation, on s'intéresse d'abord à la distance séparant un morceau des autres morceaux. Pour un morceau donné, on va calculer sa distance à chacun des autres. On peut faire cela à l'aide d'une boucle. Vu le nombre de données, c'est assez long de calculer cette distance à chacun des autres morceaux. C'est un très bon exercice de le faire ; ne soyez pas surpris par le temps que prend le calcul. Vous prendrez une donnée quelconque (numéro i) et vous calculez sa distance à toutes les autres données. Vous utilisez les attributs numérotés 12 à 269 qui sont tous numériques.
  2. On va plutôt utiliser une fonction qui fait ce calcul de manière très efficace. Pour cela, il faut installer un paquet dénommé FNN. Faites :
    install.packages ("FNN")
    Une fois installé, vous devrez le charger pour pouvoir utiliser la fonction knn() qui y est définie.
    knn() détermine la classe d'une donnée à partir de celle de ses k plus proches voisins. Pour cela, knn() calcule la distance entre 1 point et tous les autres. C'est cela qui nous intéresse ici ; on ne veut pas déterminer la classe d'une donnée, mais juste calculer ces distances.
    L'utilisation de knn() est très simple :
    > distance.a.toutes.les.donnees <- knn (toutes.les.données, la.donnée.qui.nous.intéresse, factor (c (rep (0, nrow (toutes.les.données)))), k = nrow (toutes.les.données))
    Cela renvoie un objet qui contient différentes informations. En particulier, attr (distance.a.toutes.les.donnees, "nn.dist") contient la distance entre chacune des données contenue dans toutes.les.données et la.donnée.qui.nous.intéresse. Vous pouvez en faire un histogramme. Ça doit vous donner quelque chose qui ressemble à ça :

    Qu'en pensez-vous ? Pensez-vous que ces distributions soient normales ?

Les k plus proches voisins

Pour déterminer les k plus proches voisins, on spécifie simplement la valeur du paramètre k dans l'appel à knn(). Précédemment, on avait spécifié le nombre de données pour obtenir la distance à toutes les données.
Par exemple, pour les 10 plus proches voisins, on aurait :

> k.plus.proches.voisins <- knn (toutes.les.données, la.donnée.qui.nous.intéresse, factor (c (rep (0, nrow (toutes.les.données)))), k = 10)

Ensuite,

> attr (k.plus.proches.voisins, "nn.index")

fournit l'indice des k plus proches voisins.

Sélection d'items

Si l'on veut recommander des morceaux à quelqu'un qui aime un morceau en particlier, il suffit de rechercher ce morceau dans les données, de déterminer ces plus proches et de les proposer.

  1. Recherchez des morceaux que vous connaissez qui se trouvent dans le jeu de données.
  2. Pour chacun, déterminez ces 5 plus proches voisins. Cette sélection vous statisfait-elle ?

En réalité, en général, on dispose d'une liste de morceaux qui ont été écoutés.

Cette question n'est pas facile. Elle nécessite de la réflexion...
Vous disposez d'une liste d'écoute d'un utilisateur. Quels items recommandez-vous à partir de cette liste ?
Pour donner quelques exemples, voici quelques listes d'écoutes deplusieurs utilisateurs. Quelles recommandations faites-vous ?

Référence

[1] Mauch M., MacCallum RM, Levy M, Leroi AM. 2015 The evolution of popular music USA 1960-2010. R.Soc. open sci. 2:150081.