This page is an ipython notebook, meaning you can download it and run the executable cells. It directly follows Activity 8.1. Reference answers appear after the questions, challenges, predictions, and reflections. They show one reasonable solution or interpretation, but other correct approaches may exist.
Ethics, Fairness, Accountability & Transparency¶
Tools: Python, pandas, NumPy, matplotlib/seaborn, Jupyter/VS Code
Learning objectives¶
By the end of this tutorial, you should be able to:
identify several forms of bias in a data workflow;
evaluate group representation;
calculate group-specific classification metrics;
compute demographic parity, true-positive rates, and false-positive rates;
investigate threshold tradeoffs;
quantify uncertainty from small subgroup samples;
identify proxy and measurement concerns;
write a compact model card;
document intended and out-of-scope uses;
design a basic monitoring plan;
distinguish technical performance from responsible deployment.
notebooks/week15_ethics.ipynbImport:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as snsCreate:
rng = np.random.default_rng(
556
)n = 1000
group = rng.choice(
["A", "B"],
size=n,
p=[
0.7,
0.3
]
)
score = rng.normal(
0,
1,
size=n
)
group_shift = np.where(
group == "A",
0.2,
-0.2
)
latent = (
score
+ group_shift
+ rng.normal(
0,
0.8,
size=n
)
)
y_true = (
latent > 0
).astype(int)
predicted_probability = (
1
/ (
1
+ np.exp(
-(
1.4 * score
+ 0.2
)
)
)
)
df = pd.DataFrame({
"group": group,
"score": score,
"y_true": y_true,
"probability": predicted_probability
})Inspect:
df.head()
df.shapeImportant¶
This dataset is synthetic.
The purpose is to study fairness concepts without making claims about any real population.
df["group"].value_counts()and:
df["group"].value_counts(
normalize=True
)Questions¶
Are the groups equally represented?
Is unequal representation automatically unfair?
What additional context would you need?
pd.crosstab(
df["group"],
df["y_true"],
normalize="index"
)Question¶
Do base rates differ across groups?
Why could that matter when interpreting fairness metrics?
Reference answer¶
Unequal representation is not automatically unfair. Interpretation needs context about the target population, sampling process, intended use, historical selection, and uncertainty for smaller groups.
THRESHOLD = 0.5Create:
df["y_pred"] = (
df["probability"]
>= THRESHOLD
).astype(int)Inspect:
pd.crosstab(
df["group"],
df["y_pred"],
normalize="index"
)Reference answer¶
Different base rates matter because fairness metrics condition on different events. The same classifier can have different TPR, FPR, PPV, and positive rates across groups even with one threshold.
Part 5 — Overall accuracy¶
Calculate:
accuracy = (
df["y_pred"]
== df["y_true"]
).mean()
accuracyQuestion¶
Does this value tell you whether performance is similar across groups?
group_accuracy = (
df.assign(
correct=(
df["y_pred"]
== df["y_true"]
)
)
.groupby(
"group"
)["correct"]
.mean()
)
group_accuracyReflection¶
How does this change your understanding of model performance?
Reference answer¶
Overall accuracy does not show whether groups have similar performance. Group-specific metrics are needed because aggregate accuracy can hide subgroup disparities.
def confusion_counts(
data
):
tp = (
(
data["y_true"] == 1
)
& (
data["y_pred"] == 1
)
).sum()
tn = (
(
data["y_true"] == 0
)
& (
data["y_pred"] == 0
)
).sum()
fp = (
(
data["y_true"] == 0
)
& (
data["y_pred"] == 1
)
).sum()
fn = (
(
data["y_true"] == 1
)
& (
data["y_pred"] == 0
)
).sum()
return {
"tp": tp,
"tn": tn,
"fp": fp,
"fn": fn
}Test on each group.
Reference answer¶
Confusion counts separate true positives, false positives, true negatives, and false negatives, revealing which error types differ across groups.
def classification_metrics(
data
):
c = confusion_counts(
data
)
tpr = (
c["tp"]
/ (
c["tp"]
+ c["fn"]
)
)
fpr = (
c["fp"]
/ (
c["fp"]
+ c["tn"]
)
)
ppv = (
c["tp"]
/ (
c["tp"]
+ c["fp"]
)
)
positive_rate = (
data["y_pred"]
.mean()
)
return {
"tpr": tpr,
"fpr": fpr,
"ppv": ppv,
"positive_rate": positive_rate
}Reference answer¶
Positive prediction rate, TPR, FPR, PPV, and accuracy use different denominators and answer different operational questions.
Part 9 — Calculate group metrics¶
Run:
metrics = {}
for group_name, subset in df.groupby(
"group"
):
metrics[
group_name
] = classification_metrics(
subset
)
pd.DataFrame(
metrics
).TInterpret each column.
dp_difference = (
metrics["A"][
"positive_rate"
]
- metrics["B"][
"positive_rate"
]
)
dp_differenceReference answer¶
Demographic parity compares positive prediction rates. A difference near zero means similar selection rates, not that all other fairness criteria are satisfied.
tpr_difference = (
metrics["A"][
"tpr"
]
- metrics["B"][
"tpr"
]
)
tpr_differenceInterpret:
Among truly positive cases, how differently are groups treated?
Reference answer¶
Equal opportunity compares TPR. A difference near zero means truly positive cases are detected at similar rates, but it does not establish overall fairness.
fpr_difference = (
metrics["A"][
"fpr"
]
- metrics["B"][
"fpr"
]
)
fpr_differenceQuestion¶
Why might this matter even if true-positive rates are equal?
Reference answer¶
FPR difference asks how differently truly negative cases are incorrectly labeled positive. This matters because false positives can carry substantial costs.
metrics["A"]["ppv"]with:
metrics["B"]["ppv"]Question¶
What does PPV answer that TPR does not?
Reference answer¶
Predictive parity compares PPV: among predicted-positive cases, how often is the prediction correct? It can differ even when TPR is similar.
group
n
base_rate
positive_rate
accuracy
TPR
FPR
PPVRound only for display.
Do not round intermediate calculations.
Reference answer¶
TPR conditions on actual positives; PPV conditions on predicted positives. They answer different questions and respond differently to prevalence.
sns.barplot(
data=metric_long,
x="metric",
y="value",
hue="group"
)Reflection¶
Which differences are most visually substantial?
Part 16 — Sample size beside metrics¶
Add group counts to your metric report.
Question¶
Why should a fairness metric never be interpreted without knowing how many observations support it?
Reference answer¶
Metric differences should be interpreted with group sample sizes and uncertainty. Smaller groups produce noisier estimates, so a fairness metric without its supporting n can mislead.
Part 17 — Bootstrap uncertainty for TPR¶
Use Week 11’s bootstrap logic.
For each group:
select the group’s rows;
bootstrap rows with replacement;
calculate TPR for each bootstrap sample;
calculate a 95% percentile interval.
Important¶
Handle bootstrap samples where a denominator becomes zero.
Reflection¶
How much uncertainty is there around each group’s TPR?
small_b = (
df.loc[
df["group"] == "B"
]
.sample(
n=30,
random_state=556
)
)thresholds = np.linspace(
0.1,
0.9,
17
)For each threshold:
generate predictions;
calculate TPR by group;
calculate FPR by group;
calculate positive rate by group.
Store results.
Reference answer¶
Smaller samples yield wider bootstrap intervals. Increasing a threshold generally lowers positive prediction rate, TPR, and FPR, exposing tradeoffs rather than a universally best threshold.
Part 20 — Plot threshold tradeoffs¶
Plot:
threshold vs. TPR
threshold vs. FPR
threshold vs. positive rateby group.
Questions¶
Does one threshold optimize every metric?
What tradeoffs become visible?
Which decisions are technical, and which are policy choices?
Part 21 — Compare overall and subgroup optimization¶
Find the threshold with highest overall accuracy.
Then inspect group-specific metrics at that threshold.
Reflection¶
Does maximizing aggregate accuracy guarantee acceptable subgroup performance?
Reference answer¶
Threshold selection combines technical evidence with policy/value judgments. An overall optimum can mask subgroup tradeoffs, so inspect both overall and group-specific objectives.
df["prob_bin"] = pd.cut(
df["probability"],
bins=np.linspace(
0,
1,
6
),
include_lowest=True
)Calculate by:
group
probability binthe:
mean predicted probability
observed positive rate
countPlot predicted vs. observed.
equal TPR?
equal FPR?
equal positive rates?Explain why fairness definitions are not interchangeable.
Reference answer¶
Calibration asks whether cases assigned a given probability experience the outcome at approximately that rate. Calibration can differ by group even when discrimination metrics are similar.
region_code
school_id
neighborhood_scoreand group membership is removed.
Discuss:
Could these variables still contain group information?
Would removing
groupmake auditing easier or harder?Why is “fairness through unawareness” incomplete?
No code is required.
Reference answer¶
Fairness definitions are not interchangeable because they condition on different events and represent different harms/goals. With unequal base rates, several criteria may be impossible to satisfy simultaneously.
prior system approvalrather than:
true future successQuestions¶
What exactly would the model learn?
Could historical bias enter the label?
Would excellent predictive accuracy solve this problem?
Reference answer¶
Removing group membership does not remove information about group membership if other variables act as proxies. Measurement choices can also encode historical inequalities.
audit = df.copy()
missing_index = (
audit.loc[
audit["group"] == "B"
]
.sample(
frac=0.2,
random_state=556
)
.index
)
audit.loc[
missing_index,
"score"
] = np.nanCalculate missingness by group.
Question¶
What process might produce unequal missingness in a real system?
Reference answer¶
A model trained on historically biased labels can learn that bias accurately. High predictive accuracy does not prove that the target label or decision process is ethically appropriate.
name
email
date_of_birth
ZIP code
group
score
outcome
device ID
full browsing historyThe model requires only a subset.
Write:
Keep:
Do not keep:
Need justification:Reference answer¶
Unequal missingness can arise from access, measurement, reporting, workflow, or follow-up differences. Audit missingness by group because missing-data handling can change the represented population.
## Intended use
This model is intended to...Include:
who should use it;
what decision it supports;
what population it was evaluated on.
Reference answer¶
Data minimization means collecting only information necessary for the stated purpose, reducing privacy risk, misuse opportunities, storage burden, and proxy-variable exposure.
## Out-of-scope useGive at least three examples of uses that are not supported by the analysis.
Question¶
Why is documenting misuse risk important?
Reference answer¶
Intended use should state the supported decision, users, population, setting, outputs, and evaluation context.
overall accuracy
group-specific accuracy
TPR by group
FPR by group
PPV by group
positive rate by group
sample size by groupInclude uncertainty where possible.
Reference answer¶
Document out-of-scope uses because technically possible use is not the same as validated use. This makes foreseeable misuse and unsupported extrapolation explicit.
synthetic data
sample representativeness
measurement validity
small subgroup uncertainty
threshold dependence
distribution shift
proxy variablesBe specific.
Reference answer¶
Limitations can include representativeness, label/measurement quality, subgroup sample sizes, uncertainty, distribution shift, proxy variables, and limits to generalization.
## Accountability
Model owner:
Decision owner:
Monitoring owner:
Escalation path:
Appeal/review mechanism:Reflection¶
Why should these roles be explicit before deployment?
Reference answer¶
Accountability should specify who owns deployment decisions, monitors outcomes, investigates failures, can halt/override the system, and handles appeals or review.
## TransparencyDescribe:
what the model outputs;
what information users should see;
what limitations should be communicated;
what should not be implied.
Reference answer¶
Roles must be explicit before deployment so monitoring, escalation, maintenance, and responsibility do not fall between teams.
Metric
Frequency
Population/subgroup
Alert condition
Owner
ActionInclude at least:
overall performance
TPR/FPR by group
missingness
calibration
data driftReference answer¶
Transparency should explain what the model outputs, what evidence/uncertainty users can see, known limitations, and what the output should not be interpreted to mean.
Part 35 — Distribution-shift simulation¶
Create a future dataset where:
future_score = rng.normal(
0.5,
1.2,
size=n
)Apply the same model formula and threshold.
Compare current vs. future:
probability distribution
accuracy
positive rate
group metricsQuestion¶
Why can a previously validated model become inappropriate?
Reference answer¶
Distribution shift occurs when future data differ from training/evaluation data. Compare distributions and performance over time to detect degradation.
model labels individuals high risk
↓
they receive more scrutiny
↓
more negative events are recorded
↓
future training data contain more negativesAnswer:
Is the future label independent of model deployment?
What monitoring could reveal this?
How might this affect retraining?
Reference answer¶
A previously validated model can become inappropriate because populations, measurement systems, policies, incentives, and base rates change over time.
Govern
Map
Measure
ManageFor your fictional screening system, write one concrete action for each.
Example structure:
Govern:
Map:
Measure:
Manage:Reference answer¶
Map actions to Identify, Measure, Manage, and Govern: document context/risks; quantify performance/fairness/uncertainty; implement mitigations/monitoring; assign responsibility/review processes.
Part 38 — Responsible deployment decision¶
Choose one:
Deploy
Deploy with safeguards
Do not deploy yetWrite a one-paragraph justification based on:
technical performance;
subgroup metrics;
uncertainty;
limitations;
accountability;
monitoring readiness.
There is no automatically correct answer.
The reasoning matters.
What problem is the system solving?
Who is affected?
What assumptions are being made?
What data limitations exist?
What groups may experience different errors?
Which fairness metric matters most here, and why?
What metric conflicts exist?
How uncertain are subgroup estimates?
What should users be told?
Who is accountable?
How will harm be detected after deployment?
What would trigger suspension or retraining?Reference answer¶
A defensible ethics audit ties conclusions to the problem, assumptions, data limitations, subgroup errors, uncertainty, relevant fairness criteria, accountability, and monitoring readiness.
Part 40 — Git checkpoint¶
Run:
git statusCommit:
git add .
git commit -m "Complete Week 15 responsible data science exercises"
git pushPart 41 — Final course reflection¶
Answer in Markdown.
1. Technical correctness¶
Why is correct code not sufficient for responsible data science?
2. Bias¶
What is the difference among selection, historical, and measurement bias?
3. Fairness¶
Why is there no single universally correct fairness metric?
4. Error rates¶
Why must false positives and false negatives be interpreted in context?
5. Transparency¶
What information should users know about a model?
6. Accountability¶
Why should responsibility remain with people and organizations rather than “the algorithm”?
7. Documentation¶
How do model cards and data documentation improve responsible practice?
8. Monitoring¶
Why must responsible evaluation continue after deployment?
9. Reproducibility¶
How does reproducibility support accountability?
10. STA 556¶
Which technical practice from this course most improves your ability to build trustworthy statistical workflows?
Completion checklist¶
Created Week 15 notebook
Generated a synthetic classification dataset
Audited group representation
Compared base rates
Applied a classification threshold
Calculated overall accuracy
Calculated subgroup accuracy
Built confusion-matrix counts
Calculated TPR
Calculated FPR
Calculated PPV
Calculated positive prediction rate
Calculated demographic-parity difference
Calculated equal-opportunity difference
Compared false-positive rates
Compared predictive parity
Built a group metric table
Visualized subgroup metrics
Reported subgroup sample sizes
Bootstrapped uncertainty for a fairness metric
Investigated a small subgroup
Swept classification thresholds
Visualized threshold tradeoffs
Compared overall vs. subgroup optimization
Audited calibration by group
Discussed proxy variables
Discussed label/measurement bias
Audited missingness by group
Completed a data-minimization exercise
Wrote intended-use documentation
Wrote out-of-scope-use documentation
Created a model-card performance section
Documented limitations
Defined accountability roles
Wrote a transparency section
Designed a monitoring plan
Simulated distribution shift
Discussed feedback loops
Mapped the project to Govern/Map/Measure/Manage
Made a responsible deployment recommendation
Completed the final ethics audit
Committed Week 15 work to Git
Pushed work to GitHub
What you should now understand¶
Technically correct workflow
↓
Ethical problem definition
↓
Representative + appropriate data
↓
Performance + subgroup evaluation
↓
Fairness tradeoffs
↓
Transparency + documentation
↓
Accountability
↓
Monitoring
↓
Responsible statistical practiceThis completes STA 556: from computational foundations and data engineering through reproducibility, numerical methods, testing, performance, and responsible data science.
Reference answer¶
Correct code is necessary but not sufficient: responsible data science also requires valid targets, representative data, contextual interpretation of errors, justified fairness criteria, transparency, accountability, data minimization, and ongoing monitoring.