Aller au contenu
English

Choisir une séparation

  • Leçon 14
  • 50 min
  • Module 5 : Préparer la modélisation sans risque

Ce que vous saurez faire

Choisissez les billets de soutien qui servent à l’apprentissage et ceux qui servent au test. Le test doit ressembler au travail réel du modèle. Une mauvaise séparation donne un score peu fiable, sans produire d’erreur.

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

Le carnet (notebook) Jupyter contient tous les scripts, tâches et vérifications de cette leçon, avec les consignes. Ses cellules de préparation installent pandas, téléchargent les données d’exercice et reconstruisent la table de modélisation de la leçon 1. Il fonctionne donc sans le projet local. Lisez les explications et utilisez l’explorateur ici. 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 50 minutes

Ce que vous devez savoir

Ce qu’il vous faut sur votre ordinateur (seulement pour travailler localement; le carnet n’en a pas besoin)

Testé sur macOS avec Python 3.14.6 et pandas 3.0.6. Le carnet a été testé dans Jupyter.

Un modèle n’est utile que pour les billets qu’il n’a pas vus. Vous gardez donc certains billets à part pour le tester plus tard. Une séparation divise les lignes de la table de modélisation en parties qui ont des rôles différents :

Partie Rôle Règle
Données d’entraînement Le modèle apprend à partir de ces lignes. Tout ce qui apprend des données utilise seulement ces lignes : le modèle et, dans la leçon 3, le prétraitement.
Données de validation Vous comparez les versions et choisissez les réglages avec ces lignes. Vous consultez leur score plusieurs fois.
Données de test Un seul score final, honnête. Vous consultez leur score une fois, à la fin. Si vous modifiez ensuite le modèle, les données de test deviennent de nouvelles données de validation.

La question de cette leçon est de savoir quelles lignes vont dans chaque partie. Il existe trois réponses courantes.

Voici huit billets de trois clients, en ordre chronologique. Chaque séparation place six billets dans les données d’entraînement et deux dans les données de test. Ce petit exemple n’a pas de données de validation :

Billet Client Création Aléatoire Par date Par client
T-1 A 10 janvier entraînement entraînement entraînement
T-2 B 2 février test entraînement test
T-3 A 20 février entraînement entraînement entraînement
T-4 C 15 mars entraînement entraînement entraînement
T-5 B 5 avril entraînement entraînement test
T-6 A 30 avril test entraînement entraînement
T-7 C 20 mai entraînement test entraînement
T-8 A 12 juin entraînement test entraînement
  • Séparation aléatoire : chaque ligne va dans l’entraînement ou le test au hasard. T-7 et T-8, les billets les plus récents, servent à l’entraînement. Le modèle apprend avec mai et juin, puis passe un test sur février et avril.
  • Séparation par date : tout ce qui précède une date sert à l’entraînement, et tout ce qui suit sert au test. Le modèle apprend du passé et passe un test sur l’avenir, comme en utilisation réelle.
  • Séparation par client (une séparation par groupe) : tous les billets d’un client vont dans la même partie. Le client B est seulement dans le test. Le test demande donc : comment le modèle fonctionne-t-il pour un client qu’il n’a jamais vu?

Aucune méthode ne convient toujours. La bonne séparation reproduit l’utilisation du modèle. Posez trois questions :

  1. Le modèle prédira-t-il l’avenir à partir du passé? Séparez alors par date. Presque tous les modèles en entreprise font cela.
  2. Le modèle rencontrera-t-il de nouveaux clients, patients, magasins ou machines? Gardez alors chaque groupe dans une seule partie.
  3. Les lignes sont-elles indépendantes, sans ordre chronologique ni groupes répétés? Seulement dans ce cas, une séparation aléatoire donne un test juste.

L’explorateur contient 60 billets fictifs de six clients, de janvier à juin. Le taux de transfert est de 12,5 % avant le 1er mai et de 20 % après, comme dans les données réelles. Le client C-06 est nouveau : son premier billet date de mai.

Explorer

Aléatoire, par date ou par client

Billets en entraînement / validation / test
42 / 9 / 9
Escaladés en entraînement
14,3 %6 billets sur 42
Escaladés en test
11,1 %1 billet sur 9
Billets de test dont le client est aussi en entraînement
9 sur 9
Billets d’entraînement de juin (le mois le plus récent)
6 sur 42

Découpage aléatoire, tirage 1 : chaque partie a des billets de plusieurs mois. L’entraînement a 6 billets de juin, et le test a 4 billets de janvier à avril. Le modèle apprend donc avec des billets plus récents que ceux sur lesquels on le teste. Appuyez sur « Nouveau tirage » pour voir combien les taux changent.

  • Entraînement
  • Validation
  • Test
  • Anneau : billet escaladé
janv.févr.marsavr.maijuinC-01C-02C-03C-04C-05C-061er mai1er juinT-01, C-02, 4 janv. : EntraînementT-02, C-01, 5 janv. : Entraînement, escaladéT-03, C-04, 6 janv. : EntraînementT-04, C-05, 9 janv. : EntraînementT-05, C-03, 11 janv. : EntraînementT-06, C-01, 15 janv. : ValidationT-07, C-02, 20 janv. : TestT-08, C-03, 21 janv. : ValidationT-09, C-01, 27 janv. : EntraînementT-10, C-04, 27 janv. : ValidationT-11, C-03, 5 févr. : EntraînementT-12, C-01, 6 févr. : Entraînement, escaladéT-13, C-02, 6 févr. : EntraînementT-14, C-01, 12 févr. : EntraînementT-15, C-05, 12 févr. : EntraînementT-16, C-04, 19 févr. : ValidationT-17, C-02, 21 févr. : TestT-18, C-03, 21 févr. : EntraînementT-19, C-01, 22 févr. : EntraînementT-20, C-05, 25 févr. : EntraînementT-21, C-03, 6 mars : EntraînementT-22, C-05, 6 mars : EntraînementT-23, C-04, 7 mars : EntraînementT-24, C-02, 9 mars : EntraînementT-25, C-01, 10 mars : EntraînementT-26, C-02, 16 mars : ValidationT-27, C-02, 23 mars : Entraînement, escaladéT-28, C-05, 24 mars : EntraînementT-29, C-03, 26 mars : TestT-30, C-01, 27 mars : EntraînementT-31, C-04, 29 mars : EntraînementT-32, C-02, 5 avr. : EntraînementT-33, C-05, 5 avr. : EntraînementT-34, C-04, 10 avr. : Entraînement, escaladéT-35, C-01, 11 avr. : Validation, escaladéT-36, C-03, 12 avr. : EntraînementT-37, C-02, 21 avr. : EntraînementT-38, C-03, 21 avr. : EntraînementT-39, C-04, 24 avr. : EntraînementT-40, C-05, 28 avr. : TestT-41, C-01, 3 mai : TestT-42, C-06, 8 mai : EntraînementT-43, C-02, 11 mai : EntraînementT-44, C-04, 13 mai : EntraînementT-45, C-05, 18 mai : EntraînementT-46, C-06, 18 mai : EntraînementT-47, C-01, 19 mai : Entraînement, escaladéT-48, C-03, 25 mai : TestT-49, C-06, 27 mai : TestT-50, C-02, 29 mai : Test, escaladéT-51, C-04, 3 juin : Entraînement, escaladéT-52, C-03, 4 juin : EntraînementT-53, C-06, 5 juin : ValidationT-54, C-01, 9 juin : ValidationT-55, C-06, 16 juin : EntraînementT-56, C-03, 18 juin : EntraînementT-57, C-01, 22 juin : Validation, escaladéT-58, C-02, 25 juin : EntraînementT-59, C-04, 28 juin : TestT-60, C-06, 28 juin : Entraînement
janv.févr.marsavr.maijuinC-01C-02C-03C-04C-05C-061er mai1er juinT-01, C-02, 4 janv. : EntraînementT-02, C-01, 5 janv. : Entraînement, escaladéT-03, C-04, 6 janv. : EntraînementT-04, C-05, 9 janv. : EntraînementT-05, C-03, 11 janv. : EntraînementT-06, C-01, 15 janv. : ValidationT-07, C-02, 20 janv. : TestT-08, C-03, 21 janv. : ValidationT-09, C-01, 27 janv. : EntraînementT-10, C-04, 27 janv. : ValidationT-11, C-03, 5 févr. : EntraînementT-12, C-01, 6 févr. : Entraînement, escaladéT-13, C-02, 6 févr. : EntraînementT-14, C-01, 12 févr. : EntraînementT-15, C-05, 12 févr. : EntraînementT-16, C-04, 19 févr. : ValidationT-17, C-02, 21 févr. : TestT-18, C-03, 21 févr. : EntraînementT-19, C-01, 22 févr. : EntraînementT-20, C-05, 25 févr. : EntraînementT-21, C-03, 6 mars : EntraînementT-22, C-05, 6 mars : EntraînementT-23, C-04, 7 mars : EntraînementT-24, C-02, 9 mars : EntraînementT-25, C-01, 10 mars : EntraînementT-26, C-02, 16 mars : ValidationT-27, C-02, 23 mars : Entraînement, escaladéT-28, C-05, 24 mars : EntraînementT-29, C-03, 26 mars : TestT-30, C-01, 27 mars : EntraînementT-31, C-04, 29 mars : EntraînementT-32, C-02, 5 avr. : EntraînementT-33, C-05, 5 avr. : EntraînementT-34, C-04, 10 avr. : Entraînement, escaladéT-35, C-01, 11 avr. : Validation, escaladéT-36, C-03, 12 avr. : EntraînementT-37, C-02, 21 avr. : EntraînementT-38, C-03, 21 avr. : EntraînementT-39, C-04, 24 avr. : EntraînementT-40, C-05, 28 avr. : TestT-41, C-01, 3 mai : TestT-42, C-06, 8 mai : EntraînementT-43, C-02, 11 mai : EntraînementT-44, C-04, 13 mai : EntraînementT-45, C-05, 18 mai : EntraînementT-46, C-06, 18 mai : EntraînementT-47, C-01, 19 mai : Entraînement, escaladéT-48, C-03, 25 mai : TestT-49, C-06, 27 mai : TestT-50, C-02, 29 mai : Test, escaladéT-51, C-04, 3 juin : Entraînement, escaladéT-52, C-03, 4 juin : EntraînementT-53, C-06, 5 juin : ValidationT-54, C-01, 9 juin : ValidationT-55, C-06, 16 juin : EntraînementT-56, C-03, 18 juin : EntraînementT-57, C-01, 22 juin : Validation, escaladéT-58, C-02, 25 juin : EntraînementT-59, C-04, 28 juin : TestT-60, C-06, 28 juin : Entraînement

Illustration : 60 billets inventés, pas les données du cours. Le vrai découpage est dans le texte sous l’explorateur.

Chaque point représente un billet, dans la bande de son client. La couleur et la forme indiquent la partie : cercle pour l'entraînement, carré pour la validation, triangle pour le test. Un anneau indique un billet transféré à un agent supérieur.
Description textuelle de l’explorateur

Le graphique a six bandes, une par client de C-01 à C-06, et un axe temporel de janvier à juin. Des lignes pointillées indiquent le 1er mai et le 1er juin. Il y a 60 billets. Parmi eux, 40 datent d’avant mai, dont 5 ont été transférés (12,5 %). Mai et juin comptent chacun 10 billets, dont 2 transférés par mois (20 %). C-06 a des billets seulement en mai et juin.

Séparation aléatoire, premier tirage : 42 billets d’entraînement, 9 de validation et 9 de test, répartis sur tous les mois. L’entraînement compte 6 transferts sur 42 (14,3 %), et le test, 1 sur 9 (11,1 %). Les clients des 9 billets de test sont aussi présents dans l’entraînement. L’entraînement contient 6 billets de juin. « Draw again » (tirer de nouveau) produit une nouvelle séparation aléatoire. Le taux du test change brusquement, par exemple à 0 % sur 9 billets au deuxième tirage.

Séparation par date : les 40 billets avant le 1er mai servent à l’entraînement, les 10 de mai à la validation. Les 10 billets de juin servent au test. L’entraînement compte 5 transferts (12,5 %), et le test, 2 (20 %). La hausse après le 1er mai est donc visible. Les clients de 7 des 10 billets de test sont présents dans l’entraînement. Les 3 autres billets appartiennent au nouveau client C-06. L’entraînement ne contient aucun billet de juin. « Draw again » est désactivé, car une séparation par date n’a aucune partie aléatoire.

Séparation par client, premier tirage : les 13 billets de C-01 servent tous au test. Les 11 billets d’un autre client servent à la validation, et les 36 autres à l’entraînement. Aucun client des billets de test n’est présent dans l’entraînement. L’entraînement contient encore 6 billets de juin. Chaque nouveau tirage place un autre client dans le test. Le taux du test varie beaucoup (38,5 %, 20 %, 0 %), car un seul client forme un petit échantillon.

Ce que montre l’explorateur :

  • Une séparation aléatoire mélange les mois. Chaque partie contient des billets de janvier à juin. Le modèle apprend avec juin et passe un test sur février. En utilisation réelle, le modèle n’a jamais les billets du mois suivant.
  • Seule la séparation par date montre le changement après le 1er mai. Une séparation aléatoire place des billets d’avant et d’après le changement dans les deux parties. L’entraînement et le test ont donc environ le même taux.
  • Une séparation aléatoire représente un seul tirage. Appuyez quelques fois sur « Draw again ». Avec 9 billets de test, le taux du test passe de 0 % à plus de 40 %. Un score réel varie aussi, mais moins.
  • La séparation par groupe teste de nouveaux clients, mais elle mélange les mois, comme la séparation aléatoire.

Mei compte les billets et les transferts par mois :

months.py
import pandas as pd
model = pd.read_csv("data/model/tickets_model.csv", parse_dates=["created_at"])
month = model["created_at"].dt.strftime("%Y-%m")
print(model.groupby(month)["escalated_72h"].agg(["size", "sum", "mean"]).round(3))
Sortie
size sum mean
created_at
2026-01 210 23 0.110
2026-02 225 25 0.111
2026-03 249 32 0.129
2026-04 243 28 0.115
2026-05 227 45 0.198
2026-06 215 35 0.163

De janvier à avril, environ 11 % à 13 % des billets sont transférés. En mai, ce taux atteint 19,8 %. Omar, le responsable du produit, demande ce qui s’est passé. Grace le sait : « Le 1er mai, une nouvelle politique de garantie est entrée en vigueur. Les questions de garantie vont maintenant plus souvent à un agent supérieur. » C’est le genre de changement qu’un modèle rencontre en situation réelle. Le monde après l’entraînement n’est pas celui des données d’entraînement.

Examinez maintenant des données de test aléatoires de 20 %, créées uniquement avec pandas :

random_split.py
import pandas as pd
model = pd.read_csv("data/model/tickets_model.csv", parse_dates=["created_at"])
test = model.sample(frac=0.2, random_state=0)
train = model.drop(test.index)
print(len(train), len(test))
print(test["created_at"].dt.strftime("%Y-%m").value_counts().sort_index())
print("train rate", round(train["escalated_72h"].mean(), 3), "test rate", round(test["escalated_72h"].mean(), 3))
print("train tickets from June:", (train["created_at"] >= "2026-06-01").sum())
Sortie
1095 274
created_at
2026-01 42
2026-02 44
2026-03 56
2026-04 40
2026-05 46
2026-06 46
Name: count, dtype: int64
train rate 0.14 test rate 0.128
train tickets from June: 169

Les données de test contiennent des billets de chaque mois, et l’entraînement contient 169 billets de juin. Les deux taux, 14,0 % et 12,8 %, sont proches. Rien dans cette séparation ne révèle le changement du taux de transfert en mai.

Larkfield entraînera le modèle sur des billets passés et l’utilisera sur de nouveaux billets. Mei sépare donc les données par date :

  • entraînement : billets créés avant le 1er mai 2026 (janvier à avril),
  • validation : mai,
  • test : du 1er au 27 juin. Les 28 au 30 juin sont exclus de la table, car ces cibles ne sont pas encore définitives (leçon 1).

Le changement de politique se trouve volontairement entre l’entraînement et la validation. Le score de validation dit alors la vérité : comment un modèle des anciens mois fonctionne-t-il dans les nouveaux?

scripts/split.py
"""Split the modelling table by time: train on the past, test on the future."""
import json
from pathlib import Path
import pandas as pd
IN = Path("data/model/tickets_model.csv")
OUT = Path("data/model")
VALID_FROM = pd.Timestamp("2026-05-01")
TEST_FROM = pd.Timestamp("2026-06-01")
def main():
df = pd.read_csv(IN, parse_dates=["created_at"])
df["split"] = "train"
df.loc[df["created_at"] >= VALID_FROM, "split"] = "valid"
df.loc[df["created_at"] >= TEST_FROM, "split"] = "test"
manifest = {"rule": f"train < {VALID_FROM.date()} <= valid < {TEST_FROM.date()} <= test", "parts": {}}
for name in ["train", "valid", "test"]:
part = df[df["split"] == name].drop(columns="split")
part.to_csv(OUT / f"{name}.csv", index=False, date_format="%Y-%m-%d %H:%M:%S")
manifest["parts"][name] = {
"rows": len(part), "escalated": int(part["escalated_72h"].sum()),
"escalated_rate": round(part["escalated_72h"].mean(), 3),
"first_created": str(part["created_at"].min()), "last_created": str(part["created_at"].max()),
}
train_customers = set(df.loc[df["split"] == "train", "customer_id"].dropna())
test_customers = set(df.loc[df["split"] == "test", "customer_id"].dropna())
manifest["test_customers_also_in_train"] = len(test_customers & train_customers)
manifest["test_customers"] = len(test_customers)
(OUT / "split_manifest.json").write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
print(json.dumps(manifest, indent=2))
if __name__ == "__main__":
main()
Lignes Pourquoi
VALID_FROM, TEST_FROM Les deux dates constituent toute la règle. Ce sont des constantes placées en haut, donc faciles à trouver.
df.loc[... >= VALID_FROM, "split"] = "valid", puis la même chose pour le test Chaque ligne sert d’abord à l’entraînement. Les lignes à partir de mai passent à la validation, et celles à partir de juin, au test. Chaque ligne appartient à une seule partie.
part.to_csv(OUT / f"{name}.csv", ...) Trois fichiers : train.csv, valid.csv, test.csv. Personne n’a besoin de refaire la séparation plus tard, donc personne ne peut la refaire incorrectement.
Le dictionnaire manifest Un manifeste de séparation : un petit fichier qui consigne la règle, les lignes, les transferts et les dates de chaque partie. Priya peut vérifier la séparation sans exécuter de code, et le module 6 la vérifie automatiquement.
test_customers_also_in_train Compte les clients du test que le modèle a déjà rencontrés pendant l’entraînement. Ce nombre indique le type de test.

Mei l’exécute :

Terminal
python scripts/split.py
Sortie
{
"rule": "train < 2026-05-01 <= valid < 2026-06-01 <= test",
"parts": {
"train": {
"rows": 927,
"escalated": 108,
"escalated_rate": 0.117,
"first_created": "2026-01-05 07:30:24",
"last_created": "2026-04-30 23:54:47"
},
"valid": {
"rows": 227,
"escalated": 45,
"escalated_rate": 0.198,
"first_created": "2026-05-01 11:14:19",
"last_created": "2026-05-31 20:57:12"
},
"test": {
"rows": 215,
"escalated": 35,
"escalated_rate": 0.163,
"first_created": "2026-06-01 08:42:16",
"last_created": "2026-06-27 20:14:04"
}
},
"test_customers_also_in_train": 77,
"test_customers": 89
}

Comptez les lignes : 927 + 227 + 215 = 1 369, soit toute la table. Les transferts : 108 + 45 + 35 = 188. Les taux montrent le changement : 11,7 % dans l’entraînement, 19,8 % dans la validation, 16,3 % dans le test. Les dates ne se chevauchent pas : l’entraînement finit le 30 avril, et la validation commence le 1er mai.

Parmi les 89 clients du test, 77 ont aussi des billets dans l’entraînement. Les 12 nouveaux clients ont 13 billets de test (un autre billet de test vient d’un invité). Ce test mesure donc surtout comment le modèle fonctionne pour des clients qu’il connaît déjà. Cela convient à Larkfield : la plupart des billets viennent de clients qui ont déjà écrit.

Une séparation par groupe est nécessaire quand le travail réel du modèle concerne surtout de nouveaux groupes. Par exemple, Larkfield pourrait vendre le modèle à d’autres magasins, dont il n’a jamais vu les clients. Un modèle hospitalier doit fonctionner pour de nouveaux patients, et un modèle de détection de pannes, pour de nouvelles machines. Gardez alors chaque client dans une seule partie. Vous pouvez combiner les deux méthodes : séparer par date et exclure complètement certains clients de l’entraînement.

Décrivez honnêtement ce que la séparation change pour ces données. Priya a entraîné le même modèle simple avec trois types de séparation; vous verrez ce modèle dans la leçon 3. Son score, l’aire sous la courbe ROC (ROC AUC), va de 0,5 (au hasard) à 1,0. Ce dernier score indique un classement parfait des billets transférés au-dessus des autres :

Séparation Score (ROC AUC)
Par date : entraînement sur janvier à avril, score sur mai 0,673
Aléatoire 80/20, 20 tirages aléatoires différents moyenne 0,730, minimum 0,665, maximum 0,827
Par client 80/20, 20 tirages aléatoires différents moyenne 0,744, minimum 0,663, maximum 0,823

Trois constats :

  • Les séparations aléatoires et par client donnent des scores proches sur ces données. Les variables n’identifient pas un client, donc le modèle gagne peu à connaître un client. C’est un résultat propre à ces variables, pas une règle. Une variable comme l’historique des transferts d’un client peut rendre une séparation aléatoire beaucoup trop optimiste.
  • La séparation par date donne le score le plus bas. Le modèle apprend avec les mois précédant le changement de politique et passe le test après celui-ci. C’est la situation réelle, donc 0,673 est le nombre honnête.
  • Une séparation aléatoire représente un seul tirage. Le même modèle et les mêmes données donnent des scores allant de 0,665 à 0,827. Un rapport qui annonce « 0,827 » après un tirage chanceux en dit plus sur le tirage que sur le modèle.
  1. Créez le fichier scripts/split.py avec le code ci-dessus, puis enregistrez-le.
  2. Exécutez python scripts/split.py. Vous devriez voir le manifeste ci-dessus : 927, 227 et 215 lignes.
  3. Vérifiez que les trois fichiers et le manifeste existent. Sur macOS, exécutez ls data/model. Sur Windows, exécutez Get-ChildItem data/model. Vous devriez voir build_summary.json, split_manifest.json, test.csv, tickets_model.csv, train.csv et valid.csv.
  4. Créez months.py avec le code de la section « Les données réelles », puis exécutez-le. Vous devriez voir 0.198 pour mai.
  5. Ouvrez split_manifest.json. Vérifiez que les lignes totalisent 1 369 et que la dernière date d’entraînement précède la première date de validation.

Changez une chose. Dans scripts/split.py, définissez VALID_FROM à 2026-04-01 et TEST_FROM à 2026-05-01. Avant de l’exécuter, faites une prédiction : où se trouve maintenant le changement de politique, et que révèle le taux de validation? Exécutez ensuite le script et lisez le manifeste. À la fin, remettez les dates à 2026-05-01 et 2026-06-01, puis exécutez de nouveau le script. Les fichiers seront ainsi corrects pour la leçon 3.

Afficher la réponse
Sortie (extrait)
"rule": "train < 2026-04-01 <= valid < 2026-05-01 <= test",
train: 684 rows, 80 escalated, 0.117
valid: 243 rows, 28 escalated, 0.115
test: 442 rows, 80 escalated, 0.181
"test_customers_also_in_train": 99,
"test_customers": 128

Le changement de politique se trouve maintenant entre la validation et le test. Le taux de validation (11,5 %) ressemble au taux d’entraînement (11,7 %). Toutes les vérifications sur la validation disent donc « tout est stable ». Le changement apparaît seulement dans les données de test (18,1 %), après toutes les décisions. Placez la période la plus récente et la plus réaliste dans la validation et le test. Si le monde a changé à une date connue, assurez-vous que la validation voit ce changement. Vous pourrez ainsi réagir avant le test final.

Erreur courante

Le score qui a baissé après le lancement

Symptôme : Tomás sépare les 1 369 lignes au hasard, entraîne un modèle et obtient une ROC AUC de 0,827. Larkfield commence à utiliser le modèle en juillet. Un mois plus tard, Priya le vérifie sur les billets de juillet. Il classe les transferts bien moins correctement que le score de 0,827 le promettait.

Cause : deux problèmes dans un seul nombre. D’abord, la séparation aléatoire a permis au modèle d’apprendre avec mai et juin. Elle l’a ensuite testé sur des billets des mêmes mois. En juillet, aucun billet futur ne sert à l’entraînement, et le monde peut avoir encore changé. Ensuite, 0,827 était le maximum de 20 tirages aléatoires. Le même modèle a obtenu 0,665 sur un autre tirage.

Correction : séparez par date, comme le fait split.py, pour que le score de validation reproduise l’utilisation réelle : 0,673 sur mai. Si vous utilisez aussi des séparations aléatoires, présentez la dispersion entre les tirages, pas un seul nombre. Écrivez la règle de séparation et les comptes dans split_manifest.json. Le lecteur pourra voir de quel test vient le score.

Conséquence dans le travail en IA : un score issu d’une mauvaise séparation crée de mauvaises attentes pour tout le monde. Omar planifie les effectifs avec ce score, et l’équipe cesse de chercher les problèmes. Le modèle ne devient pas moins bon après le lancement; il n’a jamais été aussi bon que le nombre l’indiquait.

Vérifiez votre compréhension

Larkfield veut un modèle qui prédit les escalades pour les nouveaux billets. Quelle séparation convient? Pourquoi une séparation aléatoire n'offre-t-elle pas un test juste?

Afficher la réponse

Une séparation temporelle : entraînez le modèle sur les anciens billets, puis validez-le et testez-le sur les plus récents. Cela correspond à son utilisation : il apprend du passé et prédit l’avenir. Une séparation aléatoire place des billets récents dans les données d’entraînement et des billets anciens dans les données de test. Le modèle apprend donc à partir d’informations qu’il n’aura jamais au moment de prédire. Cela masque aussi les changements dans le temps, comme la hausse des escalades après le 1er mai.

Vérifiez votre compréhension

Faites une prédiction : vous exécutez la séparation aléatoire de 20 % avec random_state=0, 1, 2, 3 et 4. Le taux d'escalade des données de test sera-t-il toujours le même? Une de ces séparations montrera-t-elle le changement en mai?

Afficher la réponse

Non, il change à chaque tirage, car les billets placés dans les données de test diffèrent. Avec les données réelles, les taux de test sont de 0,128, 0,142, 0,128, 0,113 et 0,139. Aucun ne montre le changement en mai. Chaque jeu de données de test aléatoire mélange les six mois. Seule une séparation temporelle distingue les mois avant et après le 1er mai.

Vérifiez votre compréhension

Votre manifeste de séparation indique test_customers_also_in_train : 77 et test_customers : 89. Qu'est-ce que cela indique à Priya? Quand aurait-elle besoin d'une autre séparation?

Afficher la réponse

La plupart des clients des données de test (77 sur 89) ont déjà des billets dans les données d’entraînement. Le test mesure donc surtout la performance du modèle pour les clients qu’il connaît. Cela correspond au travail habituel de Larkfield. Elle a besoin d’une séparation par client si le modèle doit surtout fonctionner pour de nouveaux clients. Un modèle destiné aux clients d’une autre boutique en est un exemple.

Récapitulatif

  • Les données d’entraînement servent à apprendre, les données de validation à choisir et les données de test à obtenir un score final.
  • Choisissez la séparation qui reproduit l’utilisation réelle. Séparez par période quand le modèle prédit l’avenir. Séparez par groupe quand il doit fonctionner pour de nouveaux clients. Utilisez une séparation aléatoire seulement pour des lignes indépendantes.
  • Dans les données réelles, le taux d’escalade passe de 11,7 % (entraînement) à 19,8 % (mai) et à 16,3 % (juin). Une séparation temporelle montre le changement; une séparation aléatoire le masque.
  • Une séparation aléatoire correspond à un tirage : le même modèle a obtenu des scores allant de 0,665 à 0,827.
  • split.py écrit train.csv, valid.csv, test.csv et split_manifest.json.

Ensuite, vous préparez les caractéristiques d’un modèle et découvrez où le prétraitement peut causer des fuites de données.

Leçon suivante : Ajuster les transformations correctement