Aller au contenu
English

L'analyse par sous-groupes

  • Leçon 21
  • 55 min
  • Module 7 : Comprendre et choisir le modèle
Leçon 21 sur 27 · Apprentissage automatique : du problème à un modèle fiableL'analyse par sous-groupes

Ce que vous saurez faire

Repérez où le modèle échoue, et pour qui. Un seul résultat global, comme un rappel de 0,470, peut cacher une équipe où le modèle ne détecte presque rien. Un tableau par sous-groupes le montre. Le nombre à côté de chaque taux indique si vous pouvez vous y fier.

Carnet JupyterFaites cette leçon dans un carnet JupyterColab · Kaggle · GitHub · en anglais

Le carnet (notebook) Jupyter contient toutes les cellules, tâches et vérifications de cette leçon, avec les consignes. Ses cellules de préparation installent les paquets et téléchargent les données ainsi que le fichier ticket_model.py du cours. Il ne nécessite donc aucune configuration locale. Lisez les explications ici et exécutez le code dans le carnet.

Le carnet est en anglais. Colab et Kaggle ouvrent votre propre copie. Il faut un compte Google ou Kaggle gratuit. Vous êtes bloqué ? Consultez le carnet de solution.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 55 minutes

Ce que vous devez savoir

Ce qu’il vous faut sur votre ordinateur (seulement pour travailler localement; le carnet n’exige rien de tout cela)

Testé sur macOS avec Python 3.14.6, pandas 3.0.6 et scikit-learn 1.9.1. Les commandes Windows ne sont pas testées. Le carnet a été testé dans Jupyter.

À la fin du module 6, le modèle atteignait la cible de Larkfield pour le mois de validation. Il signale 19,3 % des billets de soutien et détecte 47,0 % des transferts à l’équipe senior. La règle « signaler la priorité 1 » en détecte 33,3 %. C’est un bon résultat, mais c’est un seul chiffre pour 1 179 billets. Avant que l’équipe de Grace se fie au modèle, quelqu’un doit examiner ce que ce chiffre cache. Ce module le fait en quatre étapes :

  1. Cette leçon : où sont les erreurs, et pour quels groupes de billets?
  2. Expliquer les prédictions : quelles caractéristiques font monter ou baisser un score, et ce que cela ne signifie pas.
  3. Quand un modèle simple est meilleur : pourquoi Larkfield garde un modèle simple, et quand la loi ou les bonnes pratiques l’exigent.
  4. L’exploration non supervisée : les clients forment-ils des groupes que le modèle ne voit pas?

Chaque décision de ce module utilise les données de validation (mai 2026). Nous gardons ces données pour vérifier et améliorer le modèle. Vous pouvez consulter les données de test une fois pour le rapport final, mais jamais modifier le modèle selon ces résultats. Les données sont inventées pour ce cours; elles ne représentent aucune personne réelle.

Imaginez un restaurant avec une note moyenne de 4,5 étoiles. Cela semble rassurant. Mais supposons que tous les avis négatifs viennent de personnes qui ont commandé les plats végétariens. Si vous ne mangez pas de viande, les 4,5 étoiles ne vous disent presque rien sur votre soirée. La moyenne mélange deux groupes, et vous faites partie du groupe mal servi.

Le score global d’un modèle pose le même problème. Le rappel, soit la proportion de transferts que le modèle détecte, est de 0,470 en mai. Ce chiffre mélange les billets de paiement, de compte, urgents et moins urgents, reçus par téléphone et par courriel. Si le modèle fonctionne bien pour certains groupes et mal pour d’autres, le chiffre global le cache. Grace dirait alors à son équipe : « Le modèle détecte environ la moitié de tous les transferts. » Pour certains clients, ce serait faux.

La solution est simple : divisez les données en groupes selon une propriété et calculez la même métrique pour chaque groupe. Chaque groupe est un sous-groupe, comme une part découpée dans un gâteau. L’analyse par sous-groupes compare ces parts. Elle répond à une question qu’un seul chiffre global ne peut résoudre : « Le modèle fonctionne-t-il pour toutes les personnes qu’il sert? »

Voici 12 billets inventés de deux équipes. flag représente la décision du modèle (1 = signalé à l’équipe senior), et escalated_72h représente la réalité. Un transfert est détecté lorsque le billet est signalé et transféré.

tiny = pd.DataFrame({
"team": ["payment"] * 8 + ["account"] * 4,
"escalated_72h": [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0],
"flag": [1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0],
})
tiny["caught"] = tiny["flag"] * tiny["escalated_72h"]
print("recall, all tickets:", tiny["caught"].sum() / tiny["escalated_72h"].sum())
print(tiny.groupby("team")[["escalated_72h", "caught"]].sum())

La sortie :

recall, all tickets: 0.5
escalated_72h caught
team
account 2 0
payment 4 3

Vérifiez à la main. Il y a 6 transferts, et le modèle en détecte 3 : un rappel de 3 ÷ 6 = 0,5. Pour les paiements, c’est 3 ÷ 4 = 0,75. Pour les comptes, c’est 0 ÷ 2 = 0. Le résultat global de 0,5 mélange une équipe bien servie et une équipe où le modèle ne détecte rien. Il ne décrit ni l’une ni l’autre.

Regardez maintenant le nombre. L’équipe des comptes n’a que 2 transferts. Un seul transfert détecté de plus fait passer son rappel de 0 à 0,5. Le résultat d’un sous-groupe comporte donc toujours deux éléments : le taux et le nombre sur lequel il repose. Plus loin dans cette leçon, vous verrez comment juger si ce nombre est suffisant.

Avant de créer les sous-groupes, classez les erreurs. Imaginez un mécanicien qui constate qu’une voiture a échoué à son inspection. « Elle a échoué » ne suffit pas pour la réparer. Le mécanicien doit savoir quelle pièce a causé l’échec, et pourquoi. Les erreurs d’un modèle sont semblables : elles ne sont pas toutes du même type.

Un transfert manqué et une fausse alerte ont des coûts différents. Un transfert manqué laisse un client ayant un problème grave attendre dans la file normale. Une fausse alerte coûte environ 10 minutes du temps d’un agent senior. Et un transfert manqué avec un score de 0,18 diffère d’un transfert manqué avec un score de 0,03. Le premier était proche du seuil; un seuil légèrement plus bas le détecterait. Pour le second, le modèle ne voyait aucun risque. Priya utilise donc quatre résultats possibles pour les décisions du modèle et deux questions pour chaque erreur. Le schéma les montre pour les 1 179 billets de mai.

Les 1 179 billets du mois de validation sont répartis selon cette question : signalés, avec un score d'au moins 0,19? 227 sont signalés et 952 ne le sont pas. Parmi les billets signalés, 86 ont été transférés (détectés) et 141 ne l'ont pas été (fausses alertes). Chaque fausse alerte coûte environ 10 minutes du temps d'un agent senior. Parmi les billets non signalés, 855 n'ont pas été transférés (non-signalements corrects). Les 97 billets transférés sont manqués : 42 sont proches du seuil, avec un score entre 0,10 et 0,19. Les 55 autres ont un score faible, inférieur à 0,10. Chaque erreur mène à deux questions : y a-t-il un problème de données (une entrée inconnue ou manquante)? Y a-t-il un problème d'étiquette (la cible ne signifie pas ce que nous pensons)?
La classification des erreurs du modèle final pour le mois de validation, au seuil de 0,19. Deux questions s'appliquent à chaque erreur : un problème de données ou un problème d'étiquette.
Description textuelle du diagramme

Le mois de validation compte 1 179 billets. Première question : le billet est-il signalé, avec un score d’au moins 0,19? 227 billets sont signalés et 952 ne le sont pas.

  • Signalé et transféré : détecté, 86 billets.
  • Signalé et non transféré : fausse alerte, 141 billets. Chacun coûte environ 10 minutes du temps d’un agent senior.
  • Non signalé et non transféré : non-signalement correct, 855 billets.
  • Non signalé et transféré : transfert manqué, 97 billets. 42 sont proches du seuil, avec un score entre 0,10 et 0,19. 55 ont un score faible, inférieur à 0,10.

Pour chaque erreur, posez deux autres questions. Problème de données : une entrée est-elle inconnue ou manquante, empêchant le modèle de bien évaluer le billet? Problème d’étiquette : la cible signifie-t-elle ce que nous pensons, ou son sens a-t-il changé?

Ces deux questions demandent des définitions :

  • Un problème de données est une erreur dans les entrées : une valeur est manquante, inconnue ou incorrecte. Dans ces données, channel et region peuvent valoir unknown (inconnu). Il manque parfois order_value même si le billet concerne une commande.
  • Un problème d’étiquette est une erreur dans la cible. L’étiquette (la valeur cible) peut être incorrecte, ou son sens peut changer. Larkfield a connu un changement : la nouvelle politique de garantie du 1er mai entraîne davantage de transferts des billets de garantie. Un même billet peut recevoir une étiquette différente en mai et en avril.

Priya entraîne le modèle final sur les données d’entraînement et calcule les scores du mois de validation. Le code est le même qu’au module 6. ticket_model.py fournit les colonnes, load() et le pipeline.

from ticket_model import FEATURES, TARGET, build_pipeline, load
train, valid = load("train"), load("valid")
pipeline = build_pipeline().fit(train[FEATURES], train[TARGET])
threshold = 0.19
valid["score"] = pipeline.predict_proba(valid[FEATURES])[:, 1]
valid["flag"] = (valid["score"] >= threshold).astype(int)
print(len(valid), "tickets,", valid["flag"].sum(), "flagged,", valid[TARGET].sum(), "escalated")

La sortie :

1179 tickets, 227 flagged, 183 escalated

Ce sont les chiffres du module 6 : 227 billets signalés (19,3 %). Elle attribue maintenant un résultat à chaque billet. Avant de lire le résultat, faites une prédiction : parmi les 97 transferts manqués, la majorité est-elle proche du seuil ou bien en dessous?

escalated = valid[TARGET] == 1
flagged = valid["flag"] == 1
valid["outcome"] = "correct pass"
valid.loc[flagged & escalated, "outcome"] = "caught"
valid.loc[flagged & ~escalated, "outcome"] = "false alarm"
valid.loc[~flagged & escalated & (valid["score"] >= 0.10), "outcome"] = "missed, near threshold"
valid.loc[~flagged & escalated & (valid["score"] < 0.10), "outcome"] = "missed, low score"
print(valid["outcome"].value_counts())

La sortie :

outcome
correct pass 855
false alarm 141
caught 86
missed, low score 55
missed, near threshold 42
Name: count, dtype: int64

Les nombres correspondent au module 6 : 86 détectés (TP), 141 fausses alertes (FP) et 55 + 42 = 97 manqués (FN). La nouvelle information est la répartition des transferts manqués. 55 des 97 transferts manqués ont un score inférieur à 0,10. Un seuil de 0,10 signalerait 40,3 % des billets, soit deux fois la capacité, et manquerait encore ces 55 transferts. Pour ces billets, le modèle ne voit aucun risque.

Ensuite, les problèmes de données. Priya marque un billet quand channel ou region vaut unknown, ou quand order_value manque hors de l’équipe des comptes. Les billets de compte ne concernent aucune commande; une valeur manquante est donc normale dans ce cas. pd.crosstab compte les billets pour chaque paire de valeurs.

valid["data_problem"] = ((valid["channel"] == "unknown") | (valid["region"] == "unknown")
| (valid["order_value"].isna() & (valid["team"] != "account")))
print(pd.crosstab(valid["outcome"], valid["data_problem"]))

La sortie :

data_problem False True
outcome
caught 80 6
correct pass 785 70
false alarm 134 7
missed, low score 50 5
missed, near threshold 40 2

90 billets ont un problème de données : 7,6 % de tous les billets. Les erreurs représentent 141 + 55 + 42 = 238 billets. Parmi eux, 7 + 5 + 2 = 14 ont un problème de données : 5,9 %. Les erreurs ne viennent donc pas principalement d’entrées incorrectes. Priya note aussi ce résultat. Une vérification qui ne trouve rien reste un élément de preuve : elle indique de chercher la cause ailleurs.

Passons aux sous-groupes. Priya écrit une petite fonction et l’utilise pour chaque colonne. Pour chaque valeur d’une colonne, elle compte les billets, les transferts, les signalements et les transferts détectés. Elle calcule ensuite le taux de transfert (esc_rate), le rappel, la précision et le score moyen.

def slice_table(df, column):
"""Tickets, escalations, flags and recall for each value of one column."""
df = df.assign(caught=df["flag"] * df[TARGET])
table = df.groupby(column).agg(tickets=(TARGET, "size"), escalated=(TARGET, "sum"),
flagged=("flag", "sum"), caught=("caught", "sum"),
mean_score=("score", "mean"))
table["esc_rate"] = table["escalated"] / table["tickets"]
table["recall"] = table["caught"] / table["escalated"]
table["precision"] = table["caught"] / table["flagged"]
return table.round(3)
slice_table(valid, "team")

La sortie :

tickets escalated flagged caught mean_score esc_rate recall precision
team
account 166 12 7 1 0.057 0.072 0.083 0.143
delivery 348 42 39 13 0.092 0.121 0.310 0.333
payment 206 48 91 37 0.214 0.233 0.771 0.407
returns 291 33 40 10 0.098 0.113 0.303 0.250
warranty 168 48 50 25 0.163 0.286 0.521 0.500
Rappel du modèle final pour le mois de validation, par équipe. Le rappel pour tous les billets est de 0,47. Les nombres figurent dans le tableau ci-dessus : l'équipe des comptes n'a que 12 transferts.
Description textuelle du graphique

Un diagramme à colonnes du rappel au seuil de 0,19 pour le mois de validation, par équipe. À titre de comparaison, le rappel pour tous les billets est de 0,47 (86 transferts détectés sur 183). Paiements : 0,77 (37 sur 48). Garantie : 0,52 (25 sur 48). Livraison : 0,31 (13 sur 42). Retours : 0,30 (10 sur 33). Comptes : 0,08 (1 sur 12).

Lisez une colonne à la fois.

  • Le rappel va de 0,771 (paiements) à 0,083 (comptes). Le résultat global de 0,470 ne décrit bien aucune équipe.
  • Le nombre. L’équipe des comptes n’a que 12 transferts; son rappel est donc incertain. Mais toutes les colonnes indiquent que le modèle y voit peu de risque. Le score moyen est de 0,057, le plus faible de toutes les équipes. Les billets de compte sont rarement transférés (7,2 % en mai), alors le modèle leur attribue des scores faibles. Les quelques billets transférés ressemblent aux autres.
  • Le score moyen comparé au taux. Pour la plupart des équipes, les deux sont proches. La garantie fait exception : 28,6 % de ses billets sont transférés, mais le score moyen n’est que de 0,163. Dans les données d’entraînement, le taux de la garantie était de 15,9 %. Le modèle a appris l’ancien sens de « transféré » pour la garantie. C’est le problème d’étiquette du schéma, causé par la politique du 1er mai. C’est aussi l’écart de calibration de Seuils et calibration, observé dans un sous-groupe.

Omar demande : « Alors, le modèle est mauvais pour les clients qui ont un problème de compte? » Priya répond avec les deux nombres : « Il détecte 1 de leurs 12 transferts en mai. Douze, c’est peu, mais les scores vont dans le même sens. Grace devrait savoir que les transferts des comptes arrivent surtout à l’équipe senior par la voie normale. »

Le canal unknown est rare. Le canal vaut unknown quand le service de soutien ne l’a pas enregistré. Le cours de SQL l’a conservé comme catégorie distincte. Priya crée les sous-groupes par canal :

slice_table(valid, "channel")

La sortie :

tickets escalated flagged caught mean_score esc_rate recall precision
channel
chat 373 54 68 24 0.113 0.145 0.444 0.353
email 467 71 86 34 0.114 0.152 0.479 0.395
phone 168 33 52 18 0.172 0.196 0.545 0.346
unknown 22 5 5 3 0.153 0.227 0.600 0.600
web_form 149 20 16 7 0.090 0.134 0.350 0.438

Le canal unknown a le taux de transfert le plus élevé (0,227) et le meilleur rappel (0,600). Les deux chiffres reposent sur 22 billets et 5 transferts. Dans quelle mesure pouvez-vous vous y fier?

Imaginez une pièce de monnaie. Si vous la lancez 4 fois et obtenez 3 fois pile, vous ne dites pas qu’elle favorise pile. Quatre lancers ne suffisent pas : obtenir 3 piles sur 4 arrive souvent avec une pièce équilibrée. Si vous la lancez 400 fois et obtenez 300 piles, la pièce a un problème. La proportion est la même, 75 %, mais le nombre change ce qu’elle peut vous apprendre. Un sous-groupe de 22 billets ressemble aux 4 lancers. Deux vérifications simples le montrent.

Ajoutez ou retirez deux transferts. Si seulement deux billets avaient un résultat différent, le taux serait de 3 ÷ 22 = 0,136 ou de 7 ÷ 22 = 0,318. Pour le courriel, avec 467 billets, le même changement donne 0,148 ou 0,156. Deux billets font varier le petit sous-groupe de 9 points, et le grand de moins d’un demi-point.

L’erreur-type. Le cours de mathématiques donnait une courte formule pour l’erreur-type (SE) d’une proportion p calculée sur n billets. Elle représente la taille habituelle de l’erreur due au hasard :

SE=p (1−p)n\text{SE} = \sqrt{\frac{p\,(1-p)}{n}}
unknown = valid[valid["channel"] == "unknown"]
k, n = int(unknown[TARGET].sum()), len(unknown)
p = k / n
se = (p * (1 - p) / n) ** 0.5
print(f"{k} of {n} escalated: rate {p:.3f}, SE {se:.3f}, 95% interval {p - 1.96 * se:.3f} to {p + 1.96 * se:.3f}")
print("two escalations fewer or more:", round((k - 2) / n, 3), round((k + 2) / n, 3))

La sortie :

5 of 22 escalated: rate 0.227, SE 0.089, 95% interval 0.052 to 0.402
two escalations fewer or more: 0.136 0.318
Sous-groupe Billets Transférés Taux SE Intervalle à 95 %
channel = unknown 22 5 0,227 0,089 0,052 à 0,402
channel = email 467 71 0,152 0,017 0,119 à 0,185
Tout le mois de mai 1 179 183 0,155 0,011 0,135 à 0,176

L’intervalle du canal unknown va de 5 % à 40 %. Il comprend le taux de tous les autres canaux. Les données ne permettent donc pas de dire de façon fiable si ces billets sont transférés plus souvent. Le rappel est encore plus incertain : 3 sur 5. Avec 5 transferts, l’intervalle est plus large que toute la plage de valeurs utiles. (Avec si peu de billets, la formule n’est qu’approximative. Ce qu’il faut retenir, c’est la largeur, pas les limites exactes.)

Les invités sont encore plus rares : 9 billets en mai, avec 1 transfert, détecté. Un rappel de « 1 sur 1 » ne signifie rien. Priya inscrit les deux sous-groupes dans ses notes comme « trop petits pour juger », avec leur nombre, sans les cacher.

Tomás demande : pourquoi ne pas simplement retirer les petits sous-groupes?

Un petit sous-groupe peut quand même compter. Le canal inconnu pourrait croître, et les invités sont de vrais clients. Laissez-le dans le tableau avec son nombre et indiquez « trop petit pour juger ». Le lecteur décide alors s’il faut plus de données. Le retirer cache le fait que le modèle n’a jamais été vérifié pour ces billets.

Grace fixe la priorité de chaque nouveau billet. Elle veut donc savoir comment le modèle se comporte pour chaque priorité.

  1. Exécutez les cellules de l’exemple détaillé pour que valid contienne les colonnes score et flag, et que slice_table() existe.
  2. Avant de passer à l’étape suivante, écrivez une prédiction : quelle priorité a le rappel le plus faible?
  3. Exécutez slice_table(valid, "priority"). Vous devriez voir trois lignes : priorités 1, 2 et 3.
  4. Lisez le rappel de la priorité 3. Vous devriez voir 0,102.
  5. Lisez le nombre de transferts à l’équipe chevronnée pour chaque priorité. Vous devriez voir 61, 63 et 59.
  6. Comptez où se trouvent les 97 transferts manqués. Utilisez escalated − caught pour chaque priorité.
Afficher la sortie et la réponse
tickets escalated flagged caught mean_score esc_rate recall precision
priority
1 163 61 118 50 0.282 0.374 0.820 0.424
2 399 63 90 30 0.148 0.158 0.476 0.333
3 617 59 19 6 0.059 0.096 0.102 0.316

Les transferts manqués sont 61 − 50 = 11 (priorité 1), 63 − 30 = 33 (priorité 2) et 59 − 6 = 53 (priorité 3). Plus de la moitié des transferts manqués concernent des billets de priorité 3. Le modèle détecte 6 de leurs 59 transferts : un rappel de 0,102.

Le sous-groupe est grand : 617 billets et 59 transferts. Le rappel de 0,102 est donc fiable, avec une erreur-type d’environ 0,04. C’est une limite du modèle, pas un effet du hasard. Les billets de priorité 3 sont transférés dans 9,6 % des cas, sous la moyenne de 15,5 %. Le modèle leur donne donc des scores faibles (moyenne de 0,059). Seulement 19 des 617 billets atteignent le seuil. Avec une capacité de 20 % des billets, l’équipe chevronnée voit d’abord les billets plus risqués de priorité 1 et 2.

Grace en conclut : « Donc, un problème grave dans un billet de priorité 3 nous arrive tard, par la voie habituelle. C’était aussi vrai avant le modèle. Mais je ne dois pas dire à mon équipe que le modèle détecte la moitié des transferts. Pour la priorité 3, il en détecte un sur dix. »

Changez une condition : formez les sous-groupes selon le temps plutôt que selon le groupe. Les semaines de mai couvrent les jours 1–7, 8–14, 15–21, 22–28 et 29–31. La dernière « semaine » compte seulement trois jours.

Créez la colonne avec valid["week"] = (valid["created_at"].dt.day - 1) // 7 + 1, puis exécutez slice_table(valid, "week"). Avant de l’exécuter, faites une prédiction : le rappel est-il à peu près le même chaque semaine? Quelle semaine compte le moins de billets?

Afficher la réponse
tickets escalated flagged caught mean_score esc_rate recall precision
week
1 257 49 49 24 0.117 0.191 0.490 0.490
2 262 42 54 23 0.122 0.160 0.548 0.426
3 283 39 56 17 0.124 0.138 0.436 0.304
4 295 44 57 19 0.118 0.149 0.432 0.333
5 82 9 11 3 0.112 0.110 0.333 0.273

Le rappel varie de 0,432 à 0,548 pendant les quatre semaines complètes. Chaque semaine compte seulement 39 à 49 transferts. Un billet fait donc varier le rappel d’environ 2 points, et l’erreur-type est d’environ 0,08. Ces différences s’expliquent par le hasard. La semaine 5 (82 billets, 9 transferts) semble la pire, avec 0,333. Mais un billet détecté de plus porterait son rappel à 0,444.

Le taux de signalement reste proche de la capacité : 49 à 57 billets signalés sur 257 à 295, soit environ 19 % à 21 %. Le seuil de 0,19 a donc tenu pendant tout le mois. Un sous-groupe temporel permet de voir un changement qui commence au milieu d’un mois, comme le changement de politique du 1er mai. Le module 8 utilise la même idée pour surveiller le modèle après sa mise en service.

Erreur courante

Une règle tirée de six billets de test

Symptôme : Tomás produit le tableau des sous-groupes pour le mois de test (juin), pour le rapport final :

test = load("test")
test["score"] = pipeline.predict_proba(test[FEATURES])[:, 1]
test["flag"] = (test["score"] >= threshold).astype(int)
slice_table(test, "channel")
tickets escalated flagged caught mean_score esc_rate recall precision
channel
chat 305 41 57 17 0.119 0.134 0.415 0.298
email 355 52 65 25 0.119 0.146 0.481 0.385
phone 155 32 51 21 0.172 0.206 0.656 0.412
unknown 23 6 4 0 0.120 0.261 0.000 0.000
web_form 164 26 19 7 0.090 0.159 0.269 0.368

Le canal unknown (inconnu) : 6 transferts, 0 détecté. Tomás dit : « Le modèle échoue sur les billets dont le canal est inconnu. Signalons-les tous, ou abaissons leur seuil. »

Cause : deux erreurs dans une seule décision. D’abord, 6 transferts sont beaucoup trop peu pour juger. En mai, le même sous-groupe en a détecté 3 sur 5. Un mois donne 0,600, le suivant 0,000, et les deux résultats sont du bruit. Ensuite, les données de test servent au rapport final. Une règle créée à partir d’un résultat de test transforme les données de test en secondes données de validation. Le score final n’est alors plus une estimation honnête. C’est l’erreur de « réglage sur les données de test » de Régler les hyperparamètres, sous une nouvelle forme.

Solution : présentez le sous-groupe avec son effectif : « canal inconnu : 0 transfert détecté sur 6 en juin; trop peu pour juger ». Ne changez ni le modèle ni le seuil. Si le sous-groupe compte, recueillez plus de données et décidez sur les données de validation, avec un intervalle. Ici, mai et juin réunis donnent 3 transferts détectés sur 11, encore trop peu.

Conséquence dans le travail en IA : une règle tirée de quelques billets de test ajoute du travail à l’équipe chevronnée sans gain démontré. Et le rapport de l’équipe présente maintenant un score de test trop bon. Les petits sous-groupes produisent les taux les plus extrêmes. Ils produisent donc le plus de ces « découvertes ».

Vérifiez votre compréhension

Le rappel du modèle en mai est de 0,470. Grace dit : le modèle détecte environ la moitié des transferts, pour chaque équipe. Que dit le tableau des sous-groupes, et quels nombres lui donnez-vous?

Afficher la réponse

Le rappel global est de 0,470, mais il varie beaucoup selon l’équipe. Les paiements ont un rappel de 0,771 (37 sur 48), les garanties de 0,521 (25 sur 48), les livraisons de 0,310 (13 sur 42), les retours de 0,303 (10 sur 33) et les comptes de 0,083 (1 sur 12). Par priorité, le modèle détecte 0,820 des transferts de priorité 1 et 0,102 de ceux de priorité 3 (6 sur 59). Donnez-lui chaque rappel avec son effectif. Le nombre global mélange les sous-groupes et n’en décrit aucun correctement.

Vérifiez votre compréhension

Faites une prédiction : le canal inconnu compte 22 billets et 5 transferts en mai. Si deux de ces billets avaient une issue différente, de combien le taux de transfert pourrait-il varier? Qu'écrivez-vous dans le rapport?

Afficher la réponse

De 0,227 à 0,136 (deux de moins) ou à 0,318 (deux de plus) : environ 9 points dans chaque direction. L’erreur-type est de 0,089. L’intervalle à 95 % va d’environ 0,05 à 0,40 et inclut les taux de tous les autres canaux. Dans le rapport, écrivez le taux avec son effectif et dites « trop petit pour juger ». Par exemple : « canal inconnu : 5 billets transférés sur 22 (23 %); trop peu de billets pour comparer aux autres canaux ». N’omettez pas le sous-groupe et n’agissez pas sur ce résultat.

Vérifiez votre compréhension

Parmi les 97 transferts manqués en mai, 55 ont un score inférieur à 0,10. Est-ce un problème de données, un problème d'étiquettes ou une limite du modèle? Donnez les preuves.

Afficher la réponse

C’est surtout une limite du modèle. Seulement 14 des 238 erreurs présentent un problème de données : canal ou région inconnus, ou montant de commande manquant. Cette proportion est plus faible que dans l’ensemble des billets. Les mauvaises entrées n’expliquent donc pas les transferts manqués. Parmi les 55 transferts manqués à faible score, 40 concernent des billets de priorité 3. Leurs caractéristiques ressemblent à celles de billets ordinaires à faible risque. Le modèle ne voit donc aucun risque. Un problème d’étiquettes s’ajoute à cela. Les billets de garantie sont transférés dans 28,6 % des cas en mai. Mais le modèle, entraîné avant le changement de politique, leur donne un score moyen de 0,163.

Récapitulatif

  • Un sous-groupe est une partie des données choisie selon une propriété. L’analyse par sous-groupes calcule la même métrique pour chacun, car un nombre global peut cacher un groupe faible.
  • Classez d’abord les erreurs : détecté, fausse alerte, manqué près du seuil, manqué avec un score faible. Puis demandez-vous pour chaque erreur : est-ce un problème de données ou un problème d’étiquettes?
  • En mai, 55 des 97 transferts manqués ont un score inférieur à 0,10. Le rappel est de 0,771 pour les paiements, de 0,083 pour les comptes et de 0,102 pour la priorité 3. Les garanties sont transférées dans 28,6 % des cas, mais leur score moyen est de 0,163 : le changement de politique crée un problème d’étiquettes.
  • Placez l’effectif à côté de chaque taux. Un taux calculé sur 22 billets varie de 9 points quand deux billets changent. Son intervalle à 95 % va de 5 % à 40 %.
  • Décidez sur les données de validation. Présentez les sous-groupes de test, mais n’agissez jamais sur leurs résultats.

Ensuite, vous regardez à l’intérieur du modèle : quelles caractéristiques font monter ou baisser un score, et pourquoi elles ne causent pas le transfert.

Leçon suivante : Expliquer les prédictions