Source code for recommenders.models.geoimc.geoimc_predict

# Copyright (c) Recommenders contributors.
# Licensed under the MIT License.

import numpy as np
from scipy.linalg import sqrtm

from recommenders.utils.python_utils import binarize as conv_binary


[docs]class PlainScalarProduct(object): """ Module that implements plain scalar product as the retrieval criterion """
[docs] def __init__(self, X, Y, **kwargs): """ Args: X: numpy matrix of shape (users, features) Y: numpy matrix of shape (items, features) """ self.X = X self.Y = Y
[docs] def sim(self, **kwargs): """Calculate the similarity score""" sim = self.X.dot(self.Y.T) return sim
[docs]class Inferer: """ Holds necessary (minimal) information needed for inference """
[docs] def __init__(self, method="dot", k=10, transformation=""): """Initialize parameters Args: method (str): The inference method. Currently 'dot' (Dot product) is supported. k (uint): `k` for 'topk' transformation. transformation (str): Transform the inferred values into a different scale. Currently 'mean' (Binarize the values using mean of inferred matrix as the threshold), 'topk' (Pick Top-K inferred values per row and assign them 1, setting rest of them to 0), '' (No transformation) are supported. """ self.method = self._get_method(method) self.k = k self.transformation = transformation
def _get_method(self, k): """Get the inferer method Args: k (str): The inferer name Returns: class: A class object implementing the inferer 'k' """ if k == "dot": method = PlainScalarProduct else: raise ValueError(f"{k} is unknown.") return method
[docs] def infer(self, dataPtr, W, **kwargs): """Main inference method Args: dataPtr (DataPtr): An object containing the X, Z features needed for inference W (iterable): An iterable containing the U, B, V parametrized matrices. """ if isinstance(dataPtr, list): a = dataPtr[0] b = dataPtr[1] else: a = dataPtr.get_entity("row").dot(W[0]).dot(sqrtm(W[1])) b = dataPtr.get_entity("col").dot(W[2]).dot(sqrtm(W[1])) sim_score = self.method(a, b).sim(**kwargs) if self.transformation == "mean": prediction = conv_binary(sim_score, sim_score.mean()) elif self.transformation == "topk": masked_sim_score = sim_score.copy() for i in range(sim_score.shape[0]): topKidx = np.argpartition(masked_sim_score[i], -self.k)[-self.k :] mask = np.ones(sim_score[i].size, dtype=bool) mask[topKidx] = False masked_sim_score[i][topKidx] = 1 masked_sim_score[i][mask] = 0 prediction = masked_sim_score else: prediction = sim_score return prediction