Dépendance partielle avec courbes ICE
Comment les résultats prédits en mathématiques varient avec la pauvreté et avec la dépense par élève — la moyenne (PDP) sur une courbe par district scolaire (ICE).

Un graphique de dépendance partielle (PDP) montre comment la prédiction du modèle change, en moyenne, quand une variable varie et que toutes les autres gardent leurs valeurs observées. Derrière la moyenne se trouvent les courbes d'espérance conditionnelle individuelle (ICE), une par observation. Des courbes ICE parallèles signifient que l'effet est le même pour tous ; des courbes qui s'écartent ou se croisent révèlent des interactions que la moyenne masque. Les courbes ICE sont centrées sur le bord gauche pour comparer leurs formes plutôt que leurs niveaux ; les traits en bas marquent où se trouvent réellement les données, car ailleurs le modèle extrapole.
Les données sont les 303 districts scolaires californiens du test STAR de 1998, fournis avec statsmodels (sm.datasets.star98) ; la variable à prédire est la part des élèves au-dessus de la médiane nationale en mathématiques, à partir de dix caractéristiques des districts. Les deux panneaux opposent la part d'élèves à faible revenu, le long de laquelle les prédictions chutent fortement, à la dépense par élève, le long de laquelle elles bougent à peine. Le modèle est un gradient boosting, et les courbes viennent de sklearn.inspection.partial_dependence(kind="both"). Un PDP décrit le modèle, pas le monde : il n'est causal que si le modèle l'est.
Le code et le texte à l'intérieur des figures sont en anglais.
import matplotlib.pyplot as plt
import numpy as np
import statsmodels.api as sm
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.inspection import partial_dependence
# Data: 303 California school districts; outcome = % of students above the national median in maths
d = sm.datasets.star98.load_pandas().data
y = 100 * d["NABOVE"] / (d["NABOVE"] + d["NBELOW"])
names = {"LOWINC": "% low-income students", "PERASIAN": "% Asian students", "PERBLACK": "% Black students",
"PERHISP": "% Hispanic students", "AVYRSEXP": "Teacher experience (years)",
"AVSALK": "Teacher salary ($000)", "PERSPENK": "Spending per pupil ($000)",
"PTRATIO": "Pupils per teacher", "PCTAF": "% in college-prep courses",
"PCTYRRND": "% year-round schools"}
X = d[list(names)]
model = GradientBoostingRegressor(learning_rate=0.05, n_estimators=300, max_depth=2,
subsample=0.8, random_state=0).fit(X, y)
features = {"LOWINC": "Low-income students (% of pupils)", "PERSPENK": "Spending per pupil ($ thousands)"}
change = {}
plt.rcParams["figure.constrained_layout.use"] = False # manual margins leave room for the subtitle
fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharey=True)
fig.subplots_adjust(left=0.10, right=0.97, top=0.80, bottom=0.12, wspace=0.08)
for ax, (f, label) in zip(axes, features.items()):
pd_res = partial_dependence(model, X, [f], kind="both", grid_resolution=40)
grid = pd_res["grid_values"][0]
ice = pd_res["individual"][0]
ice_c = ice - ice[:, [0]] # centred ICE
pdp_c = pd_res["average"][0] - pd_res["average"][0][0]
change[f] = np.ptp(pdp_c) # range of the average effect
ax.plot(grid, ice_c.T, color="#007AFF", alpha=0.07, lw=0.8)
ax.plot(grid, pdp_c, color="#FF9500", lw=3, label="Average (PDP)")
lo, hi = np.percentile(ice_c, [10, 90], axis=0)
ax.plot(grid, lo, color="#007AFF", lw=1, ls="--")
ax.plot(grid, hi, color="#007AFF", lw=1, ls="--", label="10th / 90th percentile of ICE")
ax.plot(X[f], np.full(len(X), -46), "|", color="#3A3A3C", ms=8, alpha=0.4) # rug
ax.set_xlabel(label)
ax.set_title(f"Effect of {label.split(' (')[0].lower()}")
axes[0].set_ylim(-50, 12)
axes[0].set_ylabel("Change in predicted % above median\n(points, relative to the lowest value)")
axes[1].legend(loc="center", fontsize=9)
fig.suptitle(f"Poverty lowers predicted maths results by {change['LOWINC']:.0f} points; "
f"spending per pupil moves them by {change['PERSPENK']:.0f}", x=0.02, y=0.97, ha="left")
fig.text(0.02, 0.885, f"Gradient boosting · n = {len(X)} school districts · thin lines = one district (centred ICE) · "
"ticks = observed values", fontsize=9.5, color="#6E6E73")
plt.show()
Les figures utilisent le style PyStatlas (facultatif) : ajoutez plt.style.use("pystatlas.mplstyle") pour obtenir exactement le même rendu.
Source des données
- California STAR test results, 1998 (303 school districts). Gill, J. (2001). Generalized Linear Models: A Unified Approach (Quantitative Applications in the Social Sciences, No. 134). Sage. https://www.statsmodels.org/stable/datasets/generated/star98.html
Original data from the California Department of Education's Standardized Testing and Reporting (STAR) program, 1998. Subset distributed with statsmodels (sm.datasets.star98) with the author's permission.
Les exemples illustrent des méthodes statistiques. Leurs titres décrivent ce que chaque figure montre dans ces données précises — souvent un échantillon restreint, daté ou partiel —, et non la position de l'auteur sur la question de fond. Pour l'interprétation, le contexte et la qualité des données, reportez-vous aux sources originales citées ici.
Comment citer
PyStatlas est créé et maintenu par Thierry Warin. S'il vous a été utile dans vos travaux, merci de le citer.
Warin, T. (2026). Partial dependence with ICE curves. In PyStatlas: A Python Gallery of Statistical Graphics for the Social Sciences. https://warint.github.io/pystatlas/machine-learning/partial-dependence/
@misc{warin2026statlas,
author = {Warin, Thierry},
title = {PyStatlas: A Python Gallery of Statistical Graphics for the Social Sciences},
year = {2026},
howpublished = {\url{https://warint.github.io/pystatlas/}},
note = {Source code: https://github.com/warint/pystatlas}
}Plus dans Apprentissage automatique
Matrice de confusion avec indicateurs
Dans quelle mesure une régression logistique prédit qui a voté Dole en 1996 — matrice de confusion hors échantillon, avec effectifs et parts par ligne, et intervalles bootstrap pour les principaux indicateurs.
yardstick::conf_mat() + autoplot()Courbes précision–rappel
Courbes précision–rappel hors échantillon pour deux classifieurs qui prédisent quelles femmes mariées déclarent une liaison, avec précision moyenne et référence sans compétence.
yardstick::pr_curve() + autoplot()Courbe d'apprentissage
Exactitude d'entraînement et en validation croisée à mesure que l'échantillon d'entraînement grandit, pour deux modèles qui prédisent quelles femmes mariées déclarent une liaison.
caret::learning_curve_dat() + ggplot()