class_docstr: A basic collaborative filtering algorithm, taking into account the mean
  ratings of each user.
  
  The prediction :math:`\hat{r}_{ui}` is set as:
  
  .. math::
      \hat{r}_{ui} = \mu_u + \frac{ \sum\limits_{v \in N^k_i(u)}
      \text{sim}(u, v) \cdot (r_{vi} - \mu_v)} {\sum\limits_{v \in
      N^k_i(u)} \text{sim}(u, v)}
  
  or
  
  .. math::
      \hat{r}_{ui} = \mu_i + \frac{ \sum\limits_{j \in N^k_u(i)}
      \text{sim}(i, j) \cdot (r_{uj} - \mu_j)} {\sum\limits_{j \in
      N^k_u(i)} \text{sim}(i, j)}
  
  depending on the ``user_based`` field of the ``sim_options`` parameter.
  
  
  Args:
      k(int): The (max) number of neighbors to take into account for
          aggregation (see :ref:`this note <actual_k_note>`). Default is
          ``40``.
      min_k(int): The minimum number of neighbors to take into account for
          aggregation. If there are not enough neighbors, the neighbor
          aggregation is set to zero (so the prediction ends up being
          equivalent to the mean :math:`\mu_u` or :math:`\mu_i`). Default is
          ``1``.
      sim_options(dict): A dictionary of options for the similarity
          measure. See :ref:`similarity_measures_configuration` for accepted
          options.
      verbose(bool): Whether to print trace messages of bias estimation,
          similarity, etc.  Default is True.
class_docstr_tok: ["A","basic","collaborative","filtering","algorithm",",","taking","into","account","the","mean","ratings","of","each","user",".","The","prediction",":","math",":","`","\\hat","{","r","}","_","{","ui","}","`","is","set","as",":","..","math",":",":","\\hat","{","r","}","_","{","ui","}","=","\\mu_u","+","\\frac","{","\\sum\\limits_","{","v","\\in","N^k_i","(","u",")","}","\\text","{","sim","}","(","u",",","v",")","\\cdot","(","r_","{","vi","}","-","\\mu_v",")","}","{","\\sum\\limits_","{","v","\\in","N^k_i","(","u",")","}","\\text","{","sim","}","(","u",",","v",")","}","or","..","math",":",":","\\hat","{","r","}","_","{","ui","}","=","\\mu_i","+","\\frac","{","\\sum\\limits_","{","j","\\in","N^k_u","(","i",")","}","\\text","{","sim","}","(","i",",","j",")","\\cdot","(","r_","{","uj","}","-","\\mu_j",")","}","{","\\sum\\limits_","{","j","\\in","N^k_u","(","i",")","}","\\text","{","sim","}","(","i",",","j",")","}","depending","on","the","``","user_based","``","field","of","the","``","sim_options","``","parameter",".","Args",":","k","(","int",")",":","The","(","max",")","number","of","neighbors","to","take","into","account","for","aggregation","(","see",":","ref",":","`","this","note","<","actual_k_note",">","`",")",".","Default","is","``","40","``",".","min_k","(","int",")",":","The","minimum","number","of","neighbors","to","take","into","account","for","aggregation",".","If","there","are","not","enough","neighbors",",","the","neighbor","aggregation","is","set","to","zero","(","so","the","prediction","ends","up","being","equivalent","to","the","mean",":","math",":","`","\\mu_u","`","or",":","math",":","`","\\mu_i","`",")",".","Default","is","``","1","``",".","sim_options","(","dict",")",":","A","dictionary","of","options","for","the","similarity","measure",".","See",":","ref",":","`","similarity_measures_configuration","`","for","accepted","options",".","verbose","(","bool",")",":","Whether","to","print","trace","messages","of","bias","estimation",",","similarity",",","etc",".","Default","is","True","."]
code: def fit(self, trainset):
      SymmetricAlgo.fit(self, trainset)
      self.sim = self.compute_similarities()
  
      self.means = np.zeros(self.n_x)
      for x, ratings in self.xr.items():
          self.means[x] = np.mean([r for (_, r) in ratings])
  
      return self
  
imports: import heapq
  import numpy
  from .algo_base import AlgoBase
  from .predictions import PredictionImpossible
label_desc: Use image node_id 2 for calling the KNNWithMeans obj's underlying member method code with example usage: obj.fit(trainset) and returns: self