Getting Started with vfairness

A full-pipeline Python library for measuring, mitigating, and monitoring fairness in machine learning systems.

vfairness covers the entire ML fairness lifecycle: from pre-training bias auditing and fairness-aware model training, through group-specific calibration and post-processing, to production monitoring, stakeholder reporting, and controlled experimentation. Every stage produces auditable artifacts — SVG visualizations, structured reports, and machine-readable metrics — designed for regulatory environments including the EU AI Act.

~97k
Lines of Code
Built on numpy, pandas, scipy, scikit-learn, requests
92
Registered Functions
In the capability registry
98
Registered Classes
In the capability registry
44
SVG Templates
Self-contained SVG output
6
Pipeline Stages
End-to-end fairness lifecycle
9
Further Sub-Packages
8 specialized surfaces + net

Full-pipeline coverage from data audit to production monitoring

Installation

bash
# Core (numpy, pandas, scipy, scikit-learn, requests)
pip install vfairness

# With visualization support (matplotlib, seaborn)
pip install "vfairness[viz]"

# With interactive dashboards (Plotly + Dash)
pip install "vfairness[interactive]"

# Plotly charts only
pip install "vfairness[dashboard]"

# Experiment tracking (MLflow, Weights & Biases)
pip install "vfairness[mlops]"

# Full installation (all optional dependencies)
pip install "vfairness[all]"

vfairness is in beta: 0.1.0 is the release that is cut and ready, with its first PyPI publish as the pending release step, and the API is not frozen until 1.0.0. See the Release Pipeline for how versions ship.

python
import vfairness
print(f"vfairness {vfairness.__version__}")

Library Structure

vfairness is organized into 15 top-level sub-packages: a 6-stage fairness pipeline (preprocessing, in_processing, post_processing, evaluation, operations, rendering), 8 specialized analysis surfaces (llm, agents, multi_agent, xai, vision, legal, mcp, validity) and 1 cross-cutting infrastructure package (net, the egress guard). The areas below walk that pipeline from data to production.

1
Data & Preprocessing vfairness.preprocessing
Detect historical discrimination patterns, find proxy variables, audit representation, and apply fairness-aware feature transforms before training.
2
Training-Time Interventions vfairness.in_processing
Train models with fairness constraints using reductions, Lagrangian methods, and adversarial debiasing. Compare methods and visualize accuracy–fairness trade-offs.
3
Prediction-Time Interventions vfairness.post_processing
Optimize group-specific decision thresholds and reweight predictions to equalize outcomes without retraining. Includes CI/CD deployment gates.
4
Evaluation & Measurement vfairness.evaluation
Compute 20+ fairness metrics for classification, regression, and ranking tasks. Add bootstrap confidence intervals, effect sizes, and multiple-testing corrections.
5
Monitoring vfairness.operations.monitoring
Track fairness in production with sliding-window metrics, multi-scale drift detection (wavelet + KS), adaptive alert thresholds, and temporal trend analysis.
6
Reporting & Dashboards vfairness.operations.reporting
Generate multi-tier reports (executive, engineer, auditor) with natural language summaries. Build interactive Plotly dashboards with progressive disclosure.
7
Experimentation vfairness.operations.experimentation
Run fairness-aware A/B tests with intersectional analysis, per-subgroup power analysis, SPRT early stopping, Pareto optimization, and causal decomposition.
8
Workflow Integration vfairness.operations.cicd
Embed fairness into CI/CD with deployment gates, hierarchical intersectional checking, pytest plugin, pre-commit hooks, MLflow/W&B logging, and PR report cards.
9
LLM Fairness Testing vfairness.llm
Test LLMs for bias without training data. Counterfactual prompt testing, benchmark evaluation (BBQ, BOLD), output analysis, and non-determinism management.
10
Agent Fairness Testing vfairness.agents
Test AI agents for bias in tool selection, RAG retrieval, action outcomes, and delegation patterns. Includes correspondence testing and temporal trajectory tracking.
11
Multi-Agent Fairness Testing vfairness.multi_agent
Detect emergent bias in multi-agent systems. Tests non-compositionality, groupthink convergence, and coalition formation.
Complete Library Validation: vfairness_0_library_validation.ipynb — Validates all core functions across preprocessing, training, calibration, evaluation, and operations modules

Quick Start

Measure fairness in a loan approval model in under 30 lines.

python
import numpy as np
from vfairness import FairnessAnalyzer, demographic_parity_difference

# Sample data
y_true = np.array([1, 0, 1, 0, 1, 0, 1, 0, 1, 1] * 100)
y_pred = np.array([1, 0, 1, 1, 1, 0, 0, 0, 1, 1] * 100)
gender = np.array(['M','M','M','M','M','F','F','F','F','F'] * 100)

# Single metric
dp = demographic_parity_difference(y_true, y_pred, gender)
print(f"Demographic Parity Difference: {dp:.3f}")

# Full analyzer with confidence intervals
analyzer = FairnessAnalyzer(y_true, y_pred, gender, min_group_size=30)
result = analyzer.demographic_parity_difference(
    include_ci=True, n_bootstrap=5000, confidence_level=0.95
)
lo, hi = result.confidence_interval
print(f"DP Diff: {result.value:.3f}  95% CI: [{lo:.3f}, {hi:.3f}]")

# All metrics at once
for name, value in analyzer.compute_all_metrics().items():
    print(f"  {name}: {value:.3f}")
Choose Your Metric First Limitation

Fairness metrics are mathematically incompatible — you cannot satisfy demographic parity, equalized odds, and calibration simultaneously (Kleinberg et al., 2016). Decide which definition matches your use case before running analysis. See The Impossibility Theorem.

Production Features

Every test result includes audit trail metadata for EU AI Act compliance:

python
from vfairness.llm import OutputAnalyzer

analyzer = OutputAnalyzer(alpha=0.05)
result = analyzer.analyze_sentiment(texts_a, texts_b)

# Every result has audit metadata
print(result.metadata.timestamp)        # ISO 8601 UTC
print(result.metadata.library_version)  # current vfairness.__version__
print(result.metadata.parameters)       # {"alpha": 0.05, "metric": "sentiment", ...}

# Serialize for database storage
data = result.to_dict()    # Plain dict
json_str = result.to_json()  # JSON string

# Structured logging (configure once)
import logging
logging.basicConfig(level=logging.INFO)
# All vfairness operations now emit structured logs:
# INFO:vfairness.llm.output_analysis:Starting analyze_all with 4 metrics, 50 samples per group
# WARNING:vfairness.llm.output_analysis:Sample size (18) below recommended minimum of 25

Production Scorers

Install production-quality scorers with pip install "vfairness[llm]":

MetricScorerQualityDetails
SentimentVADERProduction7,500+ word lexicon, negation, intensity, emojis
Toxicityalt-profanity-checkProductionSVM trained on 200K samples, 95% accuracy
RefusalPattern-basedProduction50+ patterns, 5 categories, weighted scoring
HelpfulnessMulti-signal heuristicGood6 quality signals: length, vocabulary, structure, specificity, engagement, deflection
StereotypeCurated word listsGood61 terms + 14 phrase patterns (gender, racial, age, religious)

Progress Callbacks

Long-running batch operations support progress callbacks for UI integration:

python
from tqdm import tqdm

# With tqdm progress bar
pbar = tqdm(total=100)
proxy.send_batch(
    prompts=my_prompts,
    n_runs=25,
    progress_callback=lambda current, total: pbar.update(1)
)
pbar.close()

Bias Detection

Audit training data for representation bias, proxy variables, and historical discrimination patterns before any model is trained.

python
import pandas as pd
from vfairness import BiasDetector, detect_historical_patterns, identify_proxy_variables

# Full audit
detector = BiasDetector(
    df,
    protected_attributes=['gender', 'age'],
    outcome_column='approved',
    benchmarks={'gender': {'M': 0.49, 'F': 0.51}}
)
report = detector.full_audit()
print(report.summary())

# Historical discrimination patterns (scans all column names)
for r in detect_historical_patterns(df):
    print(f"  {r.feature}: {r.risk_level.value} - {r.pattern_type}")

# Proxy variable detection
for p in identify_proxy_variables(df, protected_attributes=['gender'], correlation_threshold=0.3):
    print(f"  {p.feature} -> {p.protected_attribute}  (r={p.correlation:.3f})")

Calibration

Ensure that a predicted probability of 70% means the same risk for every demographic group. Detect and correct calibration disparities.

python
from vfairness.post_processing.calibration import CalibrationAnalyzer

analyzer = CalibrationAnalyzer(
    y_true=labels, y_prob=model_probabilities,
    protected_attr=gender, attribute_name='gender'
)

report = analyzer.full_analysis(context='lending')
print(f"Well Calibrated: {report.is_well_calibrated}")
print(f"Significant Disparity: {report.has_significant_disparity}")
print(f"Overall ECE: {report.overall_metrics['ece']:.4f}")

# Apply group-specific recalibration
analyzer.fit_calibrator(method='isotonic')
calibrated_probs = analyzer.transform(y_prob_test, gender_test)

Explanations

Generate context-aware, stakeholder-ready explanations for every metric and audit result.

python
from vfairness import FairnessAnalyzer

# FairExplAIner mode for per-metric explanations
analyzer = FairnessAnalyzer(y_true, y_pred, gender, fair_explainer=True)
report = analyzer.get_report(include_ci=True)

for name, expl in report['explanations']['metrics'].items():
    print(f"{name}: {expl['severity']} - {expl['evaluation']}")

# FairnessExplainer for cross-module explanations
from vfairness.explainer import FairnessExplainer

explanation = FairnessExplainer.explain(audit_report)  # Takes a vfairness report object (BiasAuditReport, CalibrationReport, GateDecision, ...)
print(explanation.severity)           # 'info' | 'low' | 'medium' | 'high' | 'critical'
print(explanation.recommendations)    # Actionable next steps

Visualization

A library of SVG templates for card-based dashboards, plus Matplotlib and Plotly outputs. SVG rendering needs the [rendering] extra (Jinja2); the output SVG is self-contained. Call vfairness.rendering.list_templates() for the current set (44 renderable chart templates, plus the internal _shared_defs partial).

python
from vfairness import classification_fairness_report, plot_fairness_metrics, create_fairness_dashboard
from vfairness.rendering import radar_chart_to_svg, fairness_detailed_report_to_svg

report = classification_fairness_report(y_true, y_pred, gender, include_ci=True)

# Matplotlib (static): returns a Matplotlib Axes
ax = plot_fairness_metrics(report, style='academic', show_thresholds=True)
ax.figure.savefig('fairness_metrics.png', dpi=300, bbox_inches='tight')

# Plotly (interactive)
dashboard = create_fairness_dashboard(report, style='modern')
dashboard.write_html('fairness_dashboard.html')

# SVG templates (needs the [rendering] extra: Jinja2)
svg = radar_chart_to_svg(metrics_data, save_path='radar.svg')

plot_fairness_metrics needs the [viz] extra (Matplotlib); create_fairness_dashboard needs the [dashboard] extra (Plotly); the SVG templates need the [rendering] extra (Jinja2). Unlike the Matplotlib and Plotly charts, the SVG templates render to self-contained SVG with no runtime, browser, or JavaScript dependency.

See the SVG Gallery for every template with live previews.

Monitoring

Track fairness in production with real-time metrics, multi-scale drift detection, and adaptive alerting.

python
import pandas as pd
from vfairness.operations.monitoring import FairnessMonitor, FairnessDriftDetector

# Real-time monitoring: each batch is a DataFrame with
# 'prediction', 'label', and one 'group_<attr>' column per protected attribute
batch_df = pd.DataFrame({
    'prediction': predictions,
    'label': labels,
    'group_gender': gender,
})

monitor = FairnessMonitor(window_size=1000)
window = monitor.update_and_check(batch_df)
if window.any_alert:
    print(f"Alert! Flagged metrics: {[k for k, v in window.alerts.items() if v]}")

# Multi-scale drift detection: set a known-good baseline once,
# then compare each new stretch of metric history against it
detector = FairnessDriftDetector()
detector.set_baseline(pd.Series(reference_metrics))
drift = detector.check_drift(pd.Series(current_metrics), metric="demographic_parity")
print(f"Drift detected: {drift.drift_detected}  (score: {drift.overall_drift_score:.3f})")

Reporting

Transform metrics into stakeholder-ready intelligence with multi-tier reports and interactive dashboards.

python
from vfairness.operations.reporting import MetricsStore, FairnessDashboard, ReportGenerator

store = MetricsStore()
store.ingest_from_monitor(monitor)

# Interactive Plotly dashboard
dashboard = FairnessDashboard(store)
fig = dashboard.create_executive_view()
fig.write_html("dashboard.html")

# Automated multi-format report (HTML, PDF, JSON)
gen = ReportGenerator(store, dashboard)
report = gen.generate_executive_report()
report.save("executive_report.html")

create_executive_view needs Plotly (the [dashboard] extra); MetricsStore and ReportGenerator run on the core install.

Experimentation

Run fairness-aware A/B tests with intersectional analysis and automated deployment recommendations.

python
from vfairness.operations.experimentation import (
    FairnessExperiment, FairnessPowerAnalyzer, ExperimentAnalysis
)

exp = FairnessExperiment(
    control_data=df_ctrl, treatment_data=df_treat,
    protected_attributes=['gender', 'race'], outcome_column='approved',
)
result = exp.run_full_analysis()

# Per-intersection power analysis
power = FairnessPowerAnalyzer(exp)
print(power.get_power_summary())

# Multi-objective analysis and deployment decision
analysis = ExperimentAnalysis(result, experiment=exp)
rec = analysis.decision_recommendation()
print(f"Decision: {rec.decision}")  # DEPLOY | HOLD | REVERT

Workflow Integration

Embed fairness checks into every stage of the development lifecycle — from experiment tracking and version control to CI/CD gates and collaborative review.

python
from vfairness.operations.cicd import (
    ModelFairnessGate, HierarchicalGateConfig, FairnessReportCard
)

# Hierarchical gate: overall → single-attribute → intersectional
gate = ModelFairnessGate(
    metrics=['demographic_parity_difference', 'equal_opportunity_difference'],
    thresholds={'demographic_parity_difference': 0.1, 'equal_opportunity_difference': 0.1}
)
config = HierarchicalGateConfig(
    check_intersections=True, intersection_depth=2
)
decision = gate.evaluate_hierarchical(
    y_true, y_pred,
    protected_attrs={'gender': gender, 'race': race},  # arrays, keyed by attribute
    hierarchical_config=config
)

# Generate PR-ready report card
card = FairnessReportCard(decision, model_name='loan-approval-v2.1')
print(card.to_markdown())  # Paste into PR comment
python
from vfairness import log_fairness_to_wandb, auto_log_fairness

# W&B experiment tracking
log_fairness_to_wandb(analyzer, prefix='fairness')

# Auto-log decorator: the wrapped function returns (y_pred, y_true, sensitive_attr)
@auto_log_fairness(backend='mlflow')
def evaluate_model(X, y, sensitive):
    model = LogisticRegression().fit(X, y)
    return model.predict(X), y, sensitive  # fairness metrics logged automatically

Experiment tracking needs the [mlops] extra (pip install "vfairness[mlops]" for MLflow and Weights & Biases). Without it, log_fairness_to_wandb raises an ImportError, and the auto_log_fairness decorator warns and skips logging.

See the Workflow Integration Guide for CI/CD YAML templates, pre-commit hooks, pytest plugin setup, and end-to-end examples.

Next Steps