import numpy as np
import scipy.sparse as sp
import matplotlib.pyplot as plt
Récupérez l'archive http://files.grouplens.org/datasets/movielens/ml-100k.zip, sauvegardez-la dans votre répertoire de travail, et décompressez-la.
Le jeu de données contient 100,000 notes (entre 1 et 5) données par 943 utilisateurs sur 1682 films.
Nous utiliserons pour ce TP:
u.data
qui contient la liste des diférentes notes données par les différents utilisateurs aux différents filmsu.item
qui fournit des informations sur les films concernés (titre, année de sortie, genre,...)import pandas
f = open("ml-100k/u.data",'r', encoding = 'latin_1')
rating_data = pandas.read_csv(f, delimiter='\t', header = None)
rating_data.columns=['user_id', 'item_id', 'rating', 'timestamp']
rating_data
Les notes sont définies sous forme de triplets (3 premières colonnes):
Pour qu'elles soient exploitables, vous devez transformer ces données au format matrice creuse (coo matrix ou csr matrix).
Voir:
http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.coo_matrix.html
http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csr_matrix.html
row = rating_data.user_id # !! numerotation à partir de 1
col = rating_data.item_id #
rating = rating_data.rating
X = sp.coo_matrix((rating, (row , col))).toarray()
(m,n) = X.shape
X_norm = np.zeros((m,n))
for i in range(1, m):
indices = np.where(X[i,:]>0)
X_norm[i,indices] = X[i,indices] - np.mean(X[i,indices])
plt.figure(figsize=(35,12))
plt.imshow(X_norm, aspect='auto')
Pour lire les données contenues dans u.item
, vous devez utiliser un pandas.read_csv
:
f = open("ml-100k/u.item",'r', encoding = 'latin_1')
film_data = pandas.read_csv(f, delimiter='|', header = None)
film_data.columns=['item_id', 'title', 'date', 'nan', 'url', 'unknown', 'Action', 'Adventure', 'Animation', "Children's", 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western']
film_data= film_data.set_index('item_id')
del film_data['nan']
film_data[['Action', 'Adventure', 'Animation', "Children's", 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western']].head(60)
C = np.cov(X_norm)
C.shape
Calcul des valeurs propres et des vecteurs propres
[L,V_acp] = np.linalg.eig(C)
Y_acp = V_acp.T.dot(X_norm)
Exercice 1 :
Représentez les 100 premiers films de la base sur les deux ou trois premieres composantes en utilisant les codes couleurs suivants :
Conclusion?
Exercice 2 : Reconstruction inverse
On souhaite représenter les films de la base à l'aide d'un nombre réduit de composantes.
U_svd, s, V_svd = np.linalg.svd(X_norm)
(m,n) = X_norm.shape
S_svd = np.zeros((m,n))
S_svd[:m, :m] = np.diag(s)
Reconstruction
X_rec = U_svd.dot(S_svd.dot(V_svd))
P, Q
P = U_svd.dot(np.sqrt(S_svd))[:m,:m]
Q = np.sqrt(S_svd).dot(V_svd)
Reconstruction du signal de départ à partir de P et Q
plt.imshow(np.dot(P,Q))
Exercice 3