class_docstr: Implementation of equalized odds as a moment.
  
  Adds conditioning on label compared to demographic parity, i.e.
  
  .. math::
     P[h(X) = 1 | A = a, Y = y] = P[h(X) = 1 | Y = y] \; \forall a, y
  
  This implementation of :class:`UtilityParity` defines
  events corresponding to the unique values of the `Y` array.
  
  The `prob_event` :class:`pandas:pandas.Series` will record the
  fraction of the samples corresponding to each unique value in
  the `Y` array.
  
  The `index` MultiIndex will have a number of entries equal to
  the number of unique values for the sensitive feature, multiplied by
  the number of unique values of the `Y` array, multiplied by two (for
  the Lagrange multipliers for positive and negative constraints).
  
  With these definitions, the :meth:`UtilityParity.signed_weights` method
  will calculate the costs according to Example 4 of
  :footcite:t:`agarwal2018reductions`.
  
  This :class:`~Moment` also supports control features, which can be used to
  stratify the data, with the constraint applied within
  each stratum, but not between strata.
  
  Read more in the :ref:`User Guide <equalized_odds>`.
class_docstr_tok: ["Implementation","of","equalized","odds","as","a","moment",".","Adds","conditioning","on","label","compared","to","demographic","parity",",","i.e",".","..","math",":",":","P","[","h","(","X",")","=","1","|","A","=","a",",","Y","=","y","]","=","P","[","h","(","X",")","=","1","|","Y","=","y","]","\\",";","\\forall","a",",","y","This","implementation","of",":","class",":","`","UtilityParity","`","defines","events","corresponding","to","the","unique","values","of","the","`","Y","`","array",".","The","`","prob_event","`",":","class",":","`","pandas",":","pandas.Series","`","will","record","the","fraction","of","the","samples","corresponding","to","each","unique","value","in","the","`","Y","`","array",".","The","`","index","`","MultiIndex","will","have","a","number","of","entries","equal","to","the","number","of","unique","values","for","the","sensitive","feature",",","multiplied","by","the","number","of","unique","values","of","the","`","Y","`","array",",","multiplied","by","two","(","for","the","Lagrange","multipliers","for","positive","and","negative","constraints",")",".","With","these","definitions",",","the",":","meth",":","`","UtilityParity.signed_weights","`","method","will","calculate","the","costs","according","to","Example","4","of",":","footcite",":","t",":","`","agarwal2018reductions","`",".","This",":","class",":","`","~Moment","`","also","supports","control","features",",","which","can","be","used","to","stratify","the","data",",","with","the","constraint","applied","within","each","stratum",",","but","not","between","strata",".","Read","more","in","the",":","ref",":","`","User","Guide","<","equalized_odds",">","`","."]
docstr: Load the specified data into the object.
docstr_tok: ["Load","the","specified","data","into","the","object","."]
code: def load_data(
      self, X, y, *, sensitive_features, control_features=None
  ):
      """Load the specified data into the object."""
      _, y_train, sf_train, cf_train = _validate_and_reformat_input(
          X,
          y,
          enforce_binary_labels=True,
          sensitive_features=sensitive_features,
          control_features=control_features,
      )
  
      base_event = y_train.apply(lambda v: _LABEL + "=" + str(v))
      event = _merge_event_and_control_columns(base_event, cf_train)
      super().load_data(
          X, y_train, event=event, sensitive_features=sf_train
      )
  
imports: import numpy
  import pandas
  from fairlearn.utils._input_validation import _MESSAGE_RATIO_NOT_IN_RANGE, _validate_and_reformat_input
  from .error_rate import ErrorRate
  from .moment import _ALL, _EVENT, _GROUP_ID, _LABEL, _SIGN, ClassificationMoment
label_desc: Use image node_id 1 for calling the EqualizedOdds obj's underlying member method code with example usage: obj.load_data(X, y) without return types