Formation MLOps · Dotika · Bloc 2 · 3 h

Construire
le cerveau

Développement du modèle — un détecteur de fraude entraîné, évalué, honnête. La matière qu'on industrialisera toute la semaine.

Le fil rouge · où on en est

Le flux tourne, rien ne l'arrête

Bloc 1 : votre environnement est prêt, le dépôt Git existe, le projet est cadré — métriques choisies, coûts posés. Mais sur la carte, regardez le compteur : les fraudes passent toujours.

Mission du bloc 2 : faire apparaître le cerveau — un modèle qui score chaque transaction.

Pythonpandasscikit-learn
L'objectif du bloc

À 16 h, vous avez un modèle qui détecte la fraude — et vous savez prouver qu'il est bon

Construit en live, ensemble, au clavier. Pas le meilleur modèle du monde : un modèle honnêtement évalué, qui bat sa baseline — exactement ce qu'il faut pour la suite.

Bloc 2 · 3 h · théo 0h20 / prat 2h40

Quatre missions, au clavier

0h40
Regarder les donnéesCharger, explorer, comprendre le déséquilibre — avant toute ligne de modèle.
pratique
1h00
Construire la baselineRégression logistique, class_weight, premier entraînement — simple et solide.
pratique
0h40
Itérer méthodiquementFeatures, rééquilibrage, seuil de décision — une hypothèse à la fois.
pratique
0h40
Juger honnêtementPR-AUC, matrice de confusion, analyse d'erreurs — la théorie du bloc vit ici.
théo + pratique
Acte 1

D'abord, regarder
les données

La règle d'or

Un modèle vaut ce que valent
ses données

L'algorithme le plus sophistiqué du monde, nourri de données mal comprises, produit des erreurs sophistiquées. On passe donc 40 minutes à regarder avant de construire — c'est le meilleur investissement de la journée.

La matière première

Ce qu'il y a dans le fichier

Un CSV de 150 Mo : deux jours de transactions réelles de cartes européennes, anonymisées (dataset public Kaggle).

284 807 lignes
une transaction par ligne — assez pour que « ouvrir dans Excel » ne soit plus une option.
31 colonnes
Time, Amount, V1 à V28… et Class : 0 = légitime, 1 = fraude. C'est notre vérité terrain.
492 fraudes
soit 0,172 % des lignes. Retenez ce chiffre : il va dicter toutes nos décisions.

Première mission du lab : charger ce fichier proprement et vérifier chacun de ces chiffres vous-mêmes. Ne jamais croire un slide sur parole.

Le mystère des colonnes

Pourquoi « V1 », « V2 »… et pas « pays », « commerçant » ?

Parce que ce sont de vraies données bancaires. Publier les colonnes d'origine trahirait les clients — et les secrets de la banque.

Ce que la banque voit
pays, heure, commerçant, historique…
  • Des dizaines de variables métier, très parlantes
  • Confidentielles : impossibles à publier telles quelles
Ce qu'on reçoit
V1 … V28, anonymisées
  • Les mêmes informations, compressées et brouillées (PCA)
  • Le signal est intact — le sens des colonnes est masqué

Conséquence intéressante : on travaille comme un vrai data scientist bancaire — on ne sait pas tout, et il faut faire parler les données quand même.

L'exploration · ce qu'on cherche

Quatre questions à poser aux données

Question 1
Les classes : à quel point c'est déséquilibré ?
Compter les fraudes, visualiser la proportion. C'est ce qui décidera de la métrique et de l'entraînement.
Question 2
Les montants : les fraudes sont-elles différentes ?
Distribution des montants fraude vs légitime — premier indice de signal exploitable.
Question 3
Le temps : y a-t-il des heures à fraude ?
Les fraudeurs travaillent la nuit ? Les patterns temporels sont souvent parlants.
Question 4
Les V : lesquelles séparent le mieux ?
Même anonymisées, certaines V éloignent nettement fraudes et légitimes. Ce sont nos meilleures alliées.
Le déséquilibre, en vrai

Trouvez les fraudes

3 000 transactions à l'échelle réelle : 5 points rouges. Voilà à quoi ressemble 0,17 % — et pourquoi ce problème s'appelle l'aiguille dans la botte de foin.
Rappel du bloc 1 · le piège

Le champion du monde de l'accuracy

Le modèle « toujours OK »
Une seule ligne de code : répondre « légitime » à tout, sans regarder.
99,83 % d'accuracy. Champion.
Sa valeur réelle
Fraudes détectées : zéro. Clients protégés : zéro. Il est excellent… à ne rien faire.
0 fraude attrapée sur 492
C'est pour ça qu'au bloc 1 on a choisi la PR-AUC et le coût métier. Aujourd'hui, on les met en pratique.
La règle absolue

On ne se note jamais sur ses propres révisions

Un modèle évalué sur les données qui l'ont entraîné, c'est un étudiant qui s'examine sur les annales qu'il vient de recopier : la note ne veut rien dire.

Train · ~80 %
Pour apprendre
  • Le modèle ne voit que ces transactions
  • Stratifié : la même proportion de fraudes que l'original
Test · ~20 %
Pour juger — intouchable
  • Jamais utilisé pendant l'entraînement, jamais
  • Simule les transactions de demain, celles que le modèle n'a pas vues
Le crime parfait · data leakage

Quand le futur
fuit dans le passé

Le leakage, c'est laisser le modèle voir pendant l'entraînement une information qu'il n'aura pas en production. Résultat : des scores mirifiques au test… et un effondrement en prod.

Un score trop beau pour être vrai ne l'est jamais. Cherchez la fuite.

# l'erreur classique
scaler.fit(tout_le_dataset)  # ← le test a fui !
X_train, X_test = split(...)

# la bonne version
X_train, X_test = split(...)
scaler.fit(X_train)  # le test reste inconnu
La fuite la plus fréquente tient en une ligne d'ordre inversé.
Acte 2

Un premier cerveau,
simple

Le réflexe du débutant

« Et si on mettait un réseau de neurones ? »

Non. Pas encore. En production, le bon modèle n'est pas le plus malin — c'est le plus simple qui fait le travail.

Une référence
Sans baseline, impossible de savoir si le modèle sophistiqué apporte quoi que ce soit. On mesure toujours contre quelque chose.
Un diagnostic
Si la baseline échoue bizarrement, le problème est dans les données, pas dans l'algorithme. Le simple révèle, le complexe masque.
Un allié MLOps
Rapide à entraîner, léger à servir, facile à expliquer à un régulateur bancaire. La sophistication se paie en production.

Notre baseline : la régression logistique — 60 ans d'âge, toujours en service dans la moitié des banques du monde.

Feynman · 3 minutes

Une balance
à soupçons

Chaque variable pèse sur la balance : un montant inhabituel ajoute du soupçon, une heure normale en retire. Le modèle apprend le poids de chaque indice — puis convertit le total en probabilité entre 0 et 1.

C'est tout. Une somme pondérée d'indices, écrasée entre 0 et 1. Le reste est du vocabulaire.

indices × poids → score montant 900 €+ lourd 3 h du matin+ moyen V14 = -8,3+ très lourd client régulier− léger score 0,93 la sigmoïde écrase le total entre 0 et 1
Régression logistique = balance d'indices + écrasement 0→1.
Ce que fait vraiment .fit()

Entraîner, c'est régler la balance

Au départ, tous les poids sont au hasard. Le modèle parcourt les 227 000 transactions d'entraînement et ajuste, encore et encore : « sur celle-ci je me suis trompé — quel poids corriger ? »

227 845 exemples × des milliers d'ajustements ≈ 2 secondes de calcul.

C'est la magie ennuyeuse du ML : un algorithme d'optimisation banal, répété très vite. Aucune « intelligence » là-dedans — juste des poids qui convergent vers ce qui sépare le mieux fraudes et légitimes.

model.fit(X_train, y_train)une ligne — et 60 ans de mathématiques
Le déséquilibre contre-attaque

Dire au modèle ce qui coûte cher

Sans consigne, le modèle optimise le nombre d'erreurs — et avec 0,17 % de fraudes, la stratégie gagnante est de les ignorer. Il faut changer les règles du jeu.

Sans class_weight
« Toutes les erreurs se valent »
  • Rater une fraude = bloquer un client : même prix
  • Le modèle sacrifie les 492 fraudes sans remords
Avec class_weight='balanced'
« Une fraude ratée coûte ×580 »
  • Chaque fraude d'entraînement pèse comme ~580 transactions
  • Le modèle est forcé de les prendre au sérieux

Un seul paramètre — et c'est déjà de l'alignement métier : on encode le coût réel de l'erreur dans l'apprentissage.

Ce que le modèle rend vraiment

0,93 n'est pas « fraude »

Le modèle ne dit jamais oui ou non. Il dit « 93 % de chances que ce soit une fraude » — et c'est à nous de décider où placer la barre.

>>> model.predict_proba(transaction)
array([[0.07, 0.93]])  # [P(légitime), P(fraude)]

# le verdict, c'est NOTRE règle :
alerte = proba_fraude >= seuil  # 0.5 ? 0.3 ? 0.9 ?

Ce petit seuil est une décision métier déguisée en paramètre technique. On y consacre l'acte 3 — c'est lui qui arbitre entre fraudes ratées et clients bloqués.

Acte 3 · la théorie du bloc vit ici

Le juger
honnêtement

L'outil de base

Quatre cases, toute la vérité

le modèle dit : légitime
le modèle dit : fraude
c'était
légitime
Vrai négatif
Personne ne remarque rien. 99,8 % des cas — et c'est très bien.
Faux positif
Client honnête bloqué au restaurant. ~15 € + un client agacé.
c'était
une fraude
Faux négatif
La fraude passe. Le montant est perdu — l'erreur la plus chère.
Vrai positif
Fraude bloquée. C'est pour cette case qu'on construit tout le système.

Toutes les métriques qui suivent ne sont que des résumés de ces quatre cases. Quand une métrique vous embrouille : revenez à la matrice.

Deux questions, deux métriques

Precision et recall, en langage fraude

Precision
« Quand j'alerte, ai-je raison ? » — la proportion de vraies fraudes parmi mes alertes.
Basse ? → je crie au loup, les analystes me détestent
Recall
« Des vraies fraudes, combien j'en attrape ? » — la proportion de fraudes que je détecte.
Bas ? → les fraudes passent, la banque paie
Les deux se tirent dessus : alerter plus attrape plus de fraudes (recall ↑) mais multiplie les fausses alertes (precision ↓). Il faut arbitrer.
Démo live · à vous de jouer

Déplacez le seuil, sentez l'arbitrage

Seuil
0,50
Fraudes attrapées
Fraudes ratées
Clients bloqués à tort
La métrique du projet

PR-AUC : juger tous
les seuils d'un coup

Vous venez de le sentir : chaque seuil donne un couple precision/recall différent. La courbe PR les trace tous ; l'aire sous la courbe (PR-AUC) résume la qualité du modèle indépendamment du seuil choisi.

Un seul chiffre, honnête même à 0,17 % de fraudes. C'est notre étalon pour comparer les modèles — aujourd'hui à la main, dès mercredi en barrière automatique dans la CI.

recall — fraudes attrapées precision un seuil = un point PR-AUC = l'aire
Plus la courbe colle au coin haut-droit, meilleur est le modèle.
Question fréquente

« Et la ROC-AUC ? Tout le monde l'utilise »

Justement : tout le monde l'utilise… y compris quand il ne faut pas.

La ROC compte les vrais négatifs — et on en a 284 315. Noyée sous les légitimes, elle affiche 0,95 même pour un modèle médiocre sur la fraude.

La courbe PR, elle, ne regarde que ce qui nous intéresse : la classe rare. À déséquilibre extrême, métrique de la classe rare. C'est le réflexe à retenir — et une excellente question d'entretien.

Le juge de paix

Convertir la matrice en euros

La PR-AUC compare les modèles. Mais la décision finale — quel modèle, quel seuil — se prend dans la devise du métier : l'euro.

coût = fraudes_ratées × montant_moyen  +  fausses_alertes × 15 €

# cadré au bloc 1, calculé aujourd'hui, automatisé au bloc 6 —
# le seuil optimal est celui qui minimise CE chiffre.

C'est la boucle complète : une erreur statistique devient un coût, un coût devient une décision. Voilà ce qui distingue un modèle utile d'un modèle bien noté.

La dernière marche

Regarder ses erreurs une par une

Les métriques disent combien on se trompe. L'analyse d'erreurs dit pourquoi — et c'est là que naissent les meilleures idées d'amélioration.

Rituel 1
Trier les fraudes ratées par montant
Rater une fraude à 12 € et une à 4 800 €, ce n'est pas la même erreur. On commence par les plus chères.
Rituel 2
Chercher le point commun
Les ratées sont-elles toutes nocturnes ? Petits montants ? Même profil de V ? Un pattern = une feature à créer.
Rituel 3
Regarder les fausses alertes aussi
Qui bloque-t-on à tort ? Si c'est toujours le même profil de client, on tient un biais — et un futur incident.
Rituel 4
Noter, avant d'oublier
Chaque constat devient une hypothèse d'itération. Ce carnet manuel, c'est MLflow qui le tiendra au bloc 5.
Acte 4

Itérer,
méthodiquement

La méthode

Une hypothèse à la fois

Améliorer un modèle, ce n'est pas « essayer des trucs ». C'est une boucle scientifique : hypothèse → changement → mesure → verdict. Un seul changement par tour, sinon on ne sait plus ce qui a agi.

1 · Hypothèse
« Les fraudes ratées sont surtout nocturnes → une feature heure-de-la-nuit devrait aider. » Elle vient de l'analyse d'erreurs, jamais du hasard.
2 · Changement
Un seul : la feature, le rééquilibrage ou le seuil. Le reste ne bouge pas — même split, même graine aléatoire.
3 · Verdict
PR-AUC et coût métier, sur le test. Mieux ? On garde. Pire ? On note pourquoi, et on jette sans état d'âme.
Levier 1 / 3

Fabriquer de meilleurs indices

Le modèle ne voit que ce qu'on lui donne. Le feature engineering, c'est transformer les colonnes brutes en indices plus parlants.

# le montant brut écrase tout — on le compresse
df["amount_log"] = np.log1p(df["Amount"])

# "Time" en secondes ne dit rien — l'heure du jour, si
df["hour"] = (df["Time"] // 3600) % 24

Deux lignes, souvent plus d'impact qu'un changement d'algorithme. En fraude, l'indice bat le cerveau — les meilleures équipes passent leur temps ici.

Levier 2 / 3

Rééquilibrer les classes — avec des pincettes

Autre riposte au déséquilibre : modifier les données d'entraînement elles-mêmes.

Undersampling
Jeter des légitimes pour rééquilibrer. Simple, rapide — mais on gaspille de la donnée.
Oversampling
Dupliquer les fraudes. Le modèle les voit plus souvent — au risque de les apprendre par cœur.
SMOTE
Créer des fraudes synthétiques entre les vraies. Élégant — et dangereux si mal appliqué.

La règle qui sauve : on ne rééquilibre que le train. Toucher au test, c'est mentir sur la réalité — un data leakage de manuel. Et on compare toujours au simple class_weight : souvent, il suffit.

Levier 3 / 3

Le levier gratuit : optimiser le seuil

Même modèle, zéro ré-entraînement : on balaie tous les seuils et on garde celui qui minimise le coût métier. Vous l'avez fait à la main tout à l'heure — en code, c'est une boucle de cinq lignes.

>>> for seuil in np.arange(0.05, 0.95, 0.01): coût(seuil)
seuil = 0.50 → coût 41 300 €
seuil = 0.31 → coût 28 750 €  # ← le minimum
seuil = 0.10 → coût 55 900 €  # trop d'alertes

12 550 € économisés en déplaçant un curseur. Le seuil par défaut de 0,5 n'a rien de sacré — c'est juste la valeur d'usine.

Le danger permanent

Apprendre
par cœur

À force d'itérer, le modèle peut mémoriser le train au lieu de comprendre la fraude — brillant sur ses révisions, perdu devant l'inédit. C'est l'overfitting, et il se voit d'un coup d'œil : l'écart entre score train et score test.

Train 0,99, test 0,71 : ce modèle n'a rien appris. Il a triché.

PR-AUC au fil des itérations s'arrêter ici train (flatteur) test (la vérité)
Quand le test redescend alors que le train monte : stop.
Prémonition · vous allez le vivre aujourd'hui

« Le run 7,
c'était quoi déjà ? »

Dans une heure, vous aurez huit modèles entraînés, des scores griffonnés, trois onglets ouverts — et une vraie question : lequel était le meilleur, avec quels réglages ? Retenez cette sensation d'égarement.

Cette douleur a un remède, et il a un nom : MLflow. Rendez-vous au bloc 5.

model_final.pkl
model_final_v2.pkl
model_final_v2_VRAI.pkl
model_final_v2_VRAI_celui_la.pkl
# PR-AUC : 0.81 ? 0.83 ? c'était lequel ?
Le dossier de fin de journée de toute équipe sans tracking.
Avant de coder · l'essentiel

Cinq réflexes à emporter

Réflexe 1
Regarder les données avant le modèle
Le déséquilibre décide de tout : métrique, entraînement, seuil.
Réflexe 2
Baseline simple d'abord
Régression logistique + class_weight. On ne complexifie que si les données le réclament.
Réflexe 3
Le test est sacré
Jamais entraîné, jamais rééquilibré, jamais regardé pour choisir. Sinon : leakage.
Réflexe 4
PR-AUC + coût métier, pas l'accuracy
À classe rare, métriques de classe rare — et le verdict final en euros.

Et le cinquième : une hypothèse à la fois. C'est ce qui transforme du bricolage en ingénierie.

Acte 5 · lab

À vous :
2h40 au clavier

Mission 1 / 4 · 0h40 · pratique

Charger et faire parler les données

Dans notebooks/01_exploration.ipynb : charger le CSV, vérifier les chiffres du slide 7, puis répondre aux quatre questions de l'acte 1 — déséquilibre, montants, heures, meilleures V.

Livrable : un notebook d'exploration commité, avec vos quatre réponses écrites en markdown.

pandasmatplotlibdf.describe()value_counts()groupby("Class")

Binômes : un qui code, un qui questionne — on échange à la mi-temps.

Mission 2 / 4 · 1h00 · pratique

Construire la baseline — en module, pas en notebook

Split stratifié, scaler fit sur le train seul, régression logistique avec class_weight='balanced'. Et on code dans src/train/train.py — un script rejouable, pas des cellules éparses : le réflexe MLOps commence ici.

Livrable : python -m src.train.train entraîne, évalue, sauve le modèle (.pkl) et affiche la PR-AUC.

scikit-learntrain_test_split(stratify=y)StandardScalerLogisticRegressionjoblib

Objectif chiffré : PR-AUC ≥ 0,70. Si vous voyez 0,99 : cherchez la fuite avant de fêter.

Mission 3 / 4 · 0h40 · pratique

Battre votre propre baseline

Trois tours de boucle minimum, un levier par tour : une feature (amount_log, hour), un essai de rééquilibrage (comparé au class_weight), et le seuil optimisé sur le coût métier. Notez chaque run dans un tableau markdown — hypothèse, réglage, score, verdict.

Livrable : votre tableau de runs — il vous fera aimer MLflow au bloc 5.

np.log1pseuil × coûtSMOTE (train seul !)random_state fixé

Rappel : un seul changement par tour. Deux changements = zéro conclusion.

Mission 4 / 4 · 0h40 · théo 0h20 + prat 0h20

Le verdict final, ensemble

On reprend l'acte 3 sur vos résultats : matrices de confusion au tableau, courbes PR comparées, et l'analyse d'erreurs — chaque binôme présente sa fraude ratée la plus chère et son hypothèse pour l'attraper.

Definition of done : un modèle sauvé, sa PR-AUC ≥ baseline, son seuil justifié en euros, ses erreurs analysées.

precision_recall_curveconfusion_matrixaverage_precision_score

C'est ce modèle — le vôtre — qu'on exposera en API au bloc 3.

Le fil rouge · fin du bloc 2

Le cerveau existe — regardez-le travailler

Les transactions s'arrêtent désormais au cerveau, sont scorées, et les fraudes partent dans le bac rouge. Le compteur « fraudes bloquées » tourne enfin.

Mais regardez le cadre en pointillés : ce cerveau vit dans un notebook. Fragile, injoignable, inutilisable par la banque. Personne ne peut lui parler — sauf vous.

modèle entraîné ✓évalué ✓servi… pas encore
La suite

Donnons-lui
une adresse

Bloc 3 — Serving & API avec FastAPI : POST /predict, et le monde entier peut interroger votre modèle.

Pas à pas ↗