code: def ranking_eval(
      model,
      metrics,
      train_set,
      test_set,
      val_set=None,
      rating_threshold=1.0,
      exclude_unknowns=True,
      verbose=False,
      props=None,
  ):
      """Evaluate model on provided ranking metrics.
  
      Parameters
      ----------
      model: :obj:`cornac.models.Recommender`, required
          Recommender model to be evaluated.
  
      metrics: :obj:`iterable`, required
          List of rating metrics :obj:`cornac.metrics.RankingMetric`.
  
      train_set: :obj:`cornac.data.Dataset`, required
          Dataset to be used for model training. This will be used to exclude
          observations already appeared during training.
  
      test_set: :obj:`cornac.data.Dataset`, required
          Dataset to be used for evaluation.
  
      val_set: :obj:`cornac.data.Dataset`, optional, default: None
          Dataset to be used for model selection. This will be used to exclude
          observations already appeared during validation.
  
      rating_threshold: float, optional, default: 1.0
          The threshold to convert ratings into positive or negative feedback.
  
      exclude_unknowns: bool, optional, default: True
          Ignore unknown users and items during evaluation.
  
      verbose: bool, optional, default: False
          Output evaluation progress.
  
      props: dictionary, optional, default: None
          items propensity scores
  
      Returns
      -------
      res: (List, List)
          Tuple of two lists:
           - average result for each of the metrics
           - average result per user for each of the metrics
      """
  
      if len(metrics) == 0:
          return [], []
  
      avg_results = []
      user_results = [{} for _ in enumerate(metrics)]
  
      gt_mat = test_set.csr_matrix
      train_mat = train_set.csr_matrix
      val_mat = None if val_set is None else val_set.csr_matrix
  
      def pos_items(csr_row):
          return [
              item_idx
              for (item_idx, rating) in zip(
                  csr_row.indices, csr_row.data
              )
              if rating >= rating_threshold
          ]
  
      test_user_indices = set(test_set.uir_tuple[0])
      for user_idx in tqdm.tqdm(
          test_user_indices, disable=not verbose, miniters=100
      ):
          test_pos_items = pos_items(gt_mat.getrow(user_idx))
          if len(test_pos_items) == 0:
              continue
  
          u_gt_pos = np.zeros(test_set.num_items, dtype="float")
          u_gt_pos[test_pos_items] = 1
  
          val_pos_items = (
              []
              if val_mat is None
              else pos_items(val_mat.getrow(user_idx))
          )
          train_pos_items = (
              []
              if train_set.is_unk_user(user_idx)
              else pos_items(train_mat.getrow(user_idx))
          )
  
          u_gt_neg = np.ones(test_set.num_items, dtype="int")
          u_gt_neg[test_pos_items + val_pos_items + train_pos_items] = 0
  
          item_indices = (
              None
              if exclude_unknowns
              else np.arange(test_set.num_items)
          )
          item_rank, item_scores = model.rank(user_idx, item_indices)
  
          total_pi = 0.0
          if props is not None:
              for idx, e in enumerate(u_gt_pos):
                  if e > 0 and props[str(idx)] > 0:
                      u_gt_pos[idx] /= props[str(idx)]
                      total_pi += 1 / props[str(idx)]
  
          for i, mt in enumerate(metrics):
              mt_score = mt.compute(
                  gt_pos=u_gt_pos,
                  gt_neg=u_gt_neg,
                  pd_rank=item_rank,
                  pd_scores=item_scores,
              )
  
              user_results[i][user_idx] = mt_score
  
      # avg results of ranking metrics
      for i, mt in enumerate(metrics):
          avg_results.append(
              sum(user_results[i].values()) / len(user_results[i])
          )
  
      return avg_results, user_results
  
file_path: cornac/cornac/eval_methods/propensity_stratified_evaluation.py
imports: import time
  from collections import defaultdict
  from collections import OrderedDict
  import powerlaw
  import numpy
  import tqdm.auto
  from ..utils.common import safe_indexing
  from ..data import Dataset
  from .base_method import BaseMethod, rating_eval
  from .ratio_split import RatioSplit
  from ..experiment.result import Result, PSTResult
label_desc: Use image node_id 1 for calling a global function with example usage: ranking_eval(model, metrics, train_set, test_set, val_set, rating_threshold, exclude_unknowns, verbose, props) and returns: avg_results,  user_results, list,  list, unknown