ExFairness.Metrics.EqualOpportunity (ExFairness v0.5.1)

View Source

Equal Opportunity fairness metric.

Equal opportunity requires that the true positive rate (TPR) is equal across groups defined by the sensitive attribute. This is a relaxed version of equalized odds that only considers TPR, not FPR.

Mathematical Definition

P(Ŷ = 1 | Y = 1, A = 0) = P(Ŷ = 1 | Y = 1, A = 1)

The disparity is measured as:

Δ_EO = |TPR_{A=0} - TPR_{A=1}|

When to Use

  • When false negatives are more costly than false positives
  • Hiring (don't want to miss qualified candidates from any group)
  • College admissions
  • Loan approvals where rejecting qualified applicants is the main concern

Limitations

  • Ignores false positive rates (may unfairly burden one group with false positives)
  • Less restrictive than equalized odds
  • May conflict with demographic parity when base rates differ

References

  • Hardt, M., Price, E., & Srebro, N. (2016). "Equality of Opportunity in Supervised Learning." NeurIPS.

Examples

iex> predictions = Nx.tensor([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0])
iex> labels = Nx.tensor([1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])
iex> sensitive = Nx.tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
iex> result = ExFairness.Metrics.EqualOpportunity.compute(predictions, labels, sensitive)
iex> result.passes
true

Summary

Functions

Computes equal opportunity disparity between groups.

Types

result()

@type result() :: %{
  group_a_tpr: float(),
  group_b_tpr: float(),
  disparity: float(),
  passes: boolean(),
  threshold: float(),
  interpretation: String.t()
}

Functions

compute(predictions, labels, sensitive_attr, opts \\ [])

@spec compute(Nx.Tensor.t(), Nx.Tensor.t(), Nx.Tensor.t(), keyword()) :: result()

Computes equal opportunity disparity between groups.

Parameters

  • predictions - Binary predictions tensor (0 or 1)
  • labels - Binary labels tensor (0 or 1)
  • sensitive_attr - Binary sensitive attribute tensor (0 or 1)
  • opts - Options:
    • :threshold - Maximum acceptable TPR disparity (default: 0.1)
    • :min_per_group - Minimum samples per group for validation (default: 10)

Returns

A map containing:

  • :group_a_tpr - True positive rate for group A
  • :group_b_tpr - True positive rate for group B
  • :disparity - Absolute difference in TPR
  • :passes - Whether disparity is within threshold
  • :threshold - Threshold used
  • :interpretation - Plain language explanation of the result

Examples

iex> predictions = Nx.tensor([1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
iex> labels = Nx.tensor([1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])
iex> sensitive = Nx.tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
iex> result = ExFairness.Metrics.EqualOpportunity.compute(predictions, labels, sensitive)
iex> result.passes
false