Source code for elliot.recommender.latent_factor_models.WRMF.wrmf_model

"""
Module description:

"""

__version__ = '0.3.1'
__author__ = 'Vito Walter Anelli, Claudio Pomo'
__email__ = 'vitowalter.anelli@poliba.it, claudio.pomo@poliba.it'

import pickle

import numpy as np
from scipy import sparse as sp
from scipy.sparse.linalg import spsolve


[docs]class WRMFModel(object): """ Simple Matrix Factorization class """ def __init__(self, factors, data, random, alpha, reg): self._data = data self.random = random self.C = alpha * self._data.sp_i_train self.train_dict = self._data.train_dict self.user_num, self.item_num = self._data.num_users, self._data.num_items self.X = sp.csr_matrix(self.random.normal(scale=0.01, size=(self.user_num, factors))) self.Y = sp.csr_matrix(self.random.normal(scale=0.01, size=(self.item_num, factors))) self.X_eye = sp.eye(self.user_num) self.Y_eye = sp.eye(self.item_num) self.lambda_eye = reg * sp.eye(factors) self.user_vec, self.item_vec, self.pred_mat = None, None, None
[docs] def train_step(self): yTy = self.Y.T.dot(self.Y) xTx = self.X.T.dot(self.X) for u in range(self.user_num): Cu = self.C[u, :].toarray() Pu = Cu.copy() Pu[Pu != 0] = 1 CuI = sp.diags(Cu, [0]) yTCuIY = self.Y.T.dot(CuI).dot(self.Y) yTCuPu = self.Y.T.dot(CuI + self.Y_eye).dot(Pu.T) self.X[u] = spsolve(yTy + yTCuIY + self.lambda_eye, yTCuPu) for i in range(self.item_num): Ci = self.C[:, i].T.toarray() Pi = Ci.copy() Pi[Pi != 0] = 1 CiI = sp.diags(Ci, [0]) xTCiIX = self.X.T.dot(CiI).dot(self.X) xTCiPi = self.X.T.dot(CiI + self.X_eye).dot(Pi.T) self.Y[i] = spsolve(xTx + xTCiIX + self.lambda_eye, xTCiPi) self.pred_mat = self.X.dot(self.Y.T).A
[docs] def predict(self, user, item): return self.pred_mat[self._data.public_users[user], self._data.public_items[item]]
[docs] def get_user_recs(self, user, mask, k=100): user_mask = mask[self._data.public_users[user]] predictions = {i: self.predict(user, i) for i in self._data.items if user_mask[self._data.public_items[i]]} indices, values = zip(*predictions.items()) indices = np.array(indices) values = np.array(values) local_k = min(k, len(values)) partially_ordered_preds_indices = np.argpartition(values, -local_k)[-local_k:] real_values = values[partially_ordered_preds_indices] real_indices = indices[partially_ordered_preds_indices] local_top_k = real_values.argsort()[::-1] return [(real_indices[item], real_values[item]) for item in local_top_k]
[docs] def get_model_state(self): saving_dict = {} saving_dict['pred_mat'] = self.pred_mat saving_dict['X'] = self.X saving_dict['Y'] = self.Y saving_dict['C'] = self.C return saving_dict
[docs] def set_model_state(self, saving_dict): self.pred_mat = saving_dict['pred_mat'] self.X = saving_dict['X'] self.Y = saving_dict['Y'] self.C = saving_dict['C']
[docs] def load_weights(self, path): with open(path, "rb") as f: self.set_model_state(pickle.load(f))
[docs] def save_weights(self, path): with open(path, "wb") as f: pickle.dump(self.get_model_state(), f)