La LDA suppose que tous les groupes ont la même dispersion. L'analyse discriminante quadratique laisse chaque groupe garder la sienne : un nuage serré, un autre étalé. La frontière devient courbe. Utile quand un état anormal se distingue autant par sa régularité que par son niveau moyen.
Deux troupeaux : l'un groupé serré autour du berger, l'autre dispersé dans le pré. La limite entre les deux n'est pas une clôture droite mais une ligne qui entoure le troupeau groupé.
Pour chaque classe, on calcule sa moyenne et sa propre matrice de dispersion : étalement de chaque variable et liens entre elles.
Pour un nouveau point, on mesure à quel point il est typique de chaque classe, en tenant compte de sa forme. Un point peut être proche d'une moyenne mais atypique pour un nuage très serré.
On pondère par la fréquence de chaque classe et on retient la plus probable. La frontière qui en résulte est une courbe (ellipse, parabole).
Température et vibration d'une machine, heure par heure, avec l'étiquette « dans les 72 heures avant une panne » sur l'historique. En pré-panne, la vibration est plus haute et bien plus régulière qu'en marche normale.
Chaque heure reçoit une probabilité d'être en phase de pré-panne. Sur le jeu d'exemple, au seuil de 50 %, la QDA repère 18 heures de pré-panne sur 22, contre 15 pour la LDA, pour un nombre de fausses alertes comparable.
Les pré-pannes ne représentent que 4 % des heures : dire « tout va bien » donne 96 % d'exactitude. On suit la part des pré-pannes détectées et le nombre de fausses alertes par semaine. En production, on valide sur une période postérieure à l'entraînement.
Noms donnés pour R (MASS) et Python (scikit-learn).
Probabilités a priori des classes. Avec une classe rare, les augmenter fait lever plus d'alertes : c'est le levier pour arbitrer entre détection et fausses alertes.
Régularisation qui rapproche chaque dispersion d'une forme plus simple. Indispensable quand une classe a peu d'exemples ou des variables très corrélées. MASS::qda n'en propose pas ; klaR::rda le permet.
La probabilité de 50 % n'a rien d'obligatoire. On le fixe selon le coût d'un arrêt imprévu et celui d'une intervention inutile.
# Détection de pré-panne : analyse discriminante quadratique en R
library(MASS)
capteurs <- read.csv("capteurs_machine.csv")
capteurs$panne_72h <- factor(capteurs$panne_72h) # 1 = dans les 72 h avant la panne
set.seed(42)
idx <- sample(nrow(capteurs), round(0.7 * nrow(capteurs)))
train <- capteurs[idx, ]
test <- capteurs[-idx, ]
# Chaque classe a sa propre moyenne ET sa propre dispersion
print(aggregate(cbind(temperature, vibration) ~ panne_72h, data = train, FUN = sd))
qda_m <- qda(panne_72h ~ temperature + vibration, data = train)
lda_m <- lda(panne_72h ~ temperature + vibration, data = train)
# Comparaison au seuil de 50 % sur les heures jamais vues
print(table(QDA = predict(qda_m, test)$class, reel = test$panne_72h))
print(table(LDA = predict(lda_m, test)$class, reel = test$panne_72h))
# Détection de pré-panne : analyse discriminante quadratique en Python
import pandas as pd
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis, LinearDiscriminantAnalysis
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, roc_auc_score
capteurs = pd.read_csv("capteurs_machine.csv")
X = capteurs[["temperature", "vibration"]]
y = capteurs["panne_72h"] # 1 = dans les 72 h avant la panne
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# Chaque classe a sa propre moyenne ET sa propre dispersion
print(X_train.groupby(y_train).agg(["mean", "std"]).round(2))
qda = QuadraticDiscriminantAnalysis().fit(X_train, y_train)
lda = LinearDiscriminantAnalysis().fit(X_train, y_train)
for nom, m in [("QDA", qda), ("LDA", lda)]:
proba = m.predict_proba(X_test)[:, 1]
print(nom, "| AUC :", round(roc_auc_score(y_test, proba), 3))
print(confusion_matrix(y_test, proba > 0.5))
La LDA suppose que toutes les classes partagent la même dispersion : la frontière est droite. La QDA estime une dispersion par classe : la frontière devient courbe. La QDA est plus souple mais demande plus de données, car elle estime beaucoup plus de paramètres.
Quand les classes diffèrent autant par leur forme que par leur position : un état stable et resserré face à un état variable, par exemple. Il faut aussi assez d'exemples dans chaque classe, au moins plusieurs fois le nombre de variables.
Une classe a trop peu d'exemples par rapport au nombre de variables, ou certaines variables sont constantes ou redondantes dans une classe. Sa dispersion ne peut pas être inversée. Il faut retirer des variables, régulariser (reg_param) ou revenir à la LDA.
Une dispersion commune à toutes les classes : moins de paramètres, frontière droite.
Voir la fiche → la version simplifiéeLe Naive Bayes gaussien est une QDA qui ignore les liens entre variables.
Voir la fiche → sans étiquettesRepère les heures anormales sans historique de pannes étiqueté.
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