Fairness

Fairness diagnostics, fairness slicing and unfairness-mitigation utilities, exposed by TestSuite.

TestSuite.diagnose_fairness(group_config, favorable_label: int = 1, dataset: str = 'test', metric: str = None, threshold: float | int = None)

Evaluate fairness metrics across different protected and reference groups.

This method calculates various fairness metrics based on the provided group configurations and model predictions, allowing for an assessment of fairness across specified groups in the dataset. It returns a result object containing the computed metrics, visualizations, and other relevant information.

Parameters:
group_configdict

Configuration defining protected and reference groups. Each key is a custom group name, and each value is a dictionary with group definitions. Supports three formats:

  1. For numerical features:

    {
        "feature": str,           # Feature name
        "protected": {            # Protected group bounds
            "lower": float,       # Lower bound
            "lower_inclusive": bool,
            "upper": float,       # Optional upper bound
            "upper_inclusive": bool
        },
        "reference": {            # Reference group bounds
            "lower": float,       # Optional lower bound
            "lower_inclusive": bool,
            "upper": float,       # Upper bound
            "upper_inclusive": bool
        }
    }
    
  2. For categorical features:

    {
        "feature": str,                  # Feature name
        "protected": str or int,         # Protected group category
        "reference": str or int          # Reference group category
    }
    
  3. For probabilistic group membership:

    {
        "by_weights": True,
        "protected": str,         # Column name with protected group probabilities
        "reference": str          # Column name with reference group probabilities
    }
    
favorable_label{0, 1}, default=1
  • For classification: The preferred class label.

  • For regression: 1 means larger predictions are preferred, 0 means smaller predictions are preferred.

dataset{“main”, “train”, “test”}, default=”test”

The dataset to evaluate fairness on.

metricstr, default=None

Fairness metric to calculate. Higher values indicate less unfairness. If None, defaults are used based on task type.

For regression (default=”SMD”):

  • SMD: Standardized Mean Difference (%) between protected and reference groups

For classification (default=”AIR”):

  • AIR: Adverse Impact Ratio of predicted probabilities

  • PR: Precision Ratio

  • RR: Recall Ratio

thresholdfloat or int, default=None

Optional threshold value to display in the visualization. Used to indicate acceptable fairness levels.

Returns:
ValidationResult

A result object containing:

  • key: “diagnose_fairness”

  • data: Name of the dataset used

  • model: Name of the model used

  • inputs: Input parameters used for the test

  • value: Nested dictionary containing the (“<group_name>”, item) pairs for each group, and the item is also a dictionary with:

    • “fairness_metric”: the fairness metric for each group.

    • “distance”: The KS distance between protected vs reference group predictions.

    • “data_info”: The sample indices of the protected and reference groups, which can be further used for data distribution test, e.g.,

    data_results = ds.data_drift_test(**results.value["Gender"]["data_info"])
    data_results.plot("summary")
    data_results.plot(("density", "MedInc"))
    
  • table: DataFrame with fairness metric scores for each group.

  • options: Dictionary of visualizations configuration. Run results.plot() to show all plots; Run results.plot(name=xxx) to display one preferred plot; and the following names are available:

    • “fairness”: Fairness metric bar plots visualizing the scores for each group.

    • “<group_name>”: Empirical cumulative distribution function plots for the protected and reference group predictions, allowing for visual comparison of distributions.

Examples

TestSuite.diagnose_slicing_fairness(group_config, features: str | Tuple = None, favorable_label: int = 1, dataset: str = 'test', metric: str = None, method: str = 'uniform', bins: int | Dict = 10, n_estimators: int = 1000, threshold: float | int = None)

Evaluate a model’s slicing fairness metric across different protected-reference groups.

This function assesses the fairness of a model by calculating specified metrics across various protected and reference groups defined in the group_config. It takes into account the features used for slicing, the dataset to be evaluated, and the method for binning numerical features, among other parameters. The results include a validation object containing the fairness metrics and related information.

Parameters:
group_configdict

Configuration defining protected and reference groups. Each key is a custom group name, and each value is a dictionary with group definitions. Supports three formats:

  1. For numerical features:

    {
        "feature": str,           # Feature name
        "protected": {            # Protected group bounds
            "lower": float,       # Lower bound
            "lower_inclusive": bool,
            "upper": float,       # Optional upper bound
            "upper_inclusive": bool
        },
        "reference": {            # Reference group bounds
            "lower": float,       # Optional lower bound
            "lower_inclusive": bool,
            "upper": float,       # Upper bound
            "upper_inclusive": bool
        }
    }
    
  2. For categorical features:

    {
        "feature": str,                  # Feature name
        "protected": str or int,         # Protected group category
        "reference": str or int          # Reference group category
    }
    
  3. For probabilistic group membership:

    {
        "by_weights": True,
        "protected": str,         # Column name with protected group probabilities
        "reference": str          # Column name with reference group probabilities
    }
    
featuresUnion[str, Tuple], default=None

Feature names used for slicing. Each tuple element should contain at most 2 features.

  • If features=(“X1”, ) or “X1”, computes 1D slicing over X1.

  • If features=(“X1”, “X2”), computes 2D slicing over the interaction of X1 and X2.

  • If features=((“X1”, ), (“X2”, )), computes 1D slicing over X1 and X2 separately.

Note: Batch mode for 2D slicing is not supported. If None, all 1D features will be used.

favorable_label{0, 1}, default=1
  • For classification: The preferred class label.

  • For regression: 1 means larger predictions are preferred, 0 means smaller predictions are preferred.

dataset{“main”, “train”, “test”}, default=”train”

The dataset to be tested.

metric{“AIR”, “SMD”, “PR”, “RR”}, default=None

The fairness metric(s) to calculate. If None, defaults to SMD for regression and AIR for classification.

method{“uniform”, “quantile”, “auto-xgb1”, “precompute”}, default=”uniform”

Method for binning numerical features:

  • “uniform”: Equal-width binning

  • “quantile”: Equal-frequency binning (may result in fewer bins due to ties)

  • “auto-xgb1”: Use bins of a XGBoost depth-1 model fitted between X and residuals.

  • “precompute”: Uses pre-specified bin edges

binsint or dict, default=10

Controls binning granularity:

  • If int: Number of bins for numerical features. For “quantile”, this is the maximum number of bins. For “auto-xgb1”, this sets XGBoost’s max_bin parameter.

  • If dict: Manual bin specifications for each feature, only used with method=”precompute”. Format: {feature_name: array_of_bin_edges}. Example: {“X0”: [0.1, 0.5, 0.9]} Note: Cannot specify bins for categorical features.

n_estimatorsint, default=1000

Number of estimators in xgboost, used when method=”auto-xgb1”.

thresholdfloat or int, default=None

Threshold for filtering fairness metric results. If not specified, it will be the fairness metric of the whole population of each group, respectively.

Returns:
ValidationResult

Slicing Fairness result, which includes:

  • key: “diagnose_slicing_fairness”

  • data: Name of the dataset used

  • model: Name of the model used

  • inputs: Input parameters used for the test

  • value: Nested dictionary containing the (“<feature_name>”, item) pairs for each feature (this level is only used in batch mode, i.e., multiple 1D features are specified), and the item is also a dictionary with:

    • “<group_name>”: List of fairness metrics for each segment, and each element is a dict containing

      • “Feature”: feature name

      • “Segment”: segment value (categorical) or segment range (numerical)

      • “Size”: number of samples in this segment

      • <”metric”>: fairness metric value of this segment

      • “Sample_ID”: sample indices of this segment

      • “Sample_Dataset”: dataset name, e.g., “train”, “test”, etc.

      • “Segment_Info”: explicit definition of this segment, similar to “Segment”

      • “Weak”: boolean indicator showing whether this segment is weak or not

  • table: dictionary of fairness metric table.

    • “<group_name>”: Table of fairness metrics for each segment.

  • options: Dictionary of visualizations configuration. Run results.plot() to show all plots; To display one preferred plot by results.plot(name=xxx), and the following names are available:

    • “<group_name>” (If only one 1D or 2D slicing features are specified): Fairness metric plots against selected slicing feature(s).

    • “(<feature_name>, <group_name>)” (If multiple single features are specified): Fairness metric plots against selected slicing feature(s).

Examples

TestSuite.diagnose_mitigate_unfair_thresholding(group_config, favorable_label: int = 1, dataset: str = 'test', metric: str = None, performance_metric: str = None, proba_cutoff: int | Tuple = None)

Attempts to mitigate model unfairness by applying feature value binning.

This method evaluates how binning feature values affects both model fairness and performance. It works by replacing values within each bin with the bin’s mean value, which can help reduce unfair treatment of similar instances.

Parameters:
group_configdict

Configuration defining protected and reference groups. Supports three formats:

  1. For numerical features:

    {
        "feature": str,           # Feature name
        "protected": {            # Protected group bounds
            "lower": float,       # Lower bound
            "lower_inclusive": bool,
            "upper": float,       # Optional upper bound
            "upper_inclusive": bool
        },
        "reference": {            # Reference group bounds
            "lower": float,       # Optional lower bound
            "lower_inclusive": bool,
            "upper": float,       # Upper bound
            "upper_inclusive": bool
        }
    }
    
  2. For categorical features:

    {
        "feature": str,                  # Feature name
        "protected": str or int,         # Protected group category
        "reference": str or int          # Reference group category
    }
    
  3. For probabilistic group membership:

    {
        "by_weights": True,
        "protected": str,         # Column name with protected group probabilities
        "reference": str          # Column name with reference group probabilities
    }
    
favorable_label{0, 1}, default=1
  • For classification: The preferred class label.

  • For regression: 1 means larger predictions are preferred, 0 means smaller predictions are preferred.

dataset{“main”, “train”, “test”}, default=”test”

Which dataset partition to analyze

metricstr, optional

Fairness metric to use. Higher values indicate better fairness.

For regression (default=”SMD”):

  • “SMD”: Standardized Mean Difference (%) between groups

For classification (default=”AIR”):

  • “AIR”: Adverse Impact Ratio

  • “PR”: Precision Ratio

  • “RR”: Recall Ratio

performance_metricstr, default=None

Model performance metric to use.

  • For classification (default=”AUC”): “ACC”, “AUC”, “F1”, “LogLoss”, “Precision”, “Recall”, and “Brier”

  • For regression (default=”MSE”): “MSE”, “MAE”, and “R2”

proba_cutoff: int or tuple, default=20

If int, it represents the number of uniform grid points of cutoff values between 0 and 1. If tuple of float, it is the custom grid points of cutoff values, and its values should be within 0 and 1.

Returns:
ValidationResult

Contains:

  • key: “diagnose_mitigate_unfair_thresholding”

  • data: Name of the dataset used

  • model: Name of the model used

  • inputs: Input parameters used for the test

  • value: Nested dictionary containing the (“<threshold>”, item) pairs for each threshold, and the item is also a dictionary with:

    • “Performance”: Predictive performance scores after adjusting the threshold

    • “Fairness”: Fairness scores after adjusting the threshold

  • table: dictionary of dataframe with perforamnce and fairness metric scores after adjusting the threshold.

    • “Fairness”: Fairness scores table

    • “Performance”: Predictive performance table

  • options: Dictionary of visualizations configuration. Run results.plot() to show all plots; Run results.plot(name=xxx) to display one preferred plot; and the following names are available:

    • “<group_name>”: Line plots visualizing the performance and fairness scores against each threshold.

Notes

The method compares baseline metrics (no binning) against metrics after binning each feature. This can help identify which features, when binned, most effectively balance fairness and performance tradeoffs.

Examples

TestSuite.diagnose_mitigate_unfair_binning(group_config, favorable_label: int = 1, dataset: str = 'test', metric: str = None, performance_metric: str = None, binning_features: str | Tuple = None, binning_method: str = 'uniform', bins: int | Dict = 10)

Mitigate model unfairness through feature value binning.

This method attempts to reduce model unfairness by binning feature values, which can help smooth out predictions across different groups.

  1. For numerical features:

    {
        "feature": str,           # Feature name
        "protected": {            # Protected group bounds
            "lower": float,       # Lower bound
            "lower_inclusive": bool,
            "upper": float,       # Optional upper bound
            "upper_inclusive": bool
        },
        "reference": {            # Reference group bounds
            "lower": float,       # Optional lower bound
            "lower_inclusive": bool,
            "upper": float,       # Upper bound
            "upper_inclusive": bool
        }
    }
    
  2. For categorical features:

    {
        "feature": str,                  # Feature name
        "protected": str or int,         # Protected group category
        "reference": str or int          # Reference group category
    }
    
  3. For probabilistic group membership:

    {
        "by_weights": True,
        "protected": str,         # Column name with protected group probabilities
        "reference": str          # Column name with reference group probabilities
    }
    

favorable_label : {0, 1}, default=1

  • For classification: The preferred class label.

  • For regression: 1 means larger predictions are preferred, 0 means smaller predictions are preferred.

dataset{“main”, “train”, “test”}, default=”test”

Which dataset partition to analyze

metricstr, default=None

Fairness metric to calculate. Higher values indicate less unfairness. If None, defaults are used based on task type.

For regression (default=”SMD”):

  • SMD: Standardized Mean Difference (%) between protected and reference groups

For classification (default=”AIR”):

  • AIR: Adverse Impact Ratio of predicted probabilities

  • PR: Precision Ratio

  • RR: Recall Ratio

performance_metricstr, default=None

Model performance metric to use.

  • For classification (default=”AUC”): “ACC”, “AUC”, “F1”, “LogLoss”, “Precision”, “Recall”, and “Brier”

  • For regression (default=”MSE”): “MSE”, “MAE”, and “R2”

binning_featuresstr or tuple, default=None

Features to apply binning to. If None, bins all features.

binning_method{“uniform”, “quantile”, “auto-xgb1”, “precompute”}, default=”uniform”

Method for binning numerical features:

  • “uniform”: Equal-width bins

  • “quantile”: Equal-frequency bins

  • “auto-xgb1”: XGBoost prebinning

  • “precompute”: Use pre-specified bin edges from bins parameter

binsint or dict, default=10

For int: Number of bins for numerical features; For dict: Pre-computed bin edges for each feature when binning_method=”precompute”. Example: {“feature1”: [0.1, 0.5, 0.9], “feature2”: [0.3, 0.7]}

Returns:
ValidationResult

Contains:

  • key: “diagnose_mitigate_unfair_binning”

  • data: Name of the dataset used

  • model: Name of the model used

  • inputs: Input parameters used for the test

  • value: Nested dictionary containing the (“<feature_name>”, item) pairs for each feature, and the item is also a dictionary with:

    • “Performance”: Predictive performance scores after binning each feature

    • “Fairness”: Fairness scores after binning each feature

  • table: dictionary of dataframe with perforamnce and fairness metric scores after binning.

    • “Fairness”: Fairness scores table

    • “Performance”: Predictive performance table

  • options: Dictionary of visualizations configuration. Run results.plot() to show all plots; Run results.plot(name=xxx) to display one preferred plot; and the following names are available:

    • “<group_name>”: Line and bar plots visualizing the performance and fairness scores against each binning features.

Examples