Ethics
The questions to ask before going to production.
Ethics and the Future of AI
AI ethics suffers from a double and contradictory reputation: too abstract for technical teams, too technical for decision-makers. Both judgments are wrong for the same reason. Most so-called ethical questions come down to measurable quantities, and measuring them requires exactly the skills you acquired in the previous five lessons.
Let’s take an example that will occupy us for a while. A model screens job applications. It was never given the candidates’ sex, age, or origin, a precaution that seems sufficient. It is not, and we will show why in about fifteen lines: the model will recover the information through a correlated variable and produce clearly unequal selection rates. This is not a textbook hypothesis; it is the most common failure mode.
Then comes a more uncomfortable question. Once the inequality is observed, how do you decide whether the model is fair? We will see that several reasonable definitions of fairness exist, that they can all be measured, and that they can lead to opposite verdicts on the same model. There is no technical escape: choosing the definition is a political choice, and it is better to make it explicitly.
The lesson then turns to personal data, explainability, energy cost, the European regulatory framework, and effects on employment. On each of these topics the standard will be the same: distinguish what is established from what is conjectured, and cite no figure that cannot be verified.
Where Bias Comes From
Bias is almost never introduced by the algorithm. It comes from the data, through four distinct routes.
| Source | Mechanism | Example |
|---|---|---|
| Sampling | some groups are underrepresented | a corpus of mostly light-skinned faces |
| Labels | past decisions encode past practices | historically unequal hiring |
| Proxy variables | a neutral variable is correlated with a protected attribute | zip code, type of school, career gap |
| Feedback loop | predictions influence future data | patrolling where offenses have already been recorded |
The third row is the one most often underestimated. Here is a demonstration:
import numpy as np
from sklearn.linear_model import LogisticRegression
rng = np.random.default_rng(0)
n = 2000
groupe = rng.integers(0, 2, n) # protected attribute, 0 or 1
competence = rng.normal(0, 1, n) # true skill, independent of group
# Proxy variable: a career signal correlated with the group,
# with no link to skill.
relais = groupe * 1.5 + rng.normal(0, 0.5, n)
# Historical labels: past decisions favored group 1.
score_historique = competence + 1.2 * groupe + rng.normal(0, 0.3, n)
retenu = (score_historique > 0.8).astype(int)
# The group is NOT given to the model.
X = np.column_stack([competence, relais])
modele = LogisticRegression().fit(X, retenu)
prediction = modele.predict(X)
print(modele.coef_.round(2)) # [[3.61 2.08]]
for g in (0, 1):
m = groupe == g
print(g, round(prediction[m].mean(), 3), round(retenu[m].mean(), 3))
# 0 0.266 0.22
# 1 0.56 0.631
Two results to read together. The proxy variable’s coefficient is 2.08, versus 3.61 for skill: the model relies heavily on a variable that has no predictive power of its own, solely because it is correlated with the protected attribute, which is itself correlated with the historical labels. As a result, the selection rate is 26.6% for group 0 versus 56.0% for group 1, even though skill is distributed identically in both groups by construction.
The model reconstructed the protected attribute without ever receiving it. This is why removing a sensitive column from a dataset is not a fairness measure: it removes the ability to measure the disparity, not the disparity itself.
Let’s verify the diagnosis by removing the proxy variable:
modele_sobre = LogisticRegression().fit(competence.reshape(-1, 1), retenu)
p = modele_sobre.predict(competence.reshape(-1, 1))
for g in (0, 1):
m = groupe == g
print(g, round(p[m].mean(), 3))
# 0 0.424
# 1 0.427
The rates become 42.4% and 42.7%: the gap has disappeared. The proxy variable was indeed the transmission path. Still, you had to keep the protected attribute in the audit dataset to be able to run this calculation.
On real data, the magnitude of these disparities can sometimes be considerable. The Gender Shades study by Joy Buolamwini and Timnit Gebru, published in 2018, evaluated commercial gender classification services on photographs: the error rate reached up to 34.7% for darker-skinned women, versus 0.8% for lighter-skinned men. A single product, advertised with a high overall success rate, therefore behaved very differently depending on who was photographed.
Measuring Fairness Rather Than Swearing to It
Is a disparity in selection rates in itself proof of an unfair model? Not necessarily, and this is where the subject gets serious. Let’s go back to the biased model and measure it differently.
from sklearn.metrics import confusion_matrix
for g in (0, 1):
m = groupe == g
tn, fp, fn, tp = confusion_matrix(retenu[m], prediction[m]).ravel()
print(g, "TPR", round(tp / (tp + fn), 3), "FPR", round(fp / (fp + tn), 3))
# 0 TPR 0.853 FPR 0.101
# 1 TPR 0.834 FPR 0.091
The true positive rate is 85.3% for group 0 and 83.4% for group 1; the false positive rates are 10.1% and 9.1%. These values are nearly identical from one group to the other.
The same model is therefore, simultaneously:
- highly unfair in the sense of demographic parity — 26.6% versus 56.0% selection rates;
- almost perfectly fair in the sense of equal opportunity — the same error rates in each group.
There is no contradiction and no calculation error. The two criteria measure different things. The second asks: “for equal situations with respect to the label, does the model treat the groups the same way?” The answer is yes. But the label itself — the historical decisions — is unequal. A model that faithfully reproduces an unfair practice satisfies equal opportunity while perpetuating the inequality.
| Criterion | What it requires | Verdict here |
|---|---|---|
| Demographic parity | same selection rate per group | fails (0.266 / 0.560) |
| Equal opportunity | same true positive rate per group | satisfied (0.853 / 0.834) |
| Equal error rates | same true and false positive rates | satisfied (0.101 / 0.091) |
Impossibility results established in theoretical computer science show that these criteria generally cannot all be satisfied together, except in degenerate cases. So you have to choose. That choice depends on which question you consider relevant — faithfully reproducing the past, or correcting an imbalance — and that question is not a technical one. The engineer’s role is to make the trade-off visible and quantified, not to settle it alone in a notebook.
Personal Data and Re-identification
Removing the name and address from a file does not anonymize it. The combination of a few ordinary attributes is often enough to single out a person.
from collections import Counter
# (birth year, sex, postal code)
table = [
("1985", "H", "75011"), ("1985", "H", "75011"), ("1985", "F", "75011"),
("1990", "F", "69003"), ("1990", "F", "69003"), ("1962", "H", "33800"),
]
for combinaison, occurrences in sorted(Counter(table).items()):
print(combinaison, occurrences, "UNIQUE" if occurrences == 1 else "")
# ('1962', 'H', '33800') 1 UNIQUE
# ('1985', 'F', '75011') 1 UNIQUE
# ('1985', 'H', '75011') 2
# ('1990', 'F', '69003') 2
Out of six supposedly anonymous rows, two people are uniquely identifiable from the cross-reference of just three ordinary attributes. The principle that generalizes this check is called k-anonymity: require that each combination of quasi-identifying attributes appear at least k times. Here, with k = 2, two rows are non-compliant and should be generalized — age range rather than year, department rather than postal code — or removed.
The General Data Protection Regulation (GDPR), applicable since May 25, 2018, clearly distinguishes two often-confused notions. Pseudonymization replaces direct identifiers with codes: the data remains personal data, with all the associated obligations, because re-identification remains possible. Anonymization in the sense of the regulation requires that re-identification have become reasonably impossible — which the example above shows is difficult to achieve.
Two principles have direct consequences for the design of an AI system:
- Minimization: collect only what is necessary for the stated purpose. “It might be useful for the model later” is not a purpose.
- Purpose limitation: data collected for one use cannot be freely reused to train a model pursuing a different objective.
The reference text is Regulation (EU) 2016/679.
Explaining a Decision
Some models are readable by construction. A shallow tree can be printed and read back:
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, export_text
iris = load_iris()
arbre = DecisionTreeClassifier(max_depth=2, random_state=0).fit(iris.data, iris.target)
print(export_text(arbre, feature_names=list(iris.feature_names), decimals=1))
# |--- petal width (cm) <= 0.8
# | |--- class: 0
# |--- petal width (cm) > 0.8
# | |--- petal width (cm) <= 1.8
# | | |--- class: 1
# | |--- petal width (cm) > 1.8
# | | |--- class: 2
Two comparisons on a single measurement are enough to fully describe this classifier. A person affected by the decision can challenge it on the merits: “my petal width was measured incorrectly.”
For a network with several million parameters, this kind of reading does not exist. You then turn to post hoc explanations: measuring the drop in performance when a variable is scrambled, producing a saliency map on an image, assigning a local weight to each variable for a given prediction. These tools are useful, and one point of honesty is essential: they produce an approximation of the model’s behavior, not the reasoning it actually followed — which does not take the form of reasoning at all. Two explanation methods applied to the same model can, moreover, yield different importances.
A practical consequence follows: when a decision must be justified to the person concerned or to a regulator, choosing an interpretable model from the outset is often safer than adding an explanation layer on top of an opaque model. The performance gap is sometimes zero, and it can be measured.
The stakes are also legal. Article 22 of the aforementioned regulation governs fully automated decisions that produce legal effects or significantly affect a person, and notably provides a right to obtain human intervention.
Energy Cost
Training a model consumes electricity. The order of magnitude can be calculated from three quantities: the number of compute hours, the power draw of the machines, and the carbon intensity of the electrical grid used.
heures_gpu = 10_000 # assumption: 10,000 GPU hours
puissance_kw = 0.4 # order of magnitude for a compute card
pue = 1.2 # data center overhead (cooling, etc.)
energie_kwh = heures_gpu * puissance_kw * pue
print(energie_kwh) # 4800.0
for nom, intensite_g_par_kwh in (("très carboné", 700), ("moyen", 250), ("décarboné", 50)):
print(nom, round(energie_kwh * intensite_g_par_kwh / 1000, 1), "kg CO2e")
# très carboné 3360.0 kg CO2e
# moyen 1200.0 kg CO2e
# décarboné 240.0 kg CO2e
This calculation is not a measurement: it is an estimate built on explicit assumptions, and that is its value. For the same amount of computation, the footprint varies by a factor of 14 depending on the electricity mix. The main lever is therefore not only model optimization: it is where and when the computation is performed.
Two methodological caveats, often missing from announcements:
- Published figures almost always cover the training of a final model, leaving out failed runs and hyperparameter searches, which can account for most of the real cost.
- For a widely used model, cumulative inference eventually exceeds the cost of training. A single training run is visible; billions of requests are less so.
Estimates published in the literature vary widely depending on the methodology and scope chosen. Citing an isolated figure without its assumptions is meaningless, which is why the calculation above lays out its own.
The European Regulatory Framework
The European Union has adopted a dedicated regulation, Regulation (EU) 2024/1689, known as the “AI Act.” Its logic is to scale obligations according to the risk of the use case, not the technique employed: the same algorithm can be out of scope in a video game and high-risk in a hiring process.
| Risk level | Treatment | Examples in the category |
|---|---|---|
| Unacceptable | prohibited | social scoring by public authorities |
| High | strengthened obligations | access to employment, education, credit; certain uses in critical infrastructure |
| Limited | transparency obligations | tell the user they are interacting with an AI, label generated content |
| Minimal | no specific obligation | spam filter, ordinary content recommendation |
The regulation entered into force on August 1, 2024, with application phased in over time: the prohibitions apply first, then the obligations for general-purpose models, and the general regime for high-risk systems later. The precise deadlines and their scope are set out in the text, which is the only source to consult for an operational question: Regulation (EU) 2024/1689. For a system classified as high-risk, the obligations revolve around a few stable areas: quality and governance of training data, technical documentation, logging, user information, effective human oversight, robustness, and cybersecurity. A practitioner will recognize much of this as simply what doing the job properly looks like — and that is no accident: dataset traceability and per-subgroup performance measurement are expected well before they are legally required.
Employment: What We Know and What We Don’t
This is the topic where the temptation to make firm claims is strongest and the empirical base is weakest. Two reference points show the gap between the available estimates.
In 2013, Carl Frey and Michael Osborne estimated that about 47% of U.S. employment fell into a high-risk category for automation. This widely cited figure has been criticized for its method: it assesses entire occupations. In 2016, work carried out within the OECD framework by Melanie Arntz, Terry Gregory, and Ulrich Zierahn repeated the exercise at the level of the tasks that make up each job, and arrived at an order of magnitude of about 9% for the countries studied.
| Study | Year | Unit of analysis | Reported order of magnitude |
|---|---|---|---|
| Frey and Osborne | 2013 | the entire occupation | about 47% of U.S. employment at high risk |
| Arntz, Gregory, and Zierahn (OECD framework) | 2016 | the tasks that make up the job | about 9% of jobs at high risk |
A factor of five between two serious studies of the same subject should be read for what it is: the result depends heavily on the chosen unit of analysis. What is solidly established is more modest, but real:
- Automation affects tasks, not occupations. A job in which 30% of tasks are automated is transformed; it does not automatically disappear.
- The effects are unevenly distributed across sectors, skill levels, and regions. A net national balance masks very different local situations.
- The pace of adoption depends on organizational, regulatory, and cost factors, not just technical feasibility. This gap is what makes ten-year forecasts unreliable.
As for what comes next — future model capabilities, timelines, announced breakthroughs — the honest position is to note that published forecasts have proven unreliable in both directions, and that a prediction with a date attached is an opinion, not a result. This course therefore stops here: it has given you the means to evaluate the claims you will encounter, which is better than handing you one more.
Key Takeaways
- Bias comes from data, through four routes: sampling, labels, proxy variables, and feedback loops. Removing the sensitive attribute does not eliminate the disparity — the model reconstructs it through a proxy and reaches 26.6% versus 56.0% selection rates — it only eliminates the ability to measure it.
- Several definitions of fairness are defensible, all measurable, and generally incompatible with one another. The same model fails demographic parity and satisfies equality of opportunity. The choice of criterion is political; the engineer’s duty is to quantify it and make it visible.
- Three ordinary attributes are enough to re-identify people in an “anonymous” file. Pseudonymizing is not anonymizing, and pseudonymized data remains personal data.
- Post hoc explanations of an opaque model are approximations of its behavior, not its reasoning. When a decision must be justified, an interpretable model chosen from the start is often the best choice.
- For an identical computation, the carbon footprint varies by a factor of 14 depending on the electricity mix. On employment, two serious studies arrive at 47% and 9% depending on whether they reason by occupation or by task: uncertainty is part of the result and must be reported with it.
Comments
Comments are powered by GitHub Discussions
Sign in with GitHub to join the discussion