ExFairness.Metrics.DemographicParity (ExFairness v0.5.1)
View SourceDemographic Parity (Statistical Parity) fairness metric.
Demographic parity requires that the probability of a positive prediction is equal across groups defined by the sensitive attribute.
Mathematical Definition
P(Ŷ = 1 | A = 0) = P(Ŷ = 1 | A = 1)The disparity is measured as the absolute difference between positive prediction rates:
Δ_DP = |P(Ŷ = 1 | A = 0) - P(Ŷ = 1 | A = 1)|When to Use
- When equal representation in positive outcomes is required
- Advertising and content recommendation systems
- When base rates can legitimately differ between groups
Limitations
- Ignores base rate differences in actual outcomes
- May conflict with accuracy if base rates differ
- Can be satisfied by a random classifier
References
- Dwork, C., et al. (2012). "Fairness through awareness." ITCS.
- Feldman, M., et al. (2015). "Certifying and removing disparate impact." KDD.
Examples
iex> predictions = Nx.tensor([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 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.DemographicParity.compute(predictions, sensitive)
iex> result.passes
true
Summary
Functions
Computes demographic parity disparity between groups.
Types
Functions
@spec compute(Nx.Tensor.t(), Nx.Tensor.t(), keyword()) :: result()
Computes demographic parity disparity between groups.
Parameters
predictions- Binary predictions tensor (0 or 1)sensitive_attr- Binary sensitive attribute tensor (0 or 1)opts- Options::threshold- Maximum acceptable disparity (default: 0.1):min_per_group- Minimum samples per group for validation (default: 10)
Returns
A map containing:
:group_a_rate- Positive prediction rate for group A (sensitive_attr = 0):group_b_rate- Positive prediction rate for group B (sensitive_attr = 1):disparity- Absolute difference between rates: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, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 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.DemographicParity.compute(predictions, sensitive)
iex> result.disparity
1.0
iex> predictions = Nx.tensor([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 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.DemographicParity.compute(predictions, sensitive)
iex> result.passes
true