I’m trying to implement some matrix factorization models for recommender systems where usually there is a sparse matrix X that need to be factorized by the (matrix) product two lower dimensional matrices, say A and B, where the full product of A and B is too large to fit in memory and only want to extract the indices that match to the sparse matrix X.
I was wondering what’s the efficient approach to do this when passing in minibatches of the matrix X as triplets (i, j, value) , i.e. an approach that avoids putting the whole product of the matrices in memory, and ideally also avoids creating a computational graph too large to fit in memory.
Here’s a simplified version of the model I’m trying to build:
# X is some pandas dataframe with columns (row_ind, col_ind, val)
Xbatch=pm.Minibatch(X, batch_size)
with pm.Model():
A=pm.Normal('A',mu=0,sd=.5, shape=(nrows, latent_dim), testval=Ainit)
B=pm.Normal('B',mu=0,sd=.5, shape=(ncols, latent_dim), testval=Binit)
Xhat= ???
Xvar = pm.Normal('Xvar',mu=Xhat, sd=1.0, observed=Xbatch[:,2])
approx = pm.fit(method='advi')
If I try:
Xhat = theano.tensor.dot(A, B.T)[(Xbatch[:,0], Xbatch[:,1)]
It tries to compute the whole matrix (thus doesn’t fit in memory), whereas if I try:
Xrow_ind = pm.Minibatch(X.row_ind)
Xcol_ind = pm.Minibatch(X.col_ind)
Xval = pm.Minibatch(X.val)
...
Xhat = theano.tensor.dot(A[Xrow_ind], B[Xcol_ind].T)
...
Then it throws me:
AdvancedSubtensor1.grad illegally returned an integer-valued variable
Whereas if I try it like:
Xhat=theano.tensor.dot(A.compress(Xrow_ind, axis=0),
B.compress(Xcol_ind, axis=0).T)
I get an ‘Index out of bounds’ error.
What would be the proper way to do it?