agentsclimarketplace

Bias assessment

Skill obielin/responsible-ai-skills/skills/bias-assessment

Skills framework for coding agents that enforces responsible AI practices — bias assessment, fairness testing, explainability, governance documentation, and alignment review. Auto-activates when building AI systems.

Install
npx -y skills add obielin/responsible-ai-skills --skill bias-assessment

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when loading datasets, training ML models, evaluating model performance, or preparing data for AI systems. Do NOT skip this for "small" or "simple" models.

SKILL.md

4.9 KB, as published. Nobody here has run it

Bias Assessment

Bias in AI systems causes real harm. A model that appears accurate overall can systematically disadvantage specific groups. You MUST complete this assessment before training or evaluating any model.

Phase 1: Data Audit (Before Training)

1.1 Check Representation

Run the representation check script:

python skills/bias-assessment/scripts/check_representation.py --data <your_dataset>

If no script applies, manually verify:

# For each protected attribute in your dataset:
for attr in ['age', 'sex', 'ethnicity', 'disability', 'postcode']:
    if attr in df.columns:
        print(f"\n{attr} distribution:")
        print(df[attr].value_counts(normalize=True))
        
        # Flag underrepresented groups (<5% of dataset)
        underrepresented = df[attr].value_counts(normalize=True)
        flagged = underrepresented[underrepresented < 0.05].index.tolist()
        if flagged:
            print(f"⚠️  UNDERREPRESENTED: {flagged}")

Stop and fix if: Any group that will be affected by predictions has <5% representation.

1.2 Check for Proxy Variables

Proxy variables appear neutral but encode protected characteristics:

Proxy VariableMay Encode
Postcode / ZIP codeEthnicity, deprivation
NameEthnicity, sex
School attendedSocioeconomic status, ethnicity
Job title historySex, disability
Device typeSocioeconomic status

Action: For each proxy variable, decide: remove it, transform it, or document the risk explicitly.

1.3 Check Label Quality

Biased labels produce biased models:

  • Were labels assigned by humans? → Check inter-annotator agreement across annotator demographics
  • Were labels derived from historical decisions? → Those decisions may contain historical bias
  • Are labels consistent across demographic groups? → Run: df.groupby(protected_attr)['label'].mean()

Phase 2: Model Evaluation (After Training)

2.1 Disaggregated Performance

NEVER report only aggregate metrics. Always disaggregate:

from sklearn.metrics import classification_report

for group_val in df[protected_attr].unique():
    mask = df[protected_attr] == group_val
    print(f"\n=== {protected_attr} = {group_val} ===")
    print(classification_report(y_true[mask], y_pred[mask]))

2.2 Fairness Metrics — Compute All Three

# 1. Demographic Parity: positive prediction rate per group
for group in groups:
    mask = df[attr] == group
    rate = y_pred[mask].mean()
    print(f"Demographic parity [{group}]: {rate:.3f}")

# 2. Equal Opportunity: true positive rate per group
for group in groups:
    mask = (df[attr] == group) & (y_true == 1)
    tpr = y_pred[mask].mean()
    print(f"Equal opportunity [{group}]: {tpr:.3f}")

# 3. Predictive Parity: precision per group
for group in groups:
    mask = df[attr] == group
    from sklearn.metrics import precision_score
    prec = precision_score(y_true[mask], y_pred[mask])
    print(f"Predictive parity [{group}]: {prec:.3f}")

2.3 Bias Thresholds — Do Not Proceed If Exceeded

MetricMaximum Acceptable GapAction If Exceeded
Demographic parity difference0.05Investigate data; apply reweighting
Equal opportunity difference0.05Check label quality; consider threshold adjustment
Predictive parity difference0.05Review training data balance
False positive rate gap0.05Adjust decision threshold per group

Phase 3: Mitigation

If thresholds are exceeded, you MUST apply mitigation before proceeding:

Pre-processing

# Reweighting: give underrepresented groups more influence during training
from sklearn.utils.class_weight import compute_sample_weight
sample_weights = compute_sample_weight('balanced', y=df[protected_attr])
model.fit(X_train, y_train, sample_weight=sample_weights)

Post-processing

# Threshold adjustment: use different decision thresholds per group
thresholds = {}
for group in groups:
    mask = df[attr] == group
    # Find threshold that equalises FPR across groups
    thresholds[group] = find_threshold(y_true[mask], y_scores[mask], target_fpr)

Document your choice

Whatever mitigation you apply, add a comment in the code and update the model card.


Completion Checklist

Before leaving this skill:

  • Representation checked for all relevant protected attributes
  • Proxy variables identified and decision documented
  • Label quality assessed
  • Disaggregated performance metrics computed and recorded
  • All three fairness metrics computed
  • Any exceeded threshold addressed with documented mitigation
  • Findings written to docs/bias-assessment-<date>.md

Now proceed to fairness-testing to write tests that will catch bias regressions.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.