In [1]:
    
import numpy as np
import pandas as pd
from matplotlib import pylab as plt
%matplotlib inline
    
In [183]:
    
user_movie_ratings = [
    (1, 1, 5),
    (1, 2, 4),
    (1, 5, 1),
    (2, 1, 5),
    (2, 4, 1),
    (3, 5, 1),
    (3, 2, 4),
    (4, 3, 2),
    (4, 1, 4),
    (4, 2, 5),
    (5, 1, 1),
    (5, 5, 5),
    (6, 2, 2),
    (6, 4, 4),
    (6, 3, 1),
    (7, 5, 4),
    (7, 4, 5),
    (8, 2, 1),
    (8, 5, 4),
    (9, 4, 4),
    (9, 5, 5),
    (9, 2, 1),
    (10, 2, 1),
    (10, 1, 1),
    (10, 4, 5),
    (11, 1, 5),
    (11, 2, 4),
    (11, 5, 1),
    (12, 1, 5),
    (12, 3, 1),
    (13, 1, 4),
    (13, 2, 5),
    (13, 4, 1),
    (14, 1, 5),
    (14, 2, 5),
    (14, 3, 1),
    (15, 2, 5),
    (15, 3, 1),
    (15, 5, 1),
    (16, 1, 5),
    (17, 1, 4),
    (17, 2, 5),
    (17, 4, 1),
    (17, 5, 1),
    (18, 1, 5),
    (18, 5, 1),
    (18, 4, 1),
    (19, 5, 1),
]
user_max_id = np.amax(user_movie_ratings, axis=0)[0]
movie_max_id = np.amax(user_movie_ratings, axis=1)[0]
A = np.zeros((movie_max_id, user_max_id))
for i in user_movie_ratings:
    A[i[1] - 1][i[0] - 1] = i[2]
A
    
    Out[183]:
In [190]:
    
RANK = 5
U = np.random.rand(movie_max_id, RANK)
M = np.random.rand(RANK, user_max_id)
W = np.copy(A)
W[W!=0] = 1
W
    
    Out[190]:
In [191]:
    
eta = 0.02
for i in range(40):
    error = np.sum(np.power(W * (A - U.dot(M)), 2))
    print(error)
    dU = -(W * (A - U.dot(M))).dot(M.T)
    U = U - eta * dU
    dM = -U.T.dot(W * (A - U.dot(M)))
    M = M - eta * dM
    
    
In [192]:
    
i = 15
print(A[:,i])
print(U.dot(M).round(1)[:,i])
    
    
In [ ]:
    
    
In [ ]: