class_docstr: Speeds up inference calls to MatrixFactorization models by using
  `Faiss <https://github.com/facebookresearch/faiss>`_ to create approximate nearest neighbours
  indices of the latent factors.
  
  Parameters
  ----------
  model : MatrixFactorizationBase
      A matrix factorization model to use for the factors
  nlist : int, optional
      The number of cells to use when building the Faiss index.
  nprobe : int, optional
      The number of cells to visit to perform a search.
  use_gpu : bool, optional
      Whether or not to enable run Faiss on the GPU. Requires faiss to have been
      built with GPU support.
  approximate_similar_items : bool, optional
      whether or not to build an Faiss index for computing similar_items
  approximate_recommend : bool, optional
      whether or not to build an Faiss index for the recommend call
  
  Attributes
  ----------
  similar_items_index : faiss.IndexIVFFlat
      Faiss index for looking up similar items in the cosine space formed by the latent
      item_factors
  
  recommend_index : faiss.IndexIVFFlat
      Faiss index for looking up similar items in the inner product space formed by the latent
      item_factors
class_docstr_tok: ["Speeds","up","inference","calls","to","MatrixFactorization","models","by","using","`","Faiss","<","https",":","\/\/github.com\/facebookresearch\/faiss",">","`","_","to","create","approximate","nearest","neighbours","indices","of","the","latent","factors",".","Parameters","--","--","--","--","--","model",":","MatrixFactorizationBase","A","matrix","factorization","model","to","use","for","the","factors","nlist",":","int",",","optional","The","number","of","cells","to","use","when","building","the","Faiss","index",".","nprobe",":","int",",","optional","The","number","of","cells","to","visit","to","perform","a","search",".","use_gpu",":","bool",",","optional","Whether","or","not","to","enable","run","Faiss","on","the","GPU",".","Requires","faiss","to","have","been","built","with","GPU","support",".","approximate_similar_items",":","bool",",","optional","whether","or","not","to","build","an","Faiss","index","for","computing","similar_items","approximate_recommend",":","bool",",","optional","whether","or","not","to","build","an","Faiss","index","for","the","recommend","call","Attributes","--","--","--","--","--","similar_items_index",":","faiss.IndexIVFFlat","Faiss","index","for","looking","up","similar","items","in","the","cosine","space","formed","by","the","latent","item_factors","recommend_index",":","faiss.IndexIVFFlat","Faiss","index","for","looking","up","similar","items","in","the","inner","product","space","formed","by","the","latent","item_factors"]
code: def recommend(
      self,
      userid,
      user_items,
      N=10,
      filter_already_liked_items=True,
      filter_items=None,
      recalculate_user=False,
      items=None,
  ):
      if (
          filter_already_liked_items or recalculate_user
      ) and not isinstance(user_items, csr_matrix):
          raise ValueError("user_items needs to be a CSR sparse matrix")
  
      if items is not None and self.approximate_recommend:
          raise NotImplementedError(
              "using a 'items' list with ANN search isn't supported"
          )
  
      # batch computation is tricky with filter_already_liked_items (requires querying a
      # different number of rows per user). Instead just fallback to a faiss query per user
      if filter_already_liked_items and not np.isscalar(userid):
          return _batch_call(
              self.recommend,
              userid,
              user_items=user_items,
              N=N,
              filter_already_liked_items=filter_already_liked_items,
              filter_items=filter_items,
              recalculate_user=recalculate_user,
              items=items,
          )
  
      if not self.approximate_recommend:
          warnings.warning(
              "Calling recommend on a FaissModel with approximate_recommend=False"
          )
          return self.model.recommend(
              userid,
              user_items,
              N=N,
              filter_already_liked_items=filter_already_liked_items,
              filter_items=filter_items,
              recalculate_user=recalculate_user,
              items=items,
          )
  
      # support recalculate_user if possible (TODO: come back to this since its a bit of a hack)
      if hasattr(self.model, "+_user_factor"):
          user = self.model._user_factor(
              userid, user_items, recalculate_user
          )  # pylint: disable=protected-access
      elif recalculate_user:
          raise NotImplementedError(
              f"recalculate_user isn't supported with {self.model}"
          )
      else:
          user = self.model.user_factors[userid]
          if implicit.gpu.HAS_CUDA and isinstance(
              user, implicit.gpu.Matrix
          ):
              user = user.to_numpy()
  
      # calculate the top N items, removing the users own liked items from
      # the results
      count = N
      if filter_items:
          count += len(filter_items)
          filter_items = np.array(filter_items)
  
      if filter_already_liked_items:
          user_likes = user_items[0].indices
          filter_items = (
              np.append(filter_items, user_likes)
              if filter_items is not None
              else user_likes
          )
          count += len(user_likes)
  
      # the GPU variant of faiss doesn't support returning more than 1024 results.
      # fall back to the exact match when this happens
      if self.use_gpu and count >= 1024:
          return self.model.recommend(
              userid,
              user_items,
              N=N,
              filter_already_liked_items=filter_already_liked_items,
              filter_items=filter_items,
              recalculate_user=recalculate_user,
              items=items,
          )
  
      if np.isscalar(userid):
          query = user.reshape(1, -1).astype("float32")
      else:
          query = user.astype("float32")
  
      scores, ids = self.recommend_index.search(query, count)
  
      if np.isscalar(userid):
          ids, scores = ids[0], scores[0]
  
      if filter_items is not None:
          ids, scores = _filter_items_from_results(
              userid, ids, scores, filter_items, N
          )
  
      return ids, scores
  
file_path: implicit/implicit/ann/faiss.py
imports: import logging
  import warnings
  import faiss
  import numpy
  from scipy.sparse import csr_matrix
  import implicit.gpu
  from implicit.recommender_base import RecommenderBase
  from implicit.utils import _batch_call, _filter_items_from_results
label_desc: Use image node_id 4 for calling the FaissModel obj's underlying member method code with example usage: obj.recommend(userid, user_items, N, filter_already_liked_items, filter_items, recalculate_user, items) and returns: ids,  scores, _batch_call, self, self