Auxiliar Tarea3

Importamos las librería que vamos a utilizar

In [1]:
import numpy as np
import matplotlib.pyplot as plt
#import scipy.optimize #Use for fmincg
import scipy as sp
from recommenders import *

Utilizamos el lector de archivos de NumPy, esto porque así cargamos los datos en un formato utilizable para las operaciones matemáticas posteriores

In [2]:
datafile = 'utility_matrix.txt'
mat = np.loadtxt( datafile )

Tomamos los índices de los elementos rankeados en la metriz, esto para luego dividir los datos (Ojo que los datos se dividen por par rankeado, no por usuario o ítem). Checkeamos además que todo esté en orden, vemos además el porcentaje de la matriz que es no-cero, la forma de la matriz y la cantidad de elementos no-cero.

In [3]:
x,y = np.nonzero(mat)
In [4]:
mat[x[0],y[0]],x[0],y[0],mat
Out[4]:
(5.0, 0, 0, array([[ 5.,  4.,  0., ...,  5.,  0.,  0.],
        [ 3.,  0.,  0., ...,  0.,  0.,  5.],
        [ 4.,  0.,  0., ...,  0.,  0.,  0.],
        ..., 
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.]]))
In [5]:
x.size/(mat.shape[0]*mat.shape[1])*100, np.min(mat[x,y]), mat.shape, x.size
Out[5]:
(6.304669364224531, 1.0, (1682, 943), 100000)

Test y entrenamiento

Dividimos en test y entrenamiento de forma aleatorea.

In [6]:
# Entrenamiento + Test
indices = np.random.permutation(x.size)

entrenamiento = indices[:int(3*x.size/4)]
test          = indices[int(3*x.size/4):]

Y construimos el test de entrenamiento.

In [7]:
Y_train = np.zeros_like(mat)
Y_train[x[entrenamiento],y[entrenamiento]] = mat[x[entrenamiento],y[entrenamiento]]

# Y_train2 = np.copy(mat)
# Y_train2[x[test],y[test]] = 0

Construimos el modelo y lo entrenamos (En el caso de los modelos que deba construir la función .fit(Y_train) sólo guardará los datos de Y_train pues son modelos lazy).

In [8]:
model_recommender = ModelBasedRecommender()#0.1*np.power(1.5,3),3+0)
model_recommender.fit(Y_train)
Out[8]:
<recommenders.ModelBasedRecommender at 0x4b85358>
In [9]:
pred = model_recommender.predict_many(x[test],y[test])
In [10]:
from sklearn.metrics import mean_squared_error
np.sqrt(mean_squared_error(mat[x[test],y[test]], pred))
Out[10]:
1.1860354126247663

Algo importante de lo anterior es que la función .predict(a,b) remplaza los valores mayores a 5 por 5 y menores a 1 por 1, además los redondea a entreros (ver el código de la función predict_many en el "return")

Similaridad Coseno

La similaridad coseno ya está implementada en scikit-learn y devuelve una matriz simétrica con las similaridades

In [11]:
from sklearn.metrics.pairwise import cosine_similarity
In [12]:
cos_sim = cosine_similarity(mat)

Primero vemos que tenga la forma adecuada.

In [13]:
cos_sim.shape, mat.shape
Out[13]:
((1682, 1682), (1682, 943))

Efectivamente vemos que es una matriz cuadrada con dimesión igual a la cantidad de películas.

El siguiente comando muestra las similitudes de la película 7 con los ítemes que ha etiquetado el usuario 543

In [14]:
cos_sim[7,np.nonzero(Y_train[:,543])[0].astype(int)]
Out[14]:
array([ 0.1547468 ,  0.16388722,  0.3168463 ,  0.29980869,  0.104056  ,
        0.33571144,  0.2524818 ,  0.21688506,  0.22799386,  0.15439215,
        0.15629818,  0.29778752,  0.16934434,  0.16299541,  0.14526255,
        0.11173868,  0.15195268,  0.15126273,  0.18080153,  0.09328838,
        0.20931129,  0.11593359,  0.17468158,  0.07875204,  0.027064  ])