Source code for irspack.recommenders.edlae

import gc

import numpy as np
from scipy import linalg

from ..definitions import InteractionMatrix
from ..optimization.parameter_range import LogUniformFloatRange, UniformFloatRange
from .base import BaseSimilarityRecommender, RecommenderConfig


class EDLAEConfig(RecommenderConfig):
    reg: float = 1.0
    dropout_p: float = 0.1


[docs] class EDLAERecommender(BaseSimilarityRecommender): """Implementation of EDLAE (Emphasized Denoising Linear Autoencoder). See: - `Autoencoders that don't overfit towards the Identity (NeurIPS 2020)` by Harald Steck (NetFlix) Args: X_train_all (Union[scipy.sparse.csr_matrix, scipy.sparse.csc_matrix]): Input interaction matrix. reg (float, optional): The L2 constant regularization parameter. Defaults to 1.0. dropout_p (float, optional): Probability of dropout. Defaults to 0.1 """ default_tune_range = [ LogUniformFloatRange("reg", 1, 1e4), UniformFloatRange("dropout_p", 0.0, 0.99), ] config_class = EDLAEConfig
[docs] def __init__( self, X_train_all: InteractionMatrix, reg: float = 1.0, dropout_p: float = 0.1 ): super(EDLAERecommender, self).__init__(X_train_all) self.reg = reg self.dropout_p = dropout_p
def _learn(self) -> None: X_train_all_f32 = self.X_train_all.astype(np.float32) P = X_train_all_f32.T.dot(X_train_all_f32) P_dense: np.ndarray = P.todense() del P q = 1 - self.dropout_p lamb = self.dropout_p / q * np.diag(P_dense) + self.reg P_dense[np.arange(self.n_items), np.arange(self.n_items)] += lamb gc.collect() P_dense = linalg.inv(P_dense, overwrite_a=True) gc.collect() diag_P_inv = 1 / np.diag(P_dense) P_dense *= -diag_P_inv[np.newaxis, :] range_ = np.arange(self.n_items) P_dense[range_, range_] = 0 self._W = P_dense