4
\$\begingroup\$

I used and modified a matrix factorization function for a system recommender from quuxlabs.com. It works well for small sized input but when we get to large matrix it takes too much time. I was wondering if you had any idea to code it better to optimize the time it would take.

Here R is the rating matrix of a user with an item. 0 means that nothing has been predicted yet, the one we have to predict. K is the number of extrab features. P and Q are scores matrix on latent features that would help predict R as a whole.

import numpy

def matrix_factorization(R, P, Q, K, steps=5000, alpha=0.0002, beta=0.02):
    Q = Q.T
    for step in xrange(steps):
        for i in xrange(len(R)):
            for j in xrange(len(R[i])):    
                if R[i][j] > 0:
                    try:
                        eij = R[i][j] - numpy.dot(P[i,:],Q[:,j])
                    except IndexError:
                        print("Oops!  i = ",i,"and len(P) = ",len(P))
                        P[i,:]
                        break
                    for k in xrange(K):    
                        P[i][k] = P[i][k] + alpha * (2 * eij * Q[k][j] - beta * P[i][k])    
                        Q[k][j] = Q[k][j] + alpha * (2 * eij * P[i][k] - beta * Q[k][j])    
        eR = numpy.dot(P,Q)    
        e = 0    
        for i in xrange(len(R)):    
            for j in xrange(len(R[i])):    
                if R[i][j] > 0:                        
                    e = e + pow(R[i][j] - numpy.dot(P[i,:],Q[:,j]), 2)
                    for k in xrange(K):
                        e = e + (beta/2) * (pow(P[i][k],2) + pow(Q[k][j],2))    
        if e < 0.001:    
            break    
    return P, Q.T

It works well with the following input :

R = [
     [5,3,0,1],
     [4,0,0,1],
     [1,1,0,5],
     [1,0,0,4],
     [0,1,5,4],
    ]

R = numpy.array(R)

N = len(R)
M = len(R[0])
K = 2

P = numpy.random.rand(N,K)
Q = numpy.random.rand(M,K)
nP, nQ = matrix_factorization(R, P, Q, K)

nR = numpy.dot(nP, nQ.T)

Yet, on real big matrix, the function took so long that I eventually cancelled it because I got tired of waiting.

\$\endgroup\$
  • \$\begingroup\$ Did you consider using sklearn.decomposition? \$\endgroup\$ – Gareth Rees Jun 13 '17 at 9:38
  • \$\begingroup\$ @GarethRees No ! I'm looking on it right at the moment, especially on the Gradient NMF method. I understand these functions are faster. I am doing some reasearch to know how to use them. \$\endgroup\$ – IggyPass Jun 13 '17 at 10:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.