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.
Full-pipeline coverage from data audit to production monitoring
Installation
# Core (numpy, pandas, scipy)
pip install vfairness
# With visualization support (matplotlib, plotly)
pip install vfairness[viz]
# With interactive dashboards (Dash)
pip install vfairness[reporting]
# Full installation (all optional dependencies)
pip install vfairness[all]
import vfairness
print(f"vfairness {vfairness.__version__}")
Library Structure
vfairness is organized into eleven modules that follow the ML fairness pipeline from data to production.
vfairness.preprocessingvfairness.in_processingvfairness.post_processingvfairness.evaluationvfairness.operations.monitoringvfairness.operations.reportingvfairness.operations.experimentationvfairness.operations.cicdvfairness.llmvfairness.agentsvfairness.multi_agentQuick Start
Measure fairness in a loan approval model in under 30 lines.
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
)
print(f"DP Diff: {result.value:.3f} 95% CI: [{result.ci_lower:.3f}, {result.ci_upper:.3f}]")
# All metrics at once
for name, value in analyzer.compute_all_metrics().items():
print(f" {name}: {value:.3f}")
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:
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) # e.g. "0.1.0"
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]:
| Metric | Scorer | Quality | Details |
|---|---|---|---|
| Sentiment | VADER | Production | 7,500+ word lexicon, negation, intensity, emojis |
| Toxicity | alt-profanity-check | Production | SVM trained on 200K samples, 95% accuracy |
| Refusal | Pattern-based | Production | 50+ patterns, 5 categories, weighted scoring |
| Helpfulness | Multi-signal heuristic | Good | 6 quality signals: length, vocabulary, structure, specificity, engagement, deflection |
| Stereotype | Curated word lists | Good | 80+ terms + 14 phrase patterns (gender, racial, age, religious) |
Progress Callbacks
Long-running batch operations support progress callbacks for UI integration:
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.
import pandas as pd
from vfairness import BiasDetector, detect_historical_patterns, identify_proxy_variables
# Full audit
detector = BiasDetector(df, target_column='approved', protected_attributes=['gender', 'age'])
report = detector.full_audit(
protected_columns=['gender'],
population_benchmarks={'gender': {'M': 0.49, 'F': 0.51}}
)
print(report.summary())
# Historical discrimination patterns
for r in detect_historical_patterns(df, column_names=df.columns.tolist()):
print(f" {r.feature}: {r.risk_level.value} - {r.pattern_type}")
# Proxy variable detection
for p in identify_proxy_variables(df, protected_columns=['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.
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.
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) # Works for any result type
print(explanation.severity) # 'info' | 'low' | 'medium' | 'high' | 'critical'
print(explanation.recommendations) # Actionable next steps
Visualization
43 SVG templates for card-based dashboards, plus Matplotlib and Plotly outputs. Zero external dependencies for SVG rendering.
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)
fig = plot_fairness_metrics(report, style='academic', show_thresholds=True)
fig.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 (zero-dependency)
svg = radar_chart_to_svg(metrics_data, save_path='radar.svg')
See the SVG Gallery for all 43 templates with live previews.
Monitoring
Track fairness in production with real-time metrics, multi-scale drift detection, and adaptive alerting.
from vfairness.operations.monitoring import FairnessMonitor, FairnessDriftDetector
# Real-time monitoring
monitor = FairnessMonitor(window_size=1000)
window = monitor.update_and_check(predictions, labels, sensitive_attrs)
if window.any_alert:
print(f"Alert! Flagged metrics: {[k for k, v in window.alerts.items() if v]}")
# Multi-scale drift detection
detector = FairnessDriftDetector()
drift = detector.check_drift(reference_data, current_data, 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.
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")
Experimentation
Run fairness-aware A/B tests with intersectional analysis and automated deployment recommendations.
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.
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_attributes=['gender', 'race'],
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
from vfairness import log_fairness_to_wandb, auto_log_fairness
# W&B experiment tracking
log_fairness_to_wandb(analyzer, prefix='fairness')
# Auto-log decorator — wraps any training function
@auto_log_fairness(backend='mlflow')
def train_model(X, y, sensitive):
model = LogisticRegression().fit(X, y)
return model.predict(X) # fairness metrics logged automatically
See the Workflow Integration Guide for CI/CD YAML templates, pre-commit hooks, pytest plugin setup, and end-to-end examples.
Next Steps
API Reference
Complete documentation of all classes, functions, parameters, and return types.
Business Guide
Regulatory context, decision frameworks, and EU AI Act compliance guidance.
Concepts
Fairness definitions, the impossibility theorem, causal fairness, and statistical methodology.
SVG Gallery
Browse all 43 visualization templates with live previews and code examples.
Workflow Integration
CI/CD gates, pytest plugin, pre-commit hooks, MLOps logging, and PR report cards.