code: def _ndcg_at_k_eval_fn(k):
      if not (isinstance(k, int) and k > 0):
          _logger.warning(
              f"Cannot calculate 'ndcg_at_k' for invalid parameter 'k'. "
              f"'k' should be a positive integer; found: {k}. Skipping metric logging."
          )
          return noop
  
      def _fn(predictions, targets):
          from sklearn.metrics import ndcg_score
  
          if not _validate_list_str_data(
              predictions, "ndcg_at_k", predictions_col_specifier
          ) or not _validate_list_str_data(
              targets, "ndcg_at_k", targets_col_specifier
          ):
              return
  
          scores = []
          for ground_truth, retrieved in zip(targets, predictions):
              # 1. If no ground truth doc IDs are provided and no documents are retrieved,
              # the score is 1.
              if len(retrieved) == 0 and len(ground_truth) == 0:
                  scores.append(1)  # no error is made
                  continue
              # 2. If no ground truth doc IDs are provided and documents are retrieved,
              # the score is 0.
              # 3. If ground truth doc IDs are provided and no documents are retrieved,
              # the score is 0.
              if len(retrieved) == 0 or len(ground_truth) == 0:
                  scores.append(0)
                  continue
  
              # only include the top k retrieved chunks
              y_score, y_true = _prepare_row_for_ndcg(
                  retrieved[:k], ground_truth
              )
              score = ndcg_score(
                  y_true,
                  y_score,
                  k=len(retrieved[:k]),
                  ignore_ties=True,
              )
              scores.append(score)
  
          return MetricValue(
              scores=scores,
              aggregate_results=standard_aggregations(scores),
          )
  
      return _fn
  
imports: import functools
  import logging
  import os
  import numpy
  from mlflow.metrics.base import MetricValue, standard_aggregations
label_desc: Use image node_id 26 for calling a global function with example usage: _ndcg_at_k_eval_fn(k) and returns: _fn, noop, MetricValue