code: def _fit(self, df):
      backend = self._get_or_create_backend()
      with util.prepare_data(
          backend.num_processes(),
          self.getStore(),
          df,
          label_columns=self.getLabelCols(),
          feature_columns=self.getFeatureCols(),
          validation=self.getValidation(),
          sample_weight_col=self.getSampleWeightCol(),
          compress_sparse=self.getCompressSparseCols(),
          partitions_per_process=self.getPartitionsPerProcess(),
          verbose=self.getVerbose(),
      ) as dataset_idx:
          (
              train_rows,
              val_rows,
              metadata,
              avg_row_size,
          ) = util.get_dataset_properties(dataset_idx)
          self._check_metadata_compatibility(metadata)
          return self._fit_on_prepared_data(
              backend,
              train_rows,
              val_rows,
              metadata,
              avg_row_size,
              dataset_idx,
          )
  
file_path: horovod/horovod/spark/common/estimator.py
imports: import horovod.spark.common._namedtuple_fix
  from pyspark.ml import Estimator, Model
  from horovod.spark.common import util
  from horovod.spark.common.backend import SparkBackend
  from horovod.spark.common.params import EstimatorParams, ModelParams
label_desc: Use image node_id 4 for calling the HorovodEstimator obj's underlying member method code with example usage: obj._fit(df) and returns: self