class_docstr: A basic collaborative filtering algorithm.
  
  The prediction :math:`\hat{r}_{ui}` is set as:
  
  .. math::
      \hat{r}_{ui} = \frac{
      \sum\limits_{v \in N^k_i(u)} \text{sim}(u, v) \cdot r_{vi}}
      {\sum\limits_{v \in N^k_i(u)} \text{sim}(u, v)}
  
  or
  
  .. math::
      \hat{r}_{ui} = \frac{
      \sum\limits_{j \in N^k_u(i)} \text{sim}(i, j) \cdot r_{uj}}
      {\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 prediction is
          set to the global mean of all ratings. 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",".","The","prediction",":","math",":","`","\\hat","{","r","}","_","{","ui","}","`","is","set","as",":","..","math",":",":","\\hat","{","r","}","_","{","ui","}","=","\\frac","{","\\sum\\limits_","{","v","\\in","N^k_i","(","u",")","}","\\text","{","sim","}","(","u",",","v",")","\\cdot","r_","{","vi","}","}","{","\\sum\\limits_","{","v","\\in","N^k_i","(","u",")","}","\\text","{","sim","}","(","u",",","v",")","}","or","..","math",":",":","\\hat","{","r","}","_","{","ui","}","=","\\frac","{","\\sum\\limits_","{","j","\\in","N^k_u","(","i",")","}","\\text","{","sim","}","(","i",",","j",")","\\cdot","r_","{","uj","}","}","{","\\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","prediction","is","set","to","the","global","mean","of","all","ratings",".","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 estimate(self, u, i):
      if not (
          self.trainset.knows_user(u) and self.trainset.knows_item(i)
      ):
          raise PredictionImpossible("User and/or item is unknown.")
  
      x, y = self.switch(u, i)
  
      neighbors = [(self.sim[x, x2], r) for (x2, r) in self.yr[y]]
      k_neighbors = heapq.nlargest(
          self.k, neighbors, key=lambda t: t[0]
      )
  
      # compute weighted average
      sum_sim = sum_ratings = actual_k = 0
      for sim, r in k_neighbors:
          if sim > 0:
              sum_sim += sim
              sum_ratings += sim * r
              actual_k += 1
  
      if actual_k < self.min_k:
          raise PredictionImpossible("Not enough neighbors.")
  
      est = sum_ratings / sum_sim
  
      details = {"actual_k": actual_k}
      return est, details
  
imports: import heapq
  import numpy
  from .algo_base import AlgoBase
  from .predictions import PredictionImpossible
label_desc: Use image node_id 3 for calling the KNNBasic obj's underlying member method code with example usage: obj.estimate(u, i) and returns: est,  details