class_docstr: Alternating Least Squares
  
  A Recommendation Model based off the algorithms described in the paper 'Collaborative
  Filtering for Implicit Feedback Datasets' with performance optimizations described in
  'Applications of the Conjugate Gradient Method for Implicit Feedback Collaborative
  Filtering.'
  
  Parameters
  ----------
  factors : int, optional
      The number of latent factors to compute
  regularization : float, optional
      The regularization factor to use
  alpha : float, optional
      The weight to give to positive examples.
  dtype : data-type, optional
      Specifies whether to generate 64 bit or 32 bit floating point factors
  use_native : bool, optional
      Use native extensions to speed up model fitting
  use_cg : bool, optional
      Use a faster Conjugate Gradient solver to calculate factors
  iterations : int, optional
      The number of ALS iterations to use when fitting data
  calculate_training_loss : bool, optional
      Whether to log out the training loss at each iteration
  num_threads : int, optional
      The number of threads to use for fitting the model and batch recommend calls.
      Specifying 0 means to default to the number of cores on the machine.
  random_state : int, numpy.random.RandomState, np.random.Generator or None, optional
      The random state for seeding the initial item and user factors.
      Default is None.
  
  Attributes
  ----------
  item_factors : ndarray
      Array of latent factors for each item in the training set
  user_factors : ndarray
      Array of latent factors for each user in the training set
docstr: Factorizes the user_items matrix.
  
  After calling this method, the members 'user_factors' and 'item_factors' will be
  initialized with a latent factor model of the input data.
  
  The user_items matrix does double duty here. It defines which items are liked by which
  users (P_ui in the original paper), as well as how much confidence we have that the user
  liked the item (C_ui).
  
  The negative items are implicitly defined: This code assumes that positive items in the
  user_items matrix means that the user liked the item. The negatives are left unset in this
  sparse matrix: the library will assume that means Piu = 0 and Ciu = 1 for all these items.
  Negative items can also be passed with a higher confidence value by passing a negative
  value, indicating that the user disliked the item.
  
  Parameters
  ----------
  user_items: csr_matrix
      Matrix of confidences for the liked items. This matrix should be a csr_matrix where
      the rows of the matrix are the users, the columns are the items liked that user,
      and the value is the confidence that the user liked the item.
  show_progress : bool, optional
      Whether to show a progress bar during fitting
  callback: Callable, optional
      Callable function on each epoch with such arguments as epoch, elapsed time and progress
docstr_tok: ["Factorizes","the","user_items","matrix",".","After","calling","this","method",",","the","members","'user_factors","'","and","'item_factors","'","will","be","initialized","with","a","latent","factor","model","of","the","input","data",".","The","user_items","matrix","does","double","duty","here",".","It","defines","which","items","are","liked","by","which","users","(","P_ui","in","the","original","paper",")",",","as","well","as","how","much","confidence","we","have","that","the","user","liked","the","item","(","C_ui",")",".","The","negative","items","are","implicitly","defined",":","This","code","assumes","that","positive","items","in","the","user_items","matrix","means","that","the","user","liked","the","item",".","The","negatives","are","left","unset","in","this","sparse","matrix",":","the","library","will","assume","that","means","Piu","=","0","and","Ciu","=","1","for","all","these","items",".","Negative","items","can","also","be","passed","with","a","higher","confidence","value","by","passing","a","negative","value",",","indicating","that","the","user","disliked","the","item",".","Parameters","--","--","--","--","--","user_items",":","csr_matrix","Matrix","of","confidences","for","the","liked","items",".","This","matrix","should","be","a","csr_matrix","where","the","rows","of","the","matrix","are","the","users",",","the","columns","are","the","items","liked","that","user",",","and","the","value","is","the","confidence","that","the","user","liked","the","item",".","show_progress",":","bool",",","optional","Whether","to","show","a","progress","bar","during","fitting","callback",":","Callable",",","optional","Callable","function","on","each","epoch","with","such","arguments","as","epoch",",","elapsed","time","and","progress"]
code: def fit(self, user_items, show_progress=True, callback=None):
      """Factorizes the user_items matrix.
  
      After calling this method, the members 'user_factors' and 'item_factors' will be
      initialized with a latent factor model of the input data.
  
      The user_items matrix does double duty here. It defines which items are liked by which
      users (P_ui in the original paper), as well as how much confidence we have that the user
      liked the item (C_ui).
  
      The negative items are implicitly defined: This code assumes that positive items in the
      user_items matrix means that the user liked the item. The negatives are left unset in this
      sparse matrix: the library will assume that means Piu = 0 and Ciu = 1 for all these items.
      Negative items can also be passed with a higher confidence value by passing a negative
      value, indicating that the user disliked the item.
  
      Parameters
      ----------
      user_items: csr_matrix
          Matrix of confidences for the liked items. This matrix should be a csr_matrix where
          the rows of the matrix are the users, the columns are the items liked that user,
          and the value is the confidence that the user liked the item.
      show_progress : bool, optional
          Whether to show a progress bar during fitting
      callback: Callable, optional
          Callable function on each epoch with such arguments as epoch, elapsed time and progress
      """
      # initialize the random state
      random_state = check_random_state(self.random_state)
  
      Cui = check_csr(user_items)
      if Cui.dtype != np.float32:
          Cui = Cui.astype(np.float32)
  
      # Give the positive examples more weight if asked for
      if self.alpha != 1.0:
          Cui = self.alpha * Cui
  
      s = time.time()
      Ciu = Cui.T.tocsr()
      log.debug("Calculated transpose in %.3fs", time.time() - s)
  
      items, users = Ciu.shape
  
      s = time.time()
      # Initialize the variables randomly if they haven't already been set
      if self.user_factors is None:
          self.user_factors = (
              random_state.random(
                  (users, self.factors), dtype=self.dtype
              )
              * 0.01
          )
      if self.item_factors is None:
          self.item_factors = (
              random_state.random(
                  (items, self.factors), dtype=self.dtype
              )
              * 0.01
          )
  
      log.debug("Initialized factors in %s", time.time() - s)
  
      # invalidate cached norms and squared factors
      self._item_norms = self._user_norms = None
      self._YtY = None
      self._XtX = None
      loss = None
  
      solver = self.solver
  
      log.debug("Running %i ALS iterations", self.iterations)
      with tqdm(
          total=self.iterations, disable=not show_progress
      ) as progress:
          # alternate between learning the user_factors from the item_factors and vice-versa
          for iteration in range(self.iterations):
              s = time.time()
              solver(
                  Cui,
                  self.user_factors,
                  self.item_factors,
                  self.regularization,
                  num_threads=self.num_threads,
              )
              solver(
                  Ciu,
                  self.item_factors,
                  self.user_factors,
                  self.regularization,
                  num_threads=self.num_threads,
              )
              progress.update(1)
  
              if self.calculate_training_loss:
                  loss = _als.calculate_loss(
                      Cui,
                      self.user_factors,
                      self.item_factors,
                      self.regularization,
                      num_threads=self.num_threads,
                  )
                  progress.set_postfix({"loss": loss})
  
                  if not show_progress:
                      log.info("loss %.4f", loss)
  
              # Backward compatibility
              if not callback:
                  callback = self.fit_callback
              if callback:
                  callback(iteration, time.time() - s, loss)
  
      if self.calculate_training_loss:
          log.info("Final training loss %.4f", loss)
  
      self._check_fit_errors()
  
imports: import functools
  import heapq
  import logging
  import time
  import numpy
  import scipy
  import scipy.sparse
  from tqdm.auto import tqdm
  from ..utils import check_blas_config, check_csr, check_random_state, nonzeros
  from .None import _als
  from .matrix_factorization_base import MatrixFactorizationBase
label_desc: Use image node_id 2 for calling the AlternatingLeastSquares obj's underlying member method code with example usage: obj.fit(user_items, show_progress, callback) without return types