class_docstr: Operations related to the Lagrangian.
  
  Parameters
  ----------
  X : {numpy.ndarray, pandas.DataFrame}
      the training features
  sensitive_features : {numpy.ndarray, pandas.Series, pandas.DataFrame, list}
      the sensitive features to use for constraints
  y : {numpy.ndarray, pandas.Series, pandas.DataFrame, list}
      the training labels
  estimator :
      the estimator to fit in every iteration of :meth:`best_h` using a
      :meth:`fit` method with arguments `X`, `y`, and `sample_weight`
  constraints : fairlearn.reductions.Moment
      Object describing the fairness constraints. This provides the reweighting
      and relabelling.
  objective : fairlearn.reductions.Moment
      Object describing the optimization objective. The default is :code:`ErrorRate()` for
      binary classification and :code:`MeanLoss(...)` for regression.
  B : float
      bound on the L1-norm of the lambda vector
  opt_lambda : bool
      indicates whether to optimize lambda during the calculation of the
      Lagrangian; optional with default value True
  sample_weight_name : str
      Name of the argument to `estimator.fit()` which supplies the sample weights
      (defaults to `sample_weight`)
code: def _call_oracle(self, lambda_vec):
      signed_weights = (
          self.obj.signed_weights()
          + self.constraints.signed_weights(lambda_vec)
      )
      if isinstance(self.constraints, ClassificationMoment):
          redY = 1 * (signed_weights > 0)
      else:
          redY = self.constraints._y_as_series
      redW = signed_weights.abs()
      redW = self.constraints.total_samples * redW / redW.sum()
  
      redY_unique = np.unique(redY)
  
      estimator = None
      if len(redY_unique) == 1:
          logger.debug("redY had single value. Using DummyClassifier")
          estimator = DummyClassifier(
              strategy="constant", constant=redY_unique[0]
          )
          self.n_oracle_calls_dummy_returned += 1
      else:
          # use sklearn.base.clone to clone the estimator.
          # It is the same as copy.deepcopy for non-sklearn estimators (By using safe=False).
          # For sklearn estimators, it is more efficient as it would not
          # do a copy.deepcopy. Rather, instantiate a new estimator using the
          # get_params() internally.
          estimator = clone(estimator=self.estimator, safe=False)
  
      oracle_call_start_time = time()
      estimator.fit(
          self.constraints.X, redY, **{self.sample_weight_name: redW}
      )
      self.oracle_execution_times.append(
          time() - oracle_call_start_time
      )
      self.n_oracle_calls += 1
  
      return estimator
  
imports: import logging
  from time import time
  import numpy
  import pandas
  import scipy.optimize
  from sklearn import clone
  from sklearn.dummy import DummyClassifier
  from fairlearn.reductions._moments import ClassificationMoment
  from ._constants import _INDENTATION, _LINE, _PRECISION
label_desc: Use image node_id 5 for calling the _Lagrangian obj's underlying member method code with example usage: obj._call_oracle(lambda_vec) and returns: estimator