La classification : prédire une catégorie
Un prêt sera-t-il remboursé ?
Une coopérative d'épargne veut savoir, avant d'accorder un crédit, si le client va probablement le rembourser. C'est une classification : la cible n'est plus un nombre, mais une catégorie, ici 1 (remboursé) ou 0 (non remboursé).
Le fichier credit.csv contient 260 crédits passés : l'âge du client, son revenu mensuel, le montant emprunté, la durée en mois, le nombre d'incidents de paiement passés, et s'il a remboursé.
Elle se pilote comme tout sklearn :
from sklearn.linear_model import LogisticRegression
modele = LogisticRegression(max_iter=1000)
modele.fit(X_train, y_train)
modele.predict(X_test) # des 0 et des 1
modele.predict_proba(X_test) # les probabilités, deux colonnes : P(0) et P(1)
(max_iter=1000 laisse à la descente de gradient interne le temps de converger.)
Mettre les caractéristiques à l'échelle
Problème : le revenu se compte en centaines de milliers, le nombre d'incidents en unités. Pour beaucoup de modèles (dont la régression logistique), une caractéristique aux grands nombres écrase les autres, non pas parce qu'elle compte plus, mais parce que ses chiffres sont plus gros.
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
modele = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
modele.fit(X_train, y_train) # met à l'échelle puis entraîne, proprement
L'exactitude ne suffit pas
Mais souviens-toi du test médical du module de maths. Si 99 % des gens sont sains, un modèle qui répond toujours « sain » a 99 % d'exactitude... et ne détecte aucun malade. L'exactitude seule ment dès que les classes sont déséquilibrées.
Les deux comptent, et il y a un compromis. Pour accorder un crédit, la coopérative veut une bonne précision sur la classe « remboursera » : mieux vaut refuser un bon client que prêter à un mauvais. Pour un test de maladie grave, on veut un fort rappel : mieux vaut une fausse alerte qu'un malade raté. Le bon équilibre dépend du coût de chaque erreur.
Exercice : Un modèle de crédit
Entraîne un pipeline (mise à l'échelle + régression logistique) sur le jeu d'entraînement du crédit, puis mesure-le sur le test :
modele: le pipeline entraîné ;acc: l'exactitude sur le test ;base: l'exactitude d'un modèle bête qui prédit toujours la classe majoritaire du test (la proportion de la classe la plus fréquente).
Voir une solution
import pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv("credit.csv")
X = df[["age", "revenu", "montant", "duree", "retards"]]
y = df["rembourse"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0, stratify=y)
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import accuracy_score
modele = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000, random_state=0))
modele.fit(X_train, y_train)
acc = accuracy_score(y_test, modele.predict(X_test))
base = max(y_test.mean(), 1 - y_test.mean())
print("modele :", round(acc, 3), "| reference bete :", round(base, 3))Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice
Exercice : Précision, rappel, matrice de confusion
Avec le même pipeline, calcule sur le jeu de test :
cm: la matrice de confusion (confusion_matrix(y_test, pred)) ;prec: la précision sur la classe « remboursera » (1) ;rec: le rappel sur la classe1.
Voir une solution
import pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv("credit.csv")
X = df[["age", "revenu", "montant", "duree", "retards"]]
y = df["rembourse"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0, stratify=y)
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import confusion_matrix, precision_score, recall_score
modele = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000, random_state=0))
modele.fit(X_train, y_train)
pred = modele.predict(X_test)
cm = confusion_matrix(y_test, pred)
prec = precision_score(y_test, pred)
rec = recall_score(y_test, pred)
print(cm)
print("precision :", round(prec, 3), "| rappel :", round(rec, 3))Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice