class_docstr: Class to set up the input, train and eval processes for a TF Ranking model.
  
  An example use case is provided below:
  
  ```python
  import tensorflow as tf
  import tensorflow_ranking as tfr
  
  context_feature_columns = {
    "c1": tf.feature_column.numeric_column("c1", shape=(1,))
  }
  example_feature_columns = {
    "e1": tf.feature_column.numeric_column("e1", shape=(1,))
  }
  
  hparams = dict(
        train_input_pattern="/path/to/train/files",
        eval_input_pattern="/path/to/eval/files",
        train_batch_size=8,
        eval_batch_size=8,
        checkpoint_secs=120,
        num_checkpoints=1000,
        num_train_steps=10000,
        num_eval_steps=100,
        loss="softmax_loss",
        list_size=10,
        listwise_inference=False,
        convert_labels_to_binary=False,
        model_dir="/path/to/your/model/directory")
  
  # See `tensorflow_ranking.estimator` for details about creating an estimator.
  estimator = <create your own estimator>
  
  ranking_pipeline = tfr.ext.pipeline.RankingPipeline(
        context_feature_columns,
        example_feature_columns,
        hparams,
        estimator=estimator,
        label_feature_name="relevance",
        label_feature_type=tf.int64)
  ranking_pipeline.train_and_eval()
  ```
  
  Note that you may:
    * pass `best_exporter_metric` and `best_exporter_metric_higher_better` for
      different model export strategies.
    * pass `dataset_reader` for reading different `tf.Dataset`s. We recommend
      using TFRecord files and storing your data in `tfr.data.ELWC` format.
  
  If you want to further customize certain `RankingPipeline` behaviors, please
  create a subclass of `RankingPipeline`, and overwrite related functions. We
  recommend only overwriting the following functions:
    * `_make_dataset` which builds the tf.dataset for a tf-ranking model.
    * `_make_serving_input_fn` that defines the input function for serving.
    * `_export_strategies` if you have more advanced needs for model exporting.
  
  For example, if you want to remove the best exporters, you may overwrite:
  
  ```python
  class NoBestExporterRankingPipeline(tfr.ext.pipeline.RankingPipeline):
    def _export_strategies(self, event_file_pattern):
      del event_file_pattern
      latest_exporter = tf.estimator.LatestExporter(
          "latest_model",
          serving_input_receiver_fn=self._make_serving_input_fn())
      return [latest_exporter]
  
  ranking_pipeline = NoBestExporterRankingPipeline(
        context_feature_columns,
        example_feature_columns,
        hparams
        estimator=estimator)
  ranking_pipeline.train_and_eval()
  ```
  
  if you want to customize your dataset reading behaviors, you may overwrite:
  
  ```python
  class CustomizedDatasetRankingPipeline(tfr.ext.pipeline.RankingPipeline):
    def _make_dataset(self,
                      batch_size,
                      list_size,
                      input_pattern,
                      randomize_input=True,
                      num_epochs=None):
      # Creates your own dataset, plese follow `tfr.data.build_ranking_dataset`.
      dataset = build_my_own_ranking_dataset(...)
      ...
      return dataset.map(self._features_and_labels)
  
  ranking_pipeline = CustomizedDatasetRankingPipeline(
        context_feature_columns,
        example_feature_columns,
        hparams
        estimator=estimator)
  ranking_pipeline.train_and_eval()
  ```
docstr: Makes a tuple of (train_spec, eval_on_eval_spec, eval_on_train_spec).
docstr_tok: ["Makes","a","tuple","of","(","train_spec",",","eval_on_eval_spec",",","eval_on_train_spec",")","."]
code: def _train_eval_specs(self):
      """Makes a tuple of (train_spec, eval_on_eval_spec, eval_on_train_spec)."""
      train_list_size = self._hparams.get("list_size")
      eval_list_size = (
          self._hparams.get("eval_list_size") or train_list_size
      )
      train_input_fn = self._make_input_fn(
          input_pattern=self._hparams.get("train_input_pattern"),
          batch_size=self._hparams.get("train_batch_size"),
          list_size=train_list_size,
      )
      eval_input_fn = self._make_input_fn(
          input_pattern=self._hparams.get("eval_input_pattern"),
          batch_size=self._hparams.get("eval_batch_size"),
          list_size=eval_list_size,
          randomize_input=False,
      )
  
      train_spec = tf_estimator.TrainSpec(  # pylint: disable=g-deprecated-tf-checker
          input_fn=train_input_fn,
          max_steps=self._hparams.get("num_train_steps"),
      )
      eval_on_train_spec = tf_estimator.EvalSpec(  # pylint: disable=g-deprecated-tf-checker
          name="on_train",
          input_fn=train_input_fn,
          steps=self._hparams.get("num_eval_steps"),
          throttle_secs=5,
      )
  
      eval_on_eval_spec = tf_estimator.EvalSpec(  # pylint: disable=g-deprecated-tf-checker
          name="on_eval",
          input_fn=eval_input_fn,
          steps=self._hparams.get("num_eval_steps"),
          exporters=self._export_strategies(
              event_file_pattern="eval_on_eval/*.tfevents.*",
              assets_extra=self._hparams.get("assets_extra"),
          ),
          throttle_secs=5,
      )
      return train_spec, eval_on_eval_spec, eval_on_train_spec
  
file_path: ranking/tensorflow_ranking/extension/pipeline.py
imports: import tensorflow
  from tensorflow import estimator
  from tensorflow.compat.v1 import estimator
  from tensorflow_ranking.python import data
label_desc: Use image node_id 9 for calling the RankingPipeline obj's underlying member method code with example usage: obj._train_eval_specs() and returns: train_spec,  eval_on_eval_spec,  eval_on_train_spec