code: def rbp(recs, truth, k=None, patience=0.5, normalize=False):
      """
      Evaluate recommendations with rank-biased precision :cite:p:`rbp` with a
      patience parameter :math:`\\gamma`.
  
      If :math:`r_{ui} \\in \\{0, 1\\}` is binary implicit ratings, this is
      computed by:
  
      .. math::
          \\begin{align*}
          \\operatorname{RBP}_\\gamma(L, u) & =(1 - \\gamma) \\sum_i r_{ui} p^i
          \\end{align*}
  
      The original RBP metric depends on the idea that the rank-biased sum of
      binary relevance scores in an infinitely-long, perfectly-precise list has is
      :math:`1/(1 - \\gamma)`. However, in recommender evaluation, we usually have
      a small test set, so the maximum achievable RBP is significantly less, and
      is a function of the number of test items.  With ``normalize=True``, the RBP
      metric will be normalized by the maximum achievable with the provided test
      data.
  
      Parameters:
          recs: the recommendation list.
          truth: the user's truth data.
          k(int): the maximum recommendation list length.
          patience(float): the patience parameter :math:`\\gamma`, the probability
              that the user continues browsing at each point.
          normalize(bool): whether to normalize the RBP
              scores; if ``True``, divides the RBP score by the maximum achievable
              with the test data.
      """
      if k is not None and k <= len(recs):
          recs = recs.iloc[:k]
      else:
          k = len(recs)
  
      if "rank" not in recs.columns:
          recs = recs.assign(rank=np.arange(1, len(recs) + 1))
  
      if np.min(recs["rank"]) != 1:
          warnings.warn("rank should start with 1")
  
      nrel = len(truth)
      if nrel == 0:
          return None
  
      good = recs["item"].isin(truth.index)
      ranks = recs["rank"][good]
      disc = patience ** (ranks - 1)
      rbp = np.sum(disc)
      if normalize:
          # normalize by achievable RBP
          max = np.sum(patience ** np.arange(min(nrel, k)))
          # _log.info('rbp=%e, nrel=%d, eff=%d, max=%e', rbp, nrel, min(nrel, k), max)
          return rbp / max
      else:
          # normal RBP normalization
          return rbp * (1 - patience)
  
file_path: lkpy/lenskit/metrics/topn.py
imports: import logging
  import warnings
  import numpy
  import pandas
label_desc: Use image node_id 15 for calling a global function with example usage: rbp(recs, truth, k, patience, normalize) and returns: None, unknown, unknown