CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-fairlearn

A Python package to assess and improve fairness of machine learning models

Pending
Overview
Eval results
Files

reductions.mddocs/

Reduction Algorithms

In-processing mitigation techniques that cast fairness constraints as Lagrange multipliers in constrained optimization problems. These algorithms retrain models to satisfy fairness constraints while maintaining predictive performance by reducing the problem back to standard machine learning training.

Capabilities

ExponentiatedGradient

Implements the exponentiated gradient algorithm for fair classification and regression. Uses iterative reweighting to satisfy fairness constraints while optimizing for accuracy.

class ExponentiatedGradient:
    def __init__(self, estimator, constraints, *, objective=None, eps=0.01, 
                 max_iter=50, nu=None, eta0=2.0, run_linprog_step=True, 
                 sample_weight_name="sample_weight"):
        """
        Exponentiated gradient algorithm for fair machine learning.

        Parameters:
        - estimator: sklearn estimator, base learning algorithm
        - constraints: Moment object, fairness constraint to satisfy
        - objective: Moment object, optimization objective (default: ErrorRate)
        - eps: float, allowed fairness constraint violation
        - max_iter: int, maximum number of iterations
        - nu: float, convergence threshold (auto-set if None)
        - eta0: float, initial learning rate
        - run_linprog_step: bool, whether to run linear programming step
        - sample_weight_name: str, parameter name for sample weights in estimator
        """
    
    def fit(self, X, y, *, sensitive_features, sample_weight=None):
        """
        Fit the model with fairness constraints.
        
        Parameters:
        - X: array-like, feature matrix
        - y: array-like, target values
        - sensitive_features: array-like, sensitive feature values
        - sample_weight: array-like, optional sample weights
        
        Returns:
        self
        """
    
    def predict(self, X):
        """
        Make predictions using the fitted fair model.
        
        Parameters:
        - X: array-like, feature matrix
        
        Returns:
        array-like: Predicted values
        """
    
    def predict_proba(self, X):
        """Predict class probabilities (classification only)."""
        
    @property
    def predictors_(self):
        """List of predictors from the optimization process."""
        
    @property
    def weights_(self):
        """Weights for combining predictors."""
        
    @property
    def last_iter_(self):
        """Number of iterations run."""
        
    @property 
    def best_gap_(self):
        """Best constraint violation achieved."""
        
    @property
    def best_iter_(self):
        """Iteration with best constraint violation."""

Usage Example

from fairlearn.reductions import ExponentiatedGradient, DemographicParity
from sklearn.linear_model import LogisticRegression

# Create constraint and estimator
constraint = DemographicParity()
estimator = LogisticRegression()

# Create and fit fair model
fair_model = ExponentiatedGradient(
    estimator=estimator,
    constraints=constraint,
    eps=0.01,
    max_iter=50
)

fair_model.fit(X_train, y_train, sensitive_features=A_train)
y_pred = fair_model.predict(X_test)

GridSearch

Implements grid search over Lagrange multipliers for fair machine learning. Systematically explores the trade-off between fairness and accuracy.

class GridSearch:
    def __init__(self, estimator, constraints, *, selection_rule="tradeoff",
                 constraint_weight=0.5, grid_size=10, grid_limit=2.0,
                 grid_offset=None, sample_weight_name="sample_weight"):
        """
        Grid search approach to fairness constraints.

        Parameters:
        - estimator: sklearn estimator, base learning algorithm
        - constraints: Moment object, fairness constraint to satisfy
        - selection_rule: str, how to select solution ("tradeoff" or "best_tradeoff")
        - constraint_weight: float, weight for constraint vs. loss in tradeoff
        - grid_size: int, number of Lagrange multipliers to try
        - grid_limit: float, largest Lagrange multiplier to try
        - grid_offset: dict, base values for Lagrange multipliers
        - sample_weight_name: str, parameter name for sample weights
        """
    
    def fit(self, X, y, *, sensitive_features, sample_weight=None):
        """
        Fit the model with fairness constraints using grid search.
        
        Parameters:
        - X: array-like, feature matrix
        - y: array-like, target values
        - sensitive_features: array-like, sensitive feature values
        - sample_weight: array-like, optional sample weights
        
        Returns:
        self
        """
    
    def predict(self, X):
        """Make predictions using the selected fair model."""
        
    def predict_proba(self, X):
        """Predict class probabilities (classification only)."""
        
    @property
    def predictors_(self):
        """All predictors from the grid search."""
        
    @property
    def lambda_vecs_(self):
        """Lagrange multiplier vectors from grid search."""
        
    @property
    def objectives_(self):
        """Objective values for each grid point."""
        
    @property
    def gammas_(self):
        """Constraint violations for each grid point."""
        
    @property
    def best_idx_(self):
        """Index of the selected predictor."""

Fairness Constraints

Base Constraint Classes

Abstract base classes that define the interface for fairness constraints.

class Moment:
    """Base class for moment constraints."""
    
    def load_data(self, X, y, *, sensitive_features, sample_weight=None):
        """Load and validate input data."""
        
    def gamma(self, predictor):
        """Calculate constraint violation for a predictor."""
        
    def project_lambda(self, lambda_vec):
        """Project Lagrange multiplier to feasible region."""
        
    def signed_weights(self, lambda_vec):
        """Calculate signed weights for constraint."""

class ClassificationMoment(Moment):
    """Base class for classification fairness constraints."""

class LossMoment(Moment):
    """Base class for loss-based fairness constraints."""

Demographic Parity Constraints

Constraints that require equal positive prediction rates across groups.

class DemographicParity(ClassificationMoment):
    """
    Demographic parity constraint requiring equal selection rates.
    
    This constraint is satisfied when P(Y_hat=1 | A=a) is equal for all values of A,
    where A represents the sensitive feature and Y_hat represents predictions.
    """
    
    def __init__(self):
        """Initialize demographic parity constraint."""

Equalized Odds Constraints

Constraints that require equal true positive and false positive rates across groups.

class EqualizedOdds(ClassificationMoment):
    """
    Equalized odds constraint requiring equal TPR and FPR across groups.
    
    This constraint is satisfied when both:
    - P(Y_hat=1 | Y=1, A=a) is equal for all values of A (equal TPR)
    - P(Y_hat=1 | Y=0, A=a) is equal for all values of A (equal FPR)
    """
    
    def __init__(self):
        """Initialize equalized odds constraint."""

Equal Opportunity Constraints

Constraints that require equal true positive rates across groups.

class TruePositiveRateParity(ClassificationMoment):
    """
    Equal opportunity constraint requiring equal true positive rates.
    
    This constraint is satisfied when P(Y_hat=1 | Y=1, A=a) is equal 
    for all values of A.
    """
    
    def __init__(self):
        """Initialize true positive rate parity constraint."""

class FalsePositiveRateParity(ClassificationMoment):
    """False positive rate parity constraint."""

class ErrorRateParity(ClassificationMoment):
    """Error rate parity constraint."""

Utility-Based Constraints

General utility parity constraints that can be customized for different fairness criteria.

class UtilityParity(ClassificationMoment):
    """
    General utility parity constraint.
    
    Allows specification of different utility functions and events
    for flexible fairness definitions.
    """
    
    def __init__(self, *, difference_bound=None, ratio_bound=None):
        """
        Initialize utility parity constraint.
        
        Parameters:
        - difference_bound: float, maximum allowed difference in utilities
        - ratio_bound: tuple, (lower_bound, upper_bound) for utility ratios
        """

Error Rate Constraints

Constraints based on error rates and loss functions.

class ErrorRate(ClassificationMoment):
    """
    Error rate constraint for equal error rates across groups.
    """
    
    def __init__(self):
        """Initialize error rate constraint."""

Bounded Group Loss Constraints

Constraints that bound the loss within each sensitive group.

class BoundedGroupLoss(LossMoment):
    """
    Constraint that bounds loss within each group.
    
    Ensures that no group has loss significantly higher than others.
    """
    
    def __init__(self, loss, *, upper_bound):
        """
        Initialize bounded group loss constraint.
        
        Parameters:
        - loss: loss function object
        - upper_bound: float, maximum allowed loss for any group
        """
        
    def load_data(self, X, y, *, sensitive_features, sample_weight=None):
        """Load data and prepare for constraint computation."""
        
    def gamma(self, predictor):
        """Calculate constraint violation."""

Loss Functions

Loss functions used with bounded group loss constraints.

class SquareLoss:
    """
    Square loss function: (y_true - y_pred)^2
    """
    
    def eval(self, y_true, y_pred):
        """Evaluate square loss."""
        
    def eval_derivative(self, y_true, y_pred):
        """Evaluate derivative of square loss."""

class AbsoluteLoss:
    """
    Absolute loss function: |y_true - y_pred|
    """
    
    def eval(self, y_true, y_pred):
        """Evaluate absolute loss."""
        
    def eval_derivative(self, y_true, y_pred):
        """Evaluate derivative of absolute loss."""

class ZeroOneLoss(AbsoluteLoss):
    """
    Zero-one loss function: I(y_true != y_pred)
    
    Inherits from AbsoluteLoss but evaluates to 0 or 1.
    """

Advanced Usage

Custom Constraints

You can create custom constraints by inheriting from the base constraint classes:

from fairlearn.reductions import ClassificationMoment

class CustomFairnessConstraint(ClassificationMoment):
    def __init__(self):
        super().__init__()
    
    def load_data(self, X, y, *, sensitive_features, sample_weight=None):
        # Implement data loading logic
        pass
    
    def gamma(self, predictor):
        # Implement constraint violation calculation
        pass

Combining with Scikit-learn

Reduction algorithms are designed to work seamlessly with scikit-learn estimators:

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

# Use any sklearn estimator
rf = RandomForestClassifier(n_estimators=100)
fair_rf = ExponentiatedGradient(rf, DemographicParity())

# Works with sklearn utilities
scores = cross_val_score(fair_rf, X, y, cv=5)

Install with Tessl CLI

npx tessl i tessl/pypi-fairlearn

docs

adversarial.md

assessment.md

datasets.md

index.md

postprocessing.md

preprocessing.md

reductions.md

tile.json