Pourquoi votre projet de Maintenance Prédictive va échouer (et les leçons que j’en ai tirées de l’aéro)


Introduction

Un composant mécanique ne tombe pas en panne du jour au lendemain.

Il se dégrade, lentement, progressivement, de manière souvent imperceptible — jusqu’au moment où c’est trop tard. Une turbine qui vibre un peu plus fort. Un roulement dont la température monte imperceptiblement. Des signaux faibles que personne n’a su lire à temps.

Sur mon projet de recherche en aéronautique, j’avais exactement ce problème : estimer l’état d’usure réel d’un composant à partir de mesures de capteurs bruités et prédire combien de temps il lui restait avant de lâcher.

Ce que j’ai appris sur le terrain, c’est que le plus difficile n’était pas l’algorithme. C’était tout ce qui se passe autour.


Les trois façons de faire de la maintenance — et pourquoi deux d’entre elles vous coûtent cher

Si vous travaillez dans l’industrie, la maintenance est une réalité quotidienne. Mais derrière ce mot se cachent trois approches radicalement différentes, avec des coûts et des risques très inégaux.

La maintenance corrective — on répare quand ça casse. C’est l’approche par défaut dans beaucoup d’entreprises. Elle a un avantage : elle est simple. Elle a un inconvénient majeur : une panne imprévue coûte bien plus cher qu’une intervention planifiée. Arrêt de production, intervention d’urgence, pièces de rechange en express, pénalités contractuelles. Dans l’aéronautique, immobiliser un appareil au sol coûte entre 10 000 et 150 000€ par heure. Dans l’industrie manufacturière, une ligne d’assemblage arrêtée peut représenter plusieurs centaines de milliers d’euros par jour.

La maintenance préventive — on remplace à intervalles fixes, qu’on en ait besoin ou pas. C’est plus rassurant que la corrective mais elle génère un autre type de gaspillage : on remplace souvent des composants qui auraient pu tenir bien plus longtemps. Et paradoxalement, les interventions elles-mêmes introduisent parfois des défauts — un joint mal reposé, une vis mal serrée.

La maintenance prédictive — on intervient au bon moment, guidé par les données. L’idée est séduisante : plutôt que de réagir à la panne ou de suivre un calendrier arbitraire, on écoute ce que le composant dit lui-même de son état de santé.

Type de maintenancePrincipePrincipal problème
CorrectiveOn répare quand ça casseArrêts imprévus et coûteux
PréventiveOn remplace à date fixeRemplacement trop tôt ou trop tard
PrédictiveOn intervient au bon momentNécessite des données fiables et un modèle


Les chiffres circulent partout. Selon McKinsey, la maintenance prédictive peut réduire les coûts de maintenance de 10 à 40% et diminuer les arrêts non planifiés de 50%.

Alors tout le monde se lance les budgets data explosent, des équipes entières sont recrutées, des dashboard sont déployés.

Et pourtant, la plupart des projets n’aboutissent à rien de concret. Pas une décision prise différemment. Pas un composant remplacé au bon moment grâce aux données. Juste des coûts, de la frustration et un projet qui finit dans un tiroir.

Dans cet article, je vais vous expliquer pourquoi — en m’appuyant sur ce que j’ai vécu sur mon projet de recherche aéronautique, en utilisant un dataset public réel de la NASA et avec le code Python pour reproduire l’approche.

Ce n’est pas un tutoriel sur comment tout faire parfaitement. C’est un retour honnête sur ce qui coince vraiment.


Le dataset NASA C-MAPSS — des données réelles pour un problème réel

Pourquoi on ne peut pas apprendre la maintenance prédictive sur vos propres données (au début)

Voici un paradoxe que j’ai mis du temps à accepter sur mon projet aéro.

Pour entraîner un modèle de maintenance prédictive, vous avez besoin de données run-to-failure — c’est-à-dire l’historique complet d’un composant, depuis son état neuf jusqu’à sa défaillance réelle. Sans ça, impossible d’apprendre ce à quoi ressemble un composant en fin de vie.

Le problème : ces données n’existent presque jamais en entreprise.

Pourquoi ? Parce que les entreprises font de la maintenance préventive. Elles remplacent les composants avant qu’ils ne tombent en panne. Ce qui est une bonne pratique opérationnelle — mais qui prive complètement les algorithmes de la donnée la plus précieuse : la défaillance elle-même.

La NASA a résolu ce problème d’une façon élégante : en simulant.

C-MAPSS — le benchmark mondial

C-MAPSS signifie Commercial Modular Aero-Propulsion System Simulation. C’est un simulateur développé par le NASA Ames Prognostics Center of Excellence pour reproduire le comportement de moteurs turbofan soumis à une dégradation progressive et contrôlée.

Le principe : simuler 100 moteurs complets, de l’état parfaitement neuf jusqu’à la défaillance, en enregistrant à chaque cycle de vol les mesures de 21 capteurs. Le tout avec les vraies valeurs de durée de vie restante pour chaque instant — ce qu’on appelle la RUL, ou Remaining Useful Life.

Vous pouvez le télécharger gratuitement ici :
NASA Prognostics Data Repository

La structure du dataset FD001

Le dataset C-MAPSS est découpé en 4 sous-ensembles. On travaille sur FD001 — une seule condition opérationnelle, un seul mode de défaillance. C’est le point d’entrée idéal.

Sous-ensembleMoteursConditionsMode de défaillance
FD0011001Dégradation compresseur HP
FD0022606Dégradation compresseur HP
FD0031001Compresseur HP + HPC Fan
FD0042486Compresseur HP + HPC Fan


import pandas as pd

COL_NAMES = (
    ['unit', 'cycle', 'op1', 'op2', 'op3']
    + [f's{i}' for i in range(1, 22)]
)

df = pd.read_csv(
    'train_FD001.txt',
    sep=r's+',
    header=None,
    names=COL_NAMES + ['_drop1', '_drop2'],
)
df.drop(columns=['_drop1', '_drop2'], inplace=True)

# RUL réelle = cycles restants jusqu'à la défaillance
df['RUL'] = df.groupby('unit')['cycle'].transform('max') - df['cycle']

print(df.head())
structure du dataset FD001 de la NASA

Chaque ligne du fichier représente un cycle de vol d’un moteur.
Il y a 27 colonnes au total :

unit — l’identifiant du moteur (1 à 100). Chaque moteur est une trajectoire de dégradation indépendante.

cycle — le compteur de cycles de vol depuis la mise en service. Le dernier cycle enregistré correspond à la défaillance.

op1, op2, op3 — les réglages opérationnels au moment du cycle. Sur FD001, ils sont quasi-constants (une seule condition). Sur FD002 et FD004, ils varient significativement — c’est ce qui complique l’analyse.

s1 à s21 — les 21 capteurs. Températures, pressions, vitesses de rotation, débits d’air. Leurs noms réels sont volontairement anonymisés dans le dataset — ce qui est, paradoxalement, très réaliste. Sur beaucoup de projets industriels, la documentation des capteurs est incomplète ou absente.

RUL — le nombre de cycles restants avant la défaillance. C’est la variable qu’on cherche à prédire. Dans le dataset d’entraînement, elle est connue. En production, elle ne l’est pas — c’est tout l’objet du modèle.

FD001 simule la dégradation du compresseur haute pression, cette dégradation n’est pas uniforme d’un capteur à l’autre. Certains signaux montent progressivement avec l’usure, d’autres descendent, d’autres restent quasi-stables puis s’accélèrent brutalement dans les derniers cycles. C’est cette hétérogénéité — et cette non-linéarité partielle — qu’une régression linéaire simple ne capture pas, et que le filtre de Kalman gère naturellement en adaptant son gain à chaque instant.

Courbes de dégradation de 5 moteurs

Sélection des capteurs — le premier piège

Ne pas utiliser tous les capteurs

Quand on découvre le dataset C-MAPSS pour la première fois, le réflexe naturel est d’utiliser les 21 capteurs disponibles. Plus de données, meilleur le modèle — c’est l’intuition commune.

C’est une erreur.

Sur mon projet aéro, j’ai passé plusieurs semaines à sélectionner des capteurs pertinents.
Une grande partie des capteurs ne contenait aucune information (utile) sur la dégradation.
Ils mesuraient des grandeurs physiques qui ne variaient tout simplement pas avec l’usure du composant. Les inclure, c’était diluer le signal des capteurs informatifs.

La méthode : filtrage par variance

Un capteur qui ne varie pas a une variance proche de zéro. On peut éliminer automatiquement les capteurs non-informatifs :

sensor_cols = [f's{i}' for i in range(1, 22)]

# Calcul de la variance de chaque capteur sur l'ensemble du dataset
variances = df[sensor_cols].var()
VARIANCE_THRESHOLD = 0.01
USEFUL_SENSORS = variances[variances > VARIANCE_THRESHOLD].index.tolist()

print(f"Capteurs retenus : {USEFUL_SENSORS}")
Capteurs retenus : ['s2', 's3', 's4', 's7', 's9', 's11', 's12', 's14', 's17', 's20', 's21']

print(f"Capteurs écartés : {[s for s in sensor_cols if s not in USEFUL_SENSORS]}")
Capteurs écartés : ['s1', 's5', 's6', 's8', 's10', 's13', 's15', 's16', 's18', 's19']

On passe de 21 à 11 capteurs. C’est mieux — mais ce n’est pas suffisant.

Ce que la variance ne voit pas

La variance mesure l’agitation d’un signal. Elle ne mesure pas sa pertinence.

La vraie question n’est pas « est-ce que ce capteur varie ? » mais plutôt « est-ce que ce capteur varie en lien avec la dégradation ? »

correlations = df[USEFUL_SENSORS + ['RUL']].corr()['RUL'].drop('RUL')
print(correlations.sort_values())
s11   -0.696228
s4    -0.678948
s2    -0.606484
s17   -0.606154
s3    -0.584520
s9    -0.390102
s14   -0.306769
s20    0.629428
s21    0.635662
s7     0.657223
s12    0.671983

Un coefficient proche de -1 indique que la valeur du capteur augmente au fil des cycles tandis que la durée de vie restante diminue — les deux évoluent en sens inverse.
Un coefficient proche de +1 indique l’inverse : la valeur du capteur diminue à mesure que le moteur vieillit.
Dans les deux cas, le capteur est informatif sur la dégradation. Ce qui importe, c’est la valeur absolue du coefficient — plus elle est proche de 1, plus le capteur est utile.


Le Health Index — résumer 11 capteurs en un seul signal

Le problème : 11 capteurs, 11 unités différentes

On a 11 capteurs pertinents. Chacun mesure quelque chose de différent — une température en Kelvin, une pression en kPa, une vitesse en tr/min. Comment les combiner en un signal unique, cohérent, exploitable par un algorithme ?

C’est le rôle du Health Index.

Définition

Le Health Index (HI) est un indice synthétique, normalisé entre 0 et 1, qui résume l’état de santé global d’un composant à partir de l’ensemble de ses capteurs.

HI = 1  →  composant en parfait état (premier cycle de vol)
HI = 0  →  défaillance imminente (dernier cycle avant la panne)

Pourquoi ne pas travailler directement sur les 11 capteurs bruts ? Pour 3 raisons :

  1. l’hétérogénéité des unités,
  2. la robustesse face aux défaillances individuelles de capteurs,
  3. la simplicité algorithmique – Le filtre de Kalman dans sa version standard estime une grandeur scalaire.

Construction en trois étapes

Étape 1 — Normalisation Min-Max

df_hi = df.copy()
df_hi = df_hi.drop(NOT_USEFUL_SENSORS, axis=1)

for s in USEFUL_SENSORS:
    s_min = df[s].min()
    s_max = df[s].max()
    if s_max > s_min:
        df_hi[s] = (df[s] - s_min) / (s_max - s_min)
    else:
        df_hi[s] = 0.0

Étape 2 — Moyenne et inversion

Avant de moyenner, il faut orienter tous les capteurs dans le même sens çàd faire en sorte que chacun augmente avec la dégradation (ou tous diminuent, peu importe, mais de manière cohérente).

# On retourne les capteurs qui ont une corrélation POSITIVE avec la RUL
# (ils descendent avec la dégradation → on les retourne pour qu'ils montent)

for s in USEFUL_SENSORS:
    if correlations[s] > 0:  # corrélation positive = descend quand RUL descend
        df_hi[s] = 1 - df_hi[s]  # on retourne ce capteur

# Maintenant TOUS les capteurs montent avec la dégradation
# La moyenne est cohérente
df_hi['HI_raw'] = df_hi[USEFUL_SENSORS].mean(axis=1)

# L'inversion finale donne HI = 1 (neuf) → 0 (usé)
df_hi['HI'] = 1 - df_hi['HI_raw']

Étape 3 — Renormalisation finale

hi_min = df_hi['HI'].min()
hi_max = df_hi['HI'].max()
df_hi['HI'] = (df_hi['HI'] - hi_min) / (hi_max - hi_min)

Valider que le Health Index est correct

Un Health Index mal construit est pire qu’un signal brut. Le test est simple : le HI doit décroître régulièrement à mesure que la RUL diminue.

for lo, hi_rul, label in [
    (200, 9999, 'RUL ≥ 200    (neuf)   '),
    (100,  200, 'RUL 100-200           '),
    ( 50,  100, 'RUL 50-100            '),
    ( 20,   50, 'RUL 20-50             '),
    (  0,   20, 'RUL 0-20   (critique) '),
]:
    mask = (df_hi['RUL'] >= lo) & (df_hi['RUL'] < hi_rul)
    print(f"  {label} → HI moyen = {df_hi[mask]['HI'].mean():.3f}")

Sur FD001, vous devez obtenir :

  RUL ≥ 200    (neuf)    → HI moyen = 0.783
  RUL 100-200            → HI moyen = 0.735
  RUL 50-100             → HI moyen = 0.634
  RUL 20-50              → HI moyen = 0.482
  RUL 0-20   (critique)  → HI moyen = 0.295

Si la décroissance n’est pas monotone, revenez à la sélection des capteurs et vérifiez le signe de la corrélation de chacun avec la RUL.


Le filtre de Kalman — l’outil qui change tout

L’intuition avant les équations

Le filtre de Kalman a une réputation intimidante. Des matrices, de l’algèbre linéaire, des équations différentielles. La plupart des tutoriels commencent par les formules et perdent la moitié de leurs lecteurs dès la deuxième ligne.

Je vais faire l’inverse.

L’analogie du réservoir

Imaginez que vous conduisiez une voiture dont la jauge d’essence est défaillante. Elle indique quelque chose — mais elle fluctue aléatoirement. Parfois trop haute, parfois trop basse, jamais vraiment fiable.

Vous avez deux sources d’information pour estimer ce qu’il reste dans le réservoir.

La première : votre modèle. Vous savez que cette voiture consomme environ 6 litres aux 100 km. Vous avez fait 80 km depuis la dernière fois que vous avez fait le plein. Vous pouvez donc prédire qu’il vous reste environ 4,8 litres de moins qu’au départ.

La deuxième : votre jauge. Imparfaite, bruitée — mais pas complètement inutile. Si elle indique « presque vide » alors que votre modèle prédit encore la moitié du réservoir, vous ne l’ignorez pas. Vous en tenez compte, avec méfiance.

Intuitivement, vous faites déjà ce que fait le filtre de Kalman : vous combinez votre prédiction et votre mesure, en pondérant chacune selon sa fiabilité. Si vous faites confiance à votre modèle de consommation, vous lui accordez plus de poids. Si la jauge vient d’être réparée et est maintenant précise, vous lui accordez plus de poids.

C’est tout. C’est ça, le filtre de Kalman. La sophistication mathématique derrière n’est que la formalisation optimale de cette intuition.

Le cycle en deux étapes

Le filtre répète ce cycle à chaque nouveau cycle de vol :

Cycle du Filtre de Kalman

Étape 1 — Prédiction.
Le filtre utilise son modèle de dégradation pour projeter l’état probable du composant au prochain cycle. « Si ce moteur se dégrade progressivement où en sera son Health Index au prochain instant ? » À ce stade, l’incertitude augmente — du temps a passé, de la dégradation a eu lieu, et on n’a pas encore reçu de nouvelle mesure pour confirmer.

Étape 2 — Correction.
Le nouveau HI brut du cycle arrive. Le filtre compare cette mesure à sa prédiction. L’écart entre les deux — ce que la mesure apporte de nouveau par rapport à ce qu’on prédisait — s’appelle l’innovation. Le filtre ajuste son estimation en fonction de cet écart. Après la correction, l’incertitude diminue — on a intégré une nouvelle information.
Puis le cycle recommence.

Le Gain de Kalman — le curseur entre modèle et mesure

L’intensité de l’ajustement à l’étape 2 dépend d’un paramètre central : le Gain de Kalman, noté K.

K → 0  :  le filtre fait confiance au modèle, ignore presque la mesure
           → utile quand les capteurs sont très bruités
K → 1  :  le filtre suit les mesures de près, ignore presque le modèle
           → utile quand le modèle de dégradation est peu fiable
K entre les deux  :  compromis pondéré selon l'incertitude respective

Ce qui rend le filtre de Kalman élégant c’est que K n’est pas fixé à l’avance.
Il est calculé automatiquement à chaque cycle en fonction de l’incertitude actuelle du modèle (P) et du bruit de mesure (R).
Quand le modèle est très incertain, par exemple juste après un long intervalle sans mesure, K monte et le filtre se fie davantage aux capteurs.
Quand les capteurs sont très bruités, par exemple dans une zone de forte vibration, K descend et le filtre reste sur sa prédiction.

Les deux paramètres à calibrer : Q et R

Deux paramètres gouvernent le comportement du filtre. Comprendre leur rôle est aussi important que comprendre le code.

R — le bruit de mesure

C’est la variance du signal bruité de vos capteurs. Il quantifie à quel point vos mesures sont imprécises. Sur le dataset NASA, on l’estime sur la phase de début de vie, quand le composant est encore stable et que les variations observées sont quasi-exclusivement du bruit :R : estimé sur les moteurs encore neufs (RUL > 200 cycles)

early_life = df_hi[df_hi['RUL'] > 200]
R_calibre = float(early_life['HI'].var())
print(f"{R_calibre:.4f}")
0.0071

Q — le bruit du processus

C’est l’incertitude sur votre modèle de dégradation. Il n’a pas d’équivalent mesurable directement, il se calibre empiriquement, par itération sur des données historiques dont on connaît l’issue. C’est le paramètre le plus délicat, et le moins bien documenté dans la littérature.

# Q : calibré empiriquement — point de départ suggéré
Q_calibre = 1e-4  # à ajuster selon votre dataset

La règle intuitive : si la courbe filtrée zigzague encore trop → augmentez R.
Si le filtre réagit trop lentement aux vraies dégradations → augmentez Q.

Le code complet

def kalman_1d(measurements, Q=1e-4, R=0.01):
    """
    Filtre de Kalman scalaire (1D) pour l'estimation d'une dégradation.

    Paramètres
    ----------
    measurements : array-like — Health Index brut (bruité)
    Q            : float      — bruit du processus (incertitude modèle)
    R            : float      — bruit de mesure (variance capteurs)

    Retourne
    --------
    estimations  : np.ndarray — HI filtré à chaque pas de temps
    incertitudes : np.ndarray — écart-type de l'estimation (√P)
    """
    n = len(measurements)
    estimations  = np.zeros(n)
    incertitudes = np.zeros(n)

    x = float(measurements[0])  # initialisation sur la première mesure
    P = 0.1                      # incertitude initiale modérée

    for i, z in enumerate(measurements):

        # ── ÉTAPE 1 : PRÉDICTION ───────────────────────────────────────
        x_pred = x
        P_pred = P + Q    # l'incertitude grandit sans nouvelle mesure

        # ── GAIN DE KALMAN ─────────────────────────────────────────────
        K = P_pred / (P_pred + R)

        # ── ÉTAPE 2 : CORRECTION ───────────────────────────────────────
        # (z - x_pred) = innovation : ce que la mesure apporte de nouveau
        x = x_pred + K * (z - x_pred)
        P = (1 - K) * P_pred    # l'incertitude se réduit après la mesure

        estimations[i]  = x
        incertitudes[i] = np.sqrt(P)

    return estimations, incertitudes

Ce code est délibérément minimal. Il implémente le cas scalaire (1D) — une seule grandeur à estimer, le Health Index. C’est suffisant pour comprendre le mécanisme et produire des résultats solides sur FD001.

Ce que cela change par rapport à une régression linéaire

Une régression linéaire ajuste ses coefficients une fois sur l’historique complet. Elle suppose que la relation entre le temps et la dégradation est stable et fixe. C’est une hypothèse forte et elle tient raisonnablement bien au milieu de la vie du composant.

Elle tient mal en fin de vie, quand la dégradation s’accélère. Elle ne produit pas d’intervalle de confiance qui s’adapte à l’évolution du signal. Et elle ne détecte pas les changements de régime; un composant qui se dégrade soudainement plus vite (ou moins vite) qu’attendu.

Le filtre de Kalman fait les trois.
Son gain K s’adapte à chaque cycle selon la fiabilité relative du modèle et des mesures.
Son incertitude P évolue dynamiquement : elle monte quand le comportement devient imprévisible, elle descend quand le signal est cohérent.
Et quand la dégradation accélère brutalement, l’innovation (l’écart mesure/prédiction) explose. Ce que le filtre détecte immédiatement et intègre dans son estimation.

C’est pour ça qu’on ne fait pas une régression linéaire. Pas parce que c’est moins impressionnant — parce que c’est moins honnête sur l’incertitude, et moins réactif aux changements qui comptent.


La RUL par moteur — de l’estimation à la décision

Qu’est-ce que la RUL ?

Jusqu’ici nous avons construit un Health Index qui descend progressivement de 1 vers 0 au fil des cycles de vol. C’est utile, on sait que le composant se dégrade mais cela ne répond pas à la vraie question qu’un responsable de maintenance se pose chaque matin :

« Combien de temps me reste-t-il avant de devoir intervenir ? »

C’est exactement ce que mesure la RUL (Remaining Useful Life) ou durée de vie résiduelle en français. C’est le nombre de cycles restants avant que le composant atteigne un état critique nécessitant une intervention.

La différence entre le Health Index et la RUL est fondamentale. Le HI dit où on en est. La RUL dit combien de temps il reste. C’est la différence entre un thermomètre et une prévision météo. Les deux sont utiles — mais c’est la prévision qui permet de décider.

La RUL dans le dataset NASA – la vérité terrain

Dans le dataset C-MAPSS FD001, la RUL réelle est connue pour chaque moteur à chaque instant. Elle se calcule simplement :

# RUL réelle = cycles restants jusqu'à la défaillance
df['RUL'] = df.groupby('unit')['cycle'].transform('max') - df['cycle']

Pour un moteur qui a vécu 200 cycles au total :

  • Au cycle 1 → RUL = 199
  • Au cycle 100 → RUL = 100
  • Au cycle 199 → RUL = 1
  • Au cycle 200 → RUL = 0 → défaillance

En production, cette valeur n’existe pas. On ne sait pas combien de cycles il reste — c’est précisément ce qu’on cherche à estimer. C’est le rôle du modèle.

Comment estimer la RUL avec le filtre de Kalman

La RUL estimée à l’instant t est la distance en cycles entre t et le moment où l’estimation Kalman va franchir le seuil d’alerte.

SEUIL = 0.35  # à calibrer selon votre tolérance au risque

def compute_rul_trajectory(unit_data, Q, R, seuil):
    d = unit_data.sort_values('cycle')
    hi     = d['HI'].values
    cycles = d['cycle'].values

    est, unc = kalman_1d(hi, Q=Q, R=R)

    rul_central = np.full(len(est), np.nan)
    rul_lower   = np.full(len(est), np.nan)
    rul_upper   = np.full(len(est), np.nan)

    for i in range(len(est)):
        future_central = est[i:]
        future_lower   = (est - 2*unc)[i:]  # scénario pessimiste
        future_upper   = (est + 2*unc)[i:]  # scénario optimiste

        b_central = np.where(future_central <= seuil)[0]
        b_lower   = np.where(future_lower   <= seuil)[0]
        b_upper   = np.where(future_upper   <= seuil)[0]

        if len(b_central) > 0: rul_central[i] = b_central[0]
        if len(b_lower)   > 0: rul_lower[i]   = b_lower[0]
        if len(b_upper)   > 0: rul_upper[i]   = b_upper[0]

    return dict(cycles=cycles, est=est, unc=unc,
                rul_true=d['RUL'].values,
                rul_central=rul_central,
                rul_lower=rul_lower,
                rul_upper=rul_upper)

L’apport clé de Kalman par rapport à une régression linéaire : on ne calcule pas seulement une RUL centrale. On calcule aussi une fourchette d’incertitude — la RUL dans le scénario pessimiste (borne basse ±2σ) et dans le scénario optimiste (borne haute ±2σ). C’est cette fourchette qui informe la décision, pas seulement le chiffre central.

Les trois moteurs — ce que les graphiques nous disent

On applique maintenant ce calcul sur trois moteurs représentatifs du dataset : un à courte durée de vie, un à durée moyenne, un à longue durée de vie. C’est délibéré — on veut montrer que le modèle fonctionne quelle que soit la trajectoire individuelle du composant.

Pour chaque moteur, la visualisation montre trois choses :

Graphique 1 — Health Index

L’état de santé du moteur au fil du temps, résumé en un seul chiffre entre 0 et 1.

Health Index moteur 1
Health Index moteur 5
Health Index moteur 10

La courbe grise — c’est ce que les capteurs mesurent réellement. Elle est bruitée, elle zigzague — parce que les capteurs ne sont pas parfaits, parce que les conditions de vol varient légèrement d’un cycle à l’autre. C’est la réalité terrain, imparfaite.

La courbe rouge — c’est l’estimation du filtre de Kalman. Il a « nettoyé » le signal bruité pour en extraire la tendance réelle de dégradation. Elle est lisse, elle descend progressivement de 1 (neuf) vers 0 (usé).

La bande rose — c’est l’intervalle de confiance ±2σ autour de l’estimation rouge. Elle dit : « je suis certain à 95% que la vraie valeur du HI se trouve dans cette zone. » Quand la bande est étroite, le filtre est sûr de lui. Quand elle s’élargit, quelque chose d’inhabituel se passe — la dégradation s’accélère, ou un capteur devient instable.

La ligne pointillée orange — c’est le seuil d’alerte. Quand la courbe rouge passe en dessous, on considère que le moteur est entré en zone critique. C’est ce seuil qui déclenche le calcul de RUL.

Ce qu’il faut regarder en priorité :
La vitesse à laquelle la courbe rouge descend. Un moteur qui descend lentement a une longue vie devant lui. Un moteur dont la courbe s’accélère brutalement en fin de vie — c’est le signal le plus important.

Graphique 2 — Trajectoire RUL

À chaque instant, combien de cycles il reste avant que le moteur atteigne le seuil critique et dans quelle fourchette d’incertitude.

Trajectoire RUL moteur 1
Trajectoire RUL moteur 5
Trajectoire RUL moteur 10


La courbe noire pointillée — c’est la RUL réelle, calculée depuis le dataset NASA. Elle part du nombre de cycles total du moteur et descend linéairement vers 0. En production, cette courbe n’existe pas — c’est la vérité qu’on cherche à approcher.

La courbe rouge — c’est la RUL estimée par le modèle à chaque instant. Elle devrait suivre la courbe noire le plus fidèlement possible.

La courbe orange pointillée — c’est le scénario pessimiste. Le modèle dit : « dans le pire cas, en tenant compte de l’incertitude sur mes mesures, le moteur n’a plus que X cycles. » C’est cette courbe qui devrait déclencher les alertes en contexte industriel — on préfère intervenir un peu tôt plutôt que trop tard.

La courbe verte pointillée — c’est le scénario optimiste. « Dans le meilleur cas, il reste Y cycles. » Elle donne la borne haute de la fourchette.

La bande rose translucide — c’est la fourchette complète entre pessimiste et optimiste. Plus elle est large, plus le modèle est incertain sur le moment d’intervention.

La zone orange en bas — c’est la zone critique, quand la RUL passe sous 30 cycles. C’est là qu’une décision d’intervention devient urgente.

Ce qu’il faut regarder en priorité :
L’écart entre la courbe rouge et la courbe noire — c’est l’erreur de prédiction. Et la largeur de la bande — si elle explose brutalement, le comportement du moteur est devenu imprévisible.

Deux cas problématiques sont à surveiller :
⚠️ Courbe rouge AU-DESSUS de la noire → le modèle pense qu’il reste plus de temps qu’il n’en reste réellement, on a vraiment un risque de panne

Courbe rouge EN-DESSOUS de la noire → le modèle est trop conservateur, il va déclencher l’alerte trop tôt, ce n’est pas dangereux, c’est juste coûteux

Graphique 3 — Erreur de prédiction RUL

À chaque instant, de combien de cycles le modèle se trompe. C’est le graphique le plus honnête des trois — il montre directement la qualité de la prédiction dans le temps.

Erreur de prédiction RUL moteur 1
Erreur de prédiction RUL moteur 5
Erreur de prédiction RUL moteur 10

La ligne noire pointillée à zéro — c’est la prédiction parfaite. Si la courbe violette était collée sur cette ligne du début à la fin, le modèle prédirait la RUL exacte à chaque instant. En pratique, personne n’y arrive.

La zone verte (±15 cycles) — c’est la zone d’erreur acceptable en contexte industriel standard. Se tromper de moins de 15 cycles sur la RUL, c’est suffisamment précis pour planifier une intervention.

La zone orange (±30 cycles) — c’est la zone tolérable. Au-delà de 30 cycles d’erreur, la prédiction devient peu utile pour la planification.

La courbe violette — c’est l’erreur réelle à chaque instant, calculée comme ceci :

Erreur = RUL estimée − RUL réelle

Le RMSE et le MAE sont deux métriques qui résument la qualité globale du modèle sur ce moteur :

  • RMSE (Root Mean Square Error) — pénalise fort les grandes erreurs. Un RMSE de 20 cycles signifie qu’en moyenne le modèle se trompe de ±20 cycles, mais les grosses erreurs pèsent plus dans le calcul.
  • MAE (Mean Absolute Error) — erreur moyenne simple, sans pénalité sur les grandes erreurs. Plus facile à interpréter.

Ce qu’il faut regarder en priorité :

Le signe de l’erreur — est-ce que la courbe violette est plutôt au-dessus ou en dessous de zéro ?
Une erreur positive signifie que le modèle sur-estime la durée de vie restante — il pense qu’il reste plus de temps qu’il n’en reste réellement, ce qui est le scénario risqué.
Une erreur négative signifie qu’il sous-estime — il est conservateur, il déclenche l’alerte trop tôt, ce qui coûte de l’argent mais ne met rien en danger.

L’évolution temporelle — l’erreur est-elle stable tout au long de la vie du moteur, ou explose-t-elle en fin de vie ? Un bon modèle voit son erreur diminuer à mesure qu’on s’approche de la défaillance — le signal de dégradation s’amplifie et devient plus facile à suivre.

En résumé — comment les lire ensemble
Graphique 1  →  "Comment se porte le moteur en ce moment ?"
Graphique 2  →  "Combien de temps lui reste-t-il ?"
Graphique 3  →  "À quel point peut-on faire confiance à cette estimation ?"

Les trois se lisent dans cet ordre.
Si le graphique 1 montre une bande d’incertitude qui s’élargit brutalement on doit s’attendre à voir le graphique 3 se dégrader au même endroit ; le modèle perd de la précision exactement là où le comportement du moteur devient imprévisible.
C’est la cohérence entre les trois graphiques qui donne la vraie information.

C’est le troisième graphique — l’erreur — que j’aurais aimé voir systématiquement sur mon projet aéro. Et que personne ne produisait.

Erreur > 0  →  modèle trop optimiste  →  risque de panne imprévue  ⚠️
Erreur < 0  →  modèle trop conservateur  →  intervention précoce    ✓
Erreur = 0  →  prédiction parfaite  →  n'existe pas en pratique

Dans la plupart des contextes industriels, sur-estimer la durée de vie restante (erreur positive) est bien plus dangereux que la sous-estimer. Une erreur positive, c’est un composant laissé en service trop longtemps — panne imprévue, dégâts en cascade. Une erreur négative, c’est un composant remplacé trop tôt — gaspillage, mais pas de catastrophe.

La leçon : ne jamais évaluer un modèle de maintenance prédictive uniquement sur son RMSE global. Regardez la distribution temporelle de l’erreur. Regardez le signe. Regardez ce qui se passe dans les 30 derniers cycles — c’est là que tout se joue.


Les 4 leçons terrain

Il existe des dizaines de tutoriels sur le filtre de Kalman, des centaines d’articles académiques sur la maintenance prédictive. Presque aucun ne parle de ce qui se passe vraiment quand on essaie de faire tourner ces modèles sur des données industrielles réelles.

Ce qui suit n’est pas de la théorie. C’est ce que j’aurais voulu lire avant de commencer.

Leçon 1 — Le modèle de dégradation est tout

Le filtre de Kalman est souvent présenté comme un algorithme universel. Donnez-lui des mesures bruitées, il vous rendra un signal propre. C’est vrai — mais c’est incomplet.

Le filtre de Kalman est aussi bon que le modèle de dégradation qu’on lui donne. Il raffine une hypothèse. Il n’en crée pas une.

Sur notre projet, la première version du filtre utilisait un modèle de dégradation linéaire — on supposait que l’usure progressait de manière constante à chaque cycle de vol. C’était simple, rapide à implémenter, et raisonnablement correct.

Mais tous les composants ne suivent pas une courbe de dégradation linéaire. Certains suivent une phase quasi-stable où presque rien ne se passe visuellement puis une accélération brutale dans les derniers cycles avant la défaillance. C’est précisément dans cette phase d’accélération — là où la précision est la plus critique — que le modèle linéaire décroche.

C’est la preuve que le modèle n’est pas adapté et il faut en chercher un autre.

La leçon : avant de choisir un algorithme demandez-vous comment le composant se dégrade ? De manière linéaire ? Exponentielle ? Est-ce qu’il y a une phase de stabilité suivie d’une accélération ?

Leçon 2 — Q est le paramètre que personne ne documente


Sur le filtre de Kalman, R est relativement facile à calibrer. C’est la variance du bruit de mesure — on peut l’estimer en laboratoire, sur des données de début de vie quand le composant est encore stable. C’est une mesure objective.

Pour Q c’est une toute autre histoire.

Q représente l’incertitude sur votre modèle de dégradation çàd à quel point votre hypothèse sur la façon dont le composant se dégrade est imparfaite. Il n’existe pas de formule pour le calculer. Il se choisit et ce choix a des conséquences importantes.

Un Q trop grand : le filtre surréagit à chaque mesure. La courbe filtrée zigzague encore presque autant que le signal brut. On a fait beaucoup de bruit pour rien.

Un Q trop petit : le filtre est trop rigide. Quand la dégradation s’accélère brutalement en fin de vie — exactement le moment critique — le filtre continue sur sa lancée, ignore le changement de régime et rate l’alerte.

Sur notre projet, on a testé différentes valeurs de Q pour que le modèle se cale le plus possible à la dégradation réelle. C’est du tâtonnement rigoureux.

La leçon : documentez votre procédure de calibration de Q comme si quelqu’un d’autre devait reprendre le projet dans six mois. Notez pourquoi vous avez choisi cette valeur, sur quelles données, avec quelle métrique.

Leçon 3 — L’intervalle de confiance est sous-exploité

La plupart des projets de maintenance prédictive produisent une courbe. Une ligne. Un chiffre à chaque instant. Et sur cette ligne, un seuil : en dessous, on intervient.

Ce chiffre est une moyenne. Il ne dit pas à quel point on est certain de cette estimation.

Sur notre projet, c’est la largeur de la bande d’incertitude qui a commencé à déclencher les premières vraies alertes utiles — pas le franchissement d’un seuil fixe sur la valeur centrale. Quand l’intervalle de confiance commençait à s’élargir brutalement, c’était presque toujours le signe avant-coureur d’un changement de régime de dégradation. Souvent 20 à 30 cycles avant que la valeur centrale ne franchisse le seuil.

Pourquoi l’intervalle s’élargit-il ? Parce que le filtre de Kalman détecte une incohérence entre ce que son modèle prédit et ce que les capteurs mesurent. Il ne sait pas encore si c’est du bruit ou un vrai changement — alors il augmente son incertitude. C’est honnête. Et c’est précieux.

Un composant dont l’intervalle de confiance reste étroit est un composant dont le comportement est prévisible. Un composant dont l’intervalle explose est un composant dont le comportement devient imprévisible — et c’est souvent le premier signal de défaillance imminente, bien avant que la valeur centrale ne franchisse quoi que ce soit.

La leçon : ne livrez jamais une prédiction sans son intervalle de confiance. Et ne regardez pas seulement la valeur centrale — regardez si la bande s’élargit. C’est vrai pour la maintenance prédictive, c’est vrai pour tous les modèles data en production.

Leçon 4 — Kalman a des limites et il faut les connaître

Le filtre de Kalman classique repose sur une hypothèse fondamentale : la dégradation suit un processus gaussien. En clair, les erreurs et le bruit se distribuent en cloche symétrique autour de la moyenne. C’est une excellente approximation pour des dégradations lentes, progressives, régulières.

C’est une mauvaise approximation pour des défaillances avec des sauts brutaux.

Ce n’est pas un défaut du filtre de Kalman — c’est une limite connue et documentée. Pour des dégradations non-gaussiennes, des variantes plus robustes existent :

L’Unscented Kalman Filter (UKF) gère mieux les systèmes non-linéaires en propageant un ensemble de points sigma plutôt qu’une estimation gaussienne unique.

Le Particle Filter abandonne complètement l’hypothèse gaussienne ; il représente la distribution de l’état par un ensemble de particules pondérées, ce qui lui permet de gérer des distributions quelconques, y compris multimodales.

Ces approches sont plus puissantes. Elles sont aussi significativement plus complexes à implémenter et à calibrer.

La leçon : connaître les limites de votre outil est aussi important que savoir l’utiliser. Avant de déployer un filtre de Kalman en production, posez-vous la question : est-ce que ma dégradation peut présenter des sauts brutaux ? Si la réponse est oui — micro-fissures, contaminations soudaines, chocs mécaniques — le Kalman classique n’est peut-être pas le bon choix, ou du moins pas le seul.


Ce que ces quatre leçons ont en commun

Relisez-les. Aucune n’est une leçon d’algorithme. Aucune ne parle de lignes de code.

Elles parlent de modèles physiques, de documentation, d’incertitude, et de limites. Ce sont des leçons d’ingénierie — pas de data science au sens académique du terme.

C’est là, je crois, que se joue la différence entre un projet de maintenance prédictive qui aboutit et un projet qui finit dans un tiroir. Les algorithmes sont accessibles à tous — ils sont dans les papiers, dans les tutoriels, dans les bibliothèques open source.
Ce qui est rare, c’est la compréhension de ce qui se passe autour : pourquoi le modèle décroche, où regarder quand il dérive, comment expliquer ses limites à un ingénieur de maintenance qui n’a jamais ouvert un Jupyter notebook.

C’est cette compréhension-là qu’on construit sur le terrain. Et qu’on peut accélérer avec la bonne formation.


Conclusion

Ce que l’on a construit ensemble

Faisons un pas en arrière.

Nous sommes partis d’un fichier texte brut — 26 colonnes sans en-tête, 100 moteurs, des capteurs anonymisés. Et on en a extrait quelque chose d’utile : une estimation de la durée de vie résiduelle de chaque moteur, avec sa fourchette d’incertitude, mise à jour à chaque nouveau cycle de vol.

Ce n’est pas de la magie. C’est une chaîne de décisions rigoureuses.

Sélectionner les bons capteurs plutôt que d’utiliser tout ce qui est disponible. Construire un Health Index qui résume l’état de santé en un signal cohérent. Appliquer un filtre de Kalman qui combine intelligemment ce qu’on sait avec ce qu’on observe. Calculer une RUL individuelle par moteur — pas une moyenne globale, mais une trajectoire propre à chaque composant avec son propre niveau d’incertitude.

Et surtout : comprendre où ça peut mal tourner. Un modèle de dégradation trop simple. Un paramètre Q mal calibré et non documenté. Un intervalle de confiance qu’on ne regarde pas. Une hypothèse gaussienne qui ne tient pas face à des sauts brutaux.

Ce que la maintenance prédictive n’est pas

La maintenance prédictive n’est pas un problème qu’on résout en choisissant le bon algorithme. C’est un problème qu’on résout en comprenant physiquement ce qui se dégrade, en auditant sérieusement ses données, en impliquant les ingénieurs de maintenance dès le début, et en évaluant honnêtement les limites du modèle avant de le déployer.

L’algorithme est la partie émergée de l’iceberg.

La partie immergée, c’est tout ce qu’on a vu dans cet article : la sélection des capteurs, le Health Index, la calibration, l’interprétation des erreurs, la connaissance des limites.

C’est cette partie immergée qui détermine si un projet aboutit ou finit dans un tiroir.


Vous voulez aller plus loin ?

Je prépare une formation complète sur la maintenance prédictive appliquée à l’industrie — du pipeline de données au modèle en production, sur des données réelles NASA et au-delà.

Les inscrits sur la liste d’attente seront les premiers prévenus. Et bénéficieront d’un tarif de lancement.

Ce qu’on n’a pas couvert dans cet article :

  • Le pipeline complet clé-en-main sur les 4 sous-ensembles C-MAPSS, avec la complexité réelle des conditions opérationnelles multiples
  • La sélection avancée des capteurs par ACP et corrélation pondérée
  • La calibration croisée de Q et R sur données historiques, avec procédure documentée
  • L’analyse asymétrique des erreurs et l’optimisation du seuil d’alerte
  • L’Unscented Kalman Filter et le filtre particulaire pour les dégradations non-gaussiennes
  • L’adaptation à d’autres secteurs : énergie, industrie manufacturière, transport

Les inscrits sur la liste d’attente seront les premiers prévenus et bénéficieront d’un tarif de lancement.


A vous de jouer

Sur quel type de composant ou de secteur travaillez-vous ?
Quel est le signal que vous cherchez à estimer ?

Dites-le moi en commentaire — je lis tout et ça m’aidera à calibrer le contenu de la formation sur vos vrais besoins.

Laisser un commentaire