Une méthode statistique de 1936 qui cherche la combinaison de variables séparant le mieux des groupes connus. Elle sert à classer, comme une régression logistique, et à résumer ce qui distingue les groupes sur un ou deux axes. Le Z-score d'Altman, qui prédit les faillites d'entreprises, en est une application célèbre.
Photographier deux foules sous le meilleur angle : celui où elles se chevauchent le moins sur la photo.
On calcule la moyenne de chaque variable dans chaque groupe, et une dispersion commune à tous les groupes.
L'axe discriminant maximise l'écart entre les moyennes des groupes par rapport à la dispersion à l'intérieur des groupes. Avec k groupes, on obtient au plus k - 1 axes.
Un nouveau client est projeté sur l'axe et affecté au groupe dont il est le plus proche, en tenant compte de la taille de chaque groupe.
Ancienneté, appels au support, montant mensuel, type de contrat, incidents récents, et le statut connu : parti ou resté. La question du marketing : qu'est-ce qui distingue le profil des partants ?
Sur le jeu d'exemple, avec des variables centrées réduites, le nombre d'appels au support pèse le plus sur l'axe, devant le contrat mensuel ; l'ancienneté tire dans l'autre sens. Sur cet axe, partants et fidèles se placent nettement à l'écart les uns des autres.
La probabilité de départ issue de la LDA se juge comme celle d'une régression logistique : l'AUC mesure si les partants sont bien classés au-dessus des fidèles (0,75 sur le jeu d'exemple, au niveau de la logistique).
Peu de paramètres. Noms donnés pour R (MASS) et Python (scikit-learn).
Probabilités a priori des groupes. Par défaut, leurs fréquences dans les données. Les modifier revient à déplacer le seuil de décision.
Elle ne change pas le classement, mais elle rend les poids de l'axe comparables entre variables exprimées en mois, en euros ou en nombre d'appels.
Régularisation de la dispersion commune, utile quand il y a beaucoup de variables pour peu de lignes. En Python, solver="lsqr" avec shrinkage="auto".
# Profil des clients partants : analyse discriminante linéaire en R
library(MASS)
clients <- read.csv("clients_churn.csv")
X <- model.matrix(~ anciennete + appels_support + montant + contrat + incidents_3m, data = clients)[, -1]
set.seed(42)
idx <- sample(nrow(clients), round(0.7 * nrow(clients)))
# Variables centrées réduites avec les paramètres de l'entraînement
X_train <- scale(X[idx, ])
X_test <- scale(X[-idx, ], center = attr(X_train, "scaled:center"), scale = attr(X_train, "scaled:scale"))
modele <- lda(x = X_train, grouping = factor(clients$churn[idx]))
# L'axe discriminant : la combinaison de variables qui sépare le mieux les deux groupes
print(round(modele$scaling[order(modele$scaling[, 1]), , drop = FALSE], 2))
# Position moyenne des fidèles (0) et des partants (1) sur cet axe
res <- predict(modele, X_test)
print(round(tapply(res$x[, 1], clients$churn[-idx], mean), 2))
print(table(prevu = res$class, reel = clients$churn[-idx]))
# Profil des clients partants : analyse discriminante linéaire en Python
import pandas as pd
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
clients = pd.read_csv("clients_churn.csv")
X = pd.get_dummies(clients[["anciennete", "appels_support", "montant", "contrat", "incidents_3m"]], drop_first=True, dtype=float)
y = clients["churn"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# Variables centrées réduites : les poids de l'axe deviennent comparables
modele = make_pipeline(StandardScaler(), LinearDiscriminantAnalysis())
modele.fit(X_train, y_train)
# L'axe discriminant : la combinaison de variables qui sépare le mieux les deux groupes
print(pd.Series(modele[-1].scalings_[:, 0], index=X.columns).round(2).sort_values())
# Position moyenne des fidèles (0) et des partants (1) sur cet axe
axe = modele.transform(X_test)[:, 0]
print(pd.Series(axe).groupby(y_test.to_numpy()).mean().round(2))
print("AUC test :", round(roc_auc_score(y_test, modele.predict_proba(X_test)[:, 1]), 3))
L'ACP cherche les axes qui résument le mieux la variance des données, sans connaître les groupes. La LDA connaît les groupes et cherche les axes qui les séparent le mieux. L'ACP décrit, la LDA discrimine.
Les deux produisent une frontière linéaire et donnent souvent des résultats proches. La LDA suppose des nuages gaussiens de même dispersion ; si c'est à peu près vrai, elle est plus stable sur de petits échantillons. Sinon, la régression logistique, qui fait moins d'hypothèses, est plus sûre.
Pas ici. Le même sigle désigne aussi une méthode de détection de thèmes dans des textes, la Latent Dirichlet Allocation. Les deux n'ont rien en commun : l'analyse discriminante classe des individus, la Latent Dirichlet Allocation découvre des sujets.
Chaque groupe garde sa propre dispersion : la frontière devient courbe.
Voir la fiche → l'alternative la plus couranteMême type de frontière, moins d'hypothèses sur la forme des données, odds ratios lisibles.
Voir la fiche → la cousine non superviséeCherche les axes qui résument le plus de variance, sans connaître les groupes.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus