code: def ranking_eval(
      model,
      metrics,
      train_set,
      test_set,
      val_set=None,
      rating_threshold=1.0,
      exclude_unknowns=True,
      verbose=False,
  ):
      """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.
  
      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 [], []
  
      max_k = max(m.k for m in metrics)
  
      avg_results = []
      user_results = [{} for _ in enumerate(metrics)]
  
      test_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(
          test_user_indices,
          desc="Ranking",
          disable=not verbose,
          miniters=100,
      ):
          test_pos_items = pos_items(test_mat.getrow(user_idx))
          if len(test_pos_items) == 0:
              continue
  
          # binary mask for ground-truth positive items
          u_gt_pos_mask = np.zeros(test_set.num_items, dtype="int")
          u_gt_pos_mask[test_pos_items] = 1
  
          val_pos_items = (
              []
              if val_mat is None
              else pos_items(val_mat.getrow(user_idx))
          )
          train_pos_items = (
              pos_items(train_mat.getrow(user_idx))
              if user_idx < train_mat.shape[0]
              else []
          )
  
          # binary mask for ground-truth negative items, removing all positive items
          u_gt_neg_mask = np.ones(test_set.num_items, dtype="int")
          u_gt_neg_mask[
              test_pos_items + val_pos_items + train_pos_items
          ] = 0
  
          # filter items being considered for evaluation
          if exclude_unknowns:
              u_gt_pos_mask = u_gt_pos_mask[: train_set.num_items]
              u_gt_neg_mask = u_gt_neg_mask[: train_set.num_items]
  
          item_indices = np.nonzero(u_gt_pos_mask + u_gt_neg_mask)[0]
          u_gt_pos_items = np.nonzero(u_gt_pos_mask)[0]
          u_gt_neg_items = np.nonzero(u_gt_neg_mask)[0]
  
          item_rank, item_scores = model.rank(
              user_idx=user_idx, item_indices=item_indices, k=max_k
          )
  
          for i, mt in enumerate(metrics):
              mt_score = mt.compute(
                  gt_pos=u_gt_pos_items,
                  gt_neg=u_gt_neg_items,
                  pd_rank=item_rank,
                  pd_scores=item_scores,
                  item_indices=item_indices,
              )
              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
  
imports: from collections import OrderedDict
  import time
  import numpy
  from scipy.sparse import csr_matrix
  from tqdm.auto import tqdm
  from ..data import FeatureModality
  from ..data import TextModality, ReviewModality
  from ..data import ImageModality
  from ..data import GraphModality
  from ..data import SentimentModality
  from ..data import Dataset
  from ..metrics import RatingMetric
  from ..metrics import RankingMetric
  from ..experiment.result import Result
  from ..utils import get_rng
label_desc: Use image node_id 2 for calling a global function with example usage: ranking_eval(model, metrics, train_set, test_set, val_set, rating_threshold, exclude_unknowns, verbose) and returns: avg_results,  user_results, list,  list, unknown