Tutoriel : créer, évaluer et noter un modèle de détection d’erreur de machine
Ce tutoriel présente un exemple de bout en bout d’un workflow Synapse Data Science dans Microsoft Fabric. Le scénario utilise le Machine Learning pour une approche plus systématique du diagnostic des erreurs, pour identifier de manière proactive les problèmes et prendre des mesures avant une défaillance réelle de l’ordinateur. L’objectif est de prédire si une machine connaîtrait un échec en fonction de la température du processus, de la vitesse de rotation, etc.
Ce tutoriel décrit les étapes suivantes :
- Installer des bibliothèques personnalisées
- Charger et traiter les données
- Comprendre les données par le biais d’une analyse exploratoire des données
- Utiliser scikit-learn, LightGBM et MLflow pour entraîner des modèles de machine learning et utiliser la fonctionnalité de journalisation automatique de Fabric pour suivre les expériences.
- Noter les modèles entraînés avec la fonctionnalité Fabric
PREDICT
, enregistrer le meilleur modèle et charger ce modèle pour les prédictions - Afficher les performances du modèle chargé avec les visualisations Power BI
Conditions préalables
Obtenez un abonnement Microsoft Fabric . Vous pouvez également vous inscrire à une version d’évaluation gratuite de Microsoft Fabric .
Connectez-vous à Microsoft Fabric.
Utilisez le sélecteur d’expérience en bas à gauche de votre page d’accueil pour basculer vers Fabric.
- Si nécessaire, créez un « lakehouse » dans Microsoft Fabric comme il est décrit dans Créer un lakehouse dans Microsoft Fabric.
Suivre dans un notebook
Vous pouvez choisir l’une de ces options à suivre dans un bloc-notes :
- Ouvrez et exécutez le notebook intégré.
- Chargez votre bloc-notes à partir de GitHub.
Ouvrir le notebook intégré
L'exemple de panne de machine notebook accompagne ce didacticiel.
Pour ouvrir le notebook d'exemple pour ce didacticiel, suivez les instructions de Préparer votre système pour les didacticiels de science des données.
Assurez-vous d’attacher un lakehouse au notebook avant de commencer à exécuter du code.
Importer le notebook à partir de GitHub
Le notebook AISample - Maintenance prédictive accompagne ce didacticiel.
Pour ouvrir le bloc-notes associé pour ce didacticiel, suivez les instructions de Préparer votre système pour les didacticiels de science des données pour importer le bloc-notes dans votre espace de travail.
Si vous préférez copier et coller le code à partir de cette page, vous pouvez créer un bloc-notes.
Assurez-vous d'attacher un lakehouse au notebook avant de commencer à exécuter du code.
Étape 1 : Installer des bibliothèques personnalisées
Pour le développement de modèles Machine Learning ou l’analyse des données ad hoc, vous devrez peut-être installer rapidement une bibliothèque personnalisée pour votre session Apache Spark. Vous avez deux options d’installation des bibliothèques.
- Utilisez les fonctionnalités d’installation inline (
%pip
ou%conda
) de votre notebook pour installer une bibliothèque, dans votre bloc-notes actuel uniquement. - Vous pouvez également créer un environnement Fabric, installer des bibliothèques à partir de sources publiques ou charger des bibliothèques personnalisées vers celui-ci, puis l’administrateur de votre espace de travail peut attacher l’environnement comme valeur par défaut pour l’espace de travail. Toutes les bibliothèques de l’environnement seront ensuite disponibles pour être utilisées dans les blocs-notes et les définitions de travaux Spark dans l’espace de travail. Pour plus d’informations sur les environnements, consultez créer, configurer et utiliser un environnement dans Microsoft Fabric.
Pour ce tutoriel, utilisez %pip install
pour installer la bibliothèque de imblearn
dans votre notebook.
Remarque
Le noyau PySpark redémarre après l’exécution de %pip install
. Installez les bibliothèques nécessaires avant d’exécuter d’autres cellules.
# Use pip to install imblearn
%pip install imblearn
Étape 2 : Charger les données
Le jeu de données simule la journalisation des paramètres d’une machine de fabrication en fonction du temps, ce qui est courant dans le milieu industriel. Il se compose de 10 000 points de données stockés sous forme de lignes avec des caractéristiques sous forme de colonnes. Les fonctionnalités sont les suivantes :
Identificateur unique (UID) allant de 1 à 1 000
ID de produit, composé d’une lettre L (pour faible), M (pour moyen) ou H (pour la valeur élevée), pour indiquer la variante de qualité du produit et un numéro de série spécifique à une variante. Les variantes de faible, moyenne et haute qualité constituent respectivement 60%, 30%et 10% de tous les produits, respectivement
Température de l’air, en degrés Kelvin (K)
Température du processus, en degrés Kelvin
Vitesse de rotation, en révolutions par minute (RPM)
Couple, en Newton-Meters (Nm)
L'usure de l'outil, en minutes. Les variantes de qualité H, M et L ajoutent respectivement 5, 3 et 2 minutes d’utilisation de l’outil utilisé dans le processus
Étiquette d’échec de l’ordinateur pour indiquer si l’ordinateur a échoué dans le point de données spécifique. Ce point de données spécifique peut avoir l’un des cinq modes d’échec indépendants suivants :
- Échec de l’usure de l’outil (TWF) : l’outil est remplacé ou échoue à un temps d’usure d’outil sélectionné de façon aléatoire, entre 200 et 240 minutes
- Échec de dissipation thermique (HDF) : la dissipation thermique provoque une défaillance du processus si la différence entre la température de l’air et la température du processus est inférieure à 8,6 K, et la vitesse de rotation de l’outil est inférieure à 1380 RPM
- Panne d’alimentation (PWF) : le produit de la vitesse de couple et de rotation (en rad/s) est égal à la puissance requise pour le processus. Le processus échoue si cette puissance tombe en dessous de 3 500 W ou dépasse 9 000 W
- Échec du surentraînement (OSF) : si le produit de l’usure et du couple dépasse 11 000 Nm minimum pour la variante de produit L (12 000 pour M, 13 000 pour H), le processus échoue en raison d’un surentraînement
- Échecs aléatoires (RNF) : chaque processus a une probabilité d’échec de 0,1%, quels que soient les paramètres du processus
Remarque
Si au moins l’un des modes d’échec ci-dessus est vrai, le processus échoue et l’étiquette « Échec de l’ordinateur » est définie sur 1. La méthode Machine Learning ne peut pas déterminer quel mode d’échec a provoqué l’échec du processus.
Téléchargez le jeu de données et chargez-le dans le lakehouse
Connectez-vous au conteneur Azure Open Datasets et chargez le jeu de données maintenance prédictive. Ce code télécharge une version publique du jeu de données, puis la stocke dans un lac de données Fabric.
Important
Ajoutez un "lakehouse" au bloc-notes avant de l’exécuter. Sinon, vous rencontrerez une erreur. Pour plus d'informations sur l'ajout d'un lakehouse, consultez Connecter des lakehouses et des notebooks.
# Download demo data files into the lakehouse if they don't exist
import os, requests
DATA_FOLDER = "Files/predictive_maintenance/" # Folder that contains the dataset
DATA_FILE = "predictive_maintenance.csv" # Data file name
remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/MachineFaultDetection"
file_list = ["predictive_maintenance.csv"]
download_path = f"/lakehouse/default/{DATA_FOLDER}/raw"
if not os.path.exists("/lakehouse/default"):
raise FileNotFoundError(
"Default lakehouse not found, please add a lakehouse and restart the session."
)
os.makedirs(download_path, exist_ok=True)
for fname in file_list:
if not os.path.exists(f"{download_path}/{fname}"):
r = requests.get(f"{remote_url}/{fname}", timeout=30)
with open(f"{download_path}/{fname}", "wb") as f:
f.write(r.content)
print("Downloaded demo data files into lakehouse.")
Après avoir téléchargé le jeu de données dans le lac de données, vous pouvez le charger en tant que DataFrame Spark :
df = (
spark.read.option("header", True)
.option("inferSchema", True)
.csv(f"{DATA_FOLDER}raw/{DATA_FILE}")
.cache()
)
df.show(5)
Ce tableau affiche un aperçu des données :
UDI | ID de produit | Type | Température de l’air [K] | Température du processus [K] | Vitesse de rotation [rpm] | Couple [Nm] | Usure des outils [min] | Cible | Type d’échec |
---|---|---|---|---|---|---|---|---|---|
1 | M14860 | M | 298.1 | 308,6 | 1551 | 42.8 | 0 | 0 | Aucun échec |
2 | L47181 | L | 298,2 | 308,7 | 1408 | 46.3 | 3 | 0 | Aucun échec |
3 | L47182 | L | 298.1 | 308.5 | 1498 | 49.4 | 5 | 0 | Aucun échec |
4 | L47183 | L | 298,2 | 308,6 | 1433 | 39.5 | 7 | 0 | Aucun échec |
5 | L47184 | L | 298,2 | 308,7 | 1408 | 40.0 | 9 | 0 | Aucun échec |
Écrire un DataFrame Spark dans une table Delta Lakehouse
Mettez en forme les données (par exemple, remplacez les espaces par des traits de soulignement) pour faciliter les opérations Spark dans les étapes suivantes :
# Replace the space in the column name with an underscore to avoid an invalid character while saving
df = df.toDF(*(c.replace(' ', '_') for c in df.columns))
table_name = "predictive_maintenance_data"
df.show(5)
Ce tableau affiche un aperçu des données avec des noms de colonnes reformatés :
UDI | Product_ID | Type | Température_de_l'air_[K] | Process_temperature_[K] | Vitesse_de_rotation_[rpm] | Torque_[Nm] | Usure_de_l'outil_[min] | Cible | Type de défaillance |
---|---|---|---|---|---|---|---|---|---|
1 | M14860 | M | 298.1 | 308.6 | 1551 | 42.8 | 0 | 0 | Aucun échec |
2 | L47181 | L | 298,2 | 308,7 | 1408 | 46.3 | 3 | 0 | Aucun échec |
3 | L47182 | L | 298.1 | 308.5 | 1498 | 49.4 | 5 | 0 | Aucun échec |
4 | L47183 | L | 298,2 | 308,6 | 1433 | 39.5 | 7 | 0 | Aucun échec |
5 | L47184 | L | 298,2 | 308.7 | 1408 | 40.0 | 9 | 0 | Aucun échec |
# Save data with processed columns to the lakehouse
df.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")
Étape 3 : Prétraiter les données et effectuer une analyse exploratoire des données
Convertissez le DataFrame Spark en dataFrame pandas pour utiliser des bibliothèques de traçage populaires compatibles avec Pandas.
Conseil
Pour un jeu de données volumineux, vous devrez peut-être charger une partie de ce jeu de données.
data = spark.read.format("delta").load("Tables/predictive_maintenance_data")
SEED = 1234
df = data.toPandas()
df.drop(['UDI', 'Product_ID'],axis=1,inplace=True)
# Rename the Target column to IsFail
df = df.rename(columns = {'Target': "IsFail"})
df.info()
Convertissez des colonnes spécifiques du jeu de données en types floats ou entiers selon les besoins et les chaînes cartographiques ('L'
, 'M'
, 'H'
) en valeurs numériques (0
, 1
, 2
) :
# Convert temperature, rotational speed, torque, and tool wear columns to float
df['Air_temperature_[K]'] = df['Air_temperature_[K]'].astype(float)
df['Process_temperature_[K]'] = df['Process_temperature_[K]'].astype(float)
df['Rotational_speed_[rpm]'] = df['Rotational_speed_[rpm]'].astype(float)
df['Torque_[Nm]'] = df['Torque_[Nm]'].astype(float)
df['Tool_wear_[min]'] = df['Tool_wear_[min]'].astype(float)
# Convert the 'Target' column to an integer
df['IsFail'] = df['IsFail'].astype(int)
# Map 'L', 'M', 'H' to numerical values
df['Type'] = df['Type'].map({'L': 0, 'M': 1, 'H': 2})
Explorer les données par le biais de visualisations
# Import packages and set plotting style
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
sns.set_style('darkgrid')
# Create the correlation matrix
corr_matrix = df.corr(numeric_only=True)
# Plot a heatmap
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True)
plt.show()
Comme prévu, l’échec (IsFail
) correspond aux fonctionnalités sélectionnées (colonnes). La matrice de corrélation montre que Air_temperature
, Process_temperature
, Rotational_speed
, Torque
et Tool_wear
ont la corrélation la plus élevée avec la variable IsFail
.
# Plot histograms of select features
fig, axes = plt.subplots(2, 3, figsize=(18,10))
columns = ['Air_temperature_[K]', 'Process_temperature_[K]', 'Rotational_speed_[rpm]', 'Torque_[Nm]', 'Tool_wear_[min]']
data=df.copy()
for ind, item in enumerate (columns):
column = columns[ind]
df_column = data[column]
df_column.hist(ax = axes[ind%2][ind//2], bins=32).set_title(item)
fig.supylabel('count')
fig.subplots_adjust(hspace=0.2)
fig.delaxes(axes[1,2])
Comme le montrent les graphiques tracés, les variables Air_temperature
, Process_temperature
, Rotational_speed
, Torque
et Tool_wear
ne sont pas rares. Ils semblent avoir une bonne continuité dans l’espace de fonctionnalité. Ces tracés confirment que l’entraînement d’un modèle Machine Learning sur ce jeu de données produit probablement des résultats fiables qui peuvent être généralisés à un nouveau jeu de données.
Inspecter la variable cible pour déséquilibre de classes
Comptez le nombre d’échantillons pour les machines ayant échoué et non échoué, puis inspectez l’équilibre des données pour chaque classe (IsFail=0
, IsFail=1
) :
# Plot the counts for no failure and each failure type
plt.figure(figsize=(12, 2))
ax = sns.countplot(x='Failure_Type', data=df)
for p in ax.patches:
ax.annotate(f'{p.get_height()}', (p.get_x()+0.4, p.get_height()+50))
plt.show()
# Plot the counts for no failure versus the sum of all failure types
plt.figure(figsize=(4, 2))
ax = sns.countplot(x='IsFail', data=df)
for p in ax.patches:
ax.annotate(f'{p.get_height()}', (p.get_x()+0.4, p.get_height()+50))
plt.show()
Les tracés indiquent que la classe sans échec (indiquée comme IsFail=0
dans le deuxième tracé) constitue la plupart des échantillons. Utilisez une technique de surachantillonnage pour créer un jeu de données d’entraînement plus équilibré :
# Separate features and target
features = df[['Type', 'Air_temperature_[K]', 'Process_temperature_[K]', 'Rotational_speed_[rpm]', 'Torque_[Nm]', 'Tool_wear_[min]']]
labels = df['IsFail']
# Split the dataset into the training and testing sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)
# Ignore warnings
import warnings
warnings.filterwarnings('ignore')
# Save test data to the lakehouse for use in future sections
table_name = "predictive_maintenance_test_data"
df_test_X = spark.createDataFrame(X_test)
df_test_X.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")
Suréchantillonner pour équilibrer les classes dans le jeu de données d’entraînement
L’analyse précédente a montré que le jeu de données est très déséquilibré. Ce déséquilibre devient un problème, car la classe minoritaire a trop peu d’exemples pour que le modèle apprenne efficacement la limite de décision.
SMOTE peut résoudre le problème. SMOTE est une technique de suréchantillonnage largement utilisée qui génère des exemples synthétiques. Il génère des exemples pour la classe minoritaire basée sur les distances euclidiennes entre les points de données. Cette méthode diffère de l’échantillonnage aléatoire, car elle crée de nouveaux exemples qui ne dupliquent pas simplement la classe minoritaire. La méthode devient une technique plus efficace pour gérer les jeux de données déséquilibrés.
# Disable MLflow autologging because you don't want to track SMOTE fitting
import mlflow
mlflow.autolog(disable=True)
from imblearn.combine import SMOTETomek
smt = SMOTETomek(random_state=SEED)
X_train_res, y_train_res = smt.fit_resample(X_train, y_train)
# Plot the counts for both classes
plt.figure(figsize=(4, 2))
ax = sns.countplot(x='IsFail', data=pd.DataFrame({'IsFail': y_train_res.values}))
for p in ax.patches:
ax.annotate(f'{p.get_height()}', (p.get_x()+0.4, p.get_height()+50))
plt.show()
Vous avez correctement équilibré le jeu de données. Vous pouvez maintenant passer à l’entraînement du modèle.
Étape 4 : Entraîner et évaluer les modèles
MLflow inscrit des modèles, entraîne et compare différents modèles et choisit le meilleur modèle à des fins de prédiction. Vous pouvez utiliser les trois modèles suivants pour l’entraînement des modèles :
- Classifieur de forêt aléatoire
- Classifieur de régression logistique
- Classifieur XGBoost
Entraîner un classifieur de forêt aléatoire
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from mlflow.models.signature import infer_signature
from sklearn.metrics import f1_score, accuracy_score, recall_score
mlflow.set_experiment("Machine_Failure_Classification")
mlflow.autolog(exclusive=False) # This is needed to override the preconfigured autologging behavior
with mlflow.start_run() as run:
rfc_id = run.info.run_id
print(f"run_id {rfc_id}, status: {run.info.status}")
rfc = RandomForestClassifier(max_depth=5, n_estimators=50)
rfc.fit(X_train_res, y_train_res)
signature = infer_signature(X_train_res, y_train_res)
mlflow.sklearn.log_model(
rfc,
"machine_failure_model_rf",
signature=signature,
registered_model_name="machine_failure_model_rf"
)
y_pred_train = rfc.predict(X_train)
# Calculate the classification metrics for test data
f1_train = f1_score(y_train, y_pred_train, average='weighted')
accuracy_train = accuracy_score(y_train, y_pred_train)
recall_train = recall_score(y_train, y_pred_train, average='weighted')
# Log the classification metrics to MLflow
mlflow.log_metric("f1_score_train", f1_train)
mlflow.log_metric("accuracy_train", accuracy_train)
mlflow.log_metric("recall_train", recall_train)
# Print the run ID and the classification metrics
print("F1 score_train:", f1_train)
print("Accuracy_train:", accuracy_train)
print("Recall_train:", recall_train)
y_pred_test = rfc.predict(X_test)
# Calculate the classification metrics for test data
f1_test = f1_score(y_test, y_pred_test, average='weighted')
accuracy_test = accuracy_score(y_test, y_pred_test)
recall_test = recall_score(y_test, y_pred_test, average='weighted')
# Log the classification metrics to MLflow
mlflow.log_metric("f1_score_test", f1_test)
mlflow.log_metric("accuracy_test", accuracy_test)
mlflow.log_metric("recall_test", recall_test)
# Print the classification metrics
print("F1 score_test:", f1_test)
print("Accuracy_test:", accuracy_test)
print("Recall_test:", recall_test)
À partir de la sortie, les jeux de données d’entraînement et de test produisent un score F1, une précision et un rappel d’environ 0,9 lors de l’utilisation du classifieur de forêt aléatoire.
Entraîner un classifieur de régression logistique
from sklearn.linear_model import LogisticRegression
with mlflow.start_run() as run:
lr_id = run.info.run_id
print(f"run_id {lr_id}, status: {run.info.status}")
lr = LogisticRegression(random_state=42)
lr.fit(X_train_res, y_train_res)
signature = infer_signature(X_train_res, y_train_res)
mlflow.sklearn.log_model(
lr,
"machine_failure_model_lr",
signature=signature,
registered_model_name="machine_failure_model_lr"
)
y_pred_train = lr.predict(X_train)
# Calculate the classification metrics for training data
f1_train = f1_score(y_train, y_pred_train, average='weighted')
accuracy_train = accuracy_score(y_train, y_pred_train)
recall_train = recall_score(y_train, y_pred_train, average='weighted')
# Log the classification metrics to MLflow
mlflow.log_metric("f1_score_train", f1_train)
mlflow.log_metric("accuracy_train", accuracy_train)
mlflow.log_metric("recall_train", recall_train)
# Print the run ID and the classification metrics
print("F1 score_train:", f1_train)
print("Accuracy_train:", accuracy_train)
print("Recall_train:", recall_train)
y_pred_test = lr.predict(X_test)
# Calculate the classification metrics for test data
f1_test = f1_score(y_test, y_pred_test, average='weighted')
accuracy_test = accuracy_score(y_test, y_pred_test)
recall_test = recall_score(y_test, y_pred_test, average='weighted')
# Log the classification metrics to MLflow
mlflow.log_metric("f1_score_test", f1_test)
mlflow.log_metric("accuracy_test", accuracy_test)
mlflow.log_metric("recall_test", recall_test)
Entraîner un classifieur XGBoost
from xgboost import XGBClassifier
with mlflow.start_run() as run:
xgb = XGBClassifier()
xgb_id = run.info.run_id
print(f"run_id {xgb_id}, status: {run.info.status}")
xgb.fit(X_train_res.to_numpy(), y_train_res.to_numpy())
signature = infer_signature(X_train_res, y_train_res)
mlflow.xgboost.log_model(
xgb,
"machine_failure_model_xgb",
signature=signature,
registered_model_name="machine_failure_model_xgb"
)
y_pred_train = xgb.predict(X_train)
# Calculate the classification metrics for training data
f1_train = f1_score(y_train, y_pred_train, average='weighted')
accuracy_train = accuracy_score(y_train, y_pred_train)
recall_train = recall_score(y_train, y_pred_train, average='weighted')
# Log the classification metrics to MLflow
mlflow.log_metric("f1_score_train", f1_train)
mlflow.log_metric("accuracy_train", accuracy_train)
mlflow.log_metric("recall_train", recall_train)
# Print the run ID and the classification metrics
print("F1 score_train:", f1_train)
print("Accuracy_train:", accuracy_train)
print("Recall_train:", recall_train)
y_pred_test = xgb.predict(X_test)
# Calculate the classification metrics for test data
f1_test = f1_score(y_test, y_pred_test, average='weighted')
accuracy_test = accuracy_score(y_test, y_pred_test)
recall_test = recall_score(y_test, y_pred_test, average='weighted')
# Log the classification metrics to MLflow
mlflow.log_metric("f1_score_test", f1_test)
mlflow.log_metric("accuracy_test", accuracy_test)
mlflow.log_metric("recall_test", recall_test)
Étape 5 : Sélectionner le meilleur modèle et prédire les sorties
Dans la section précédente, vous avez formé trois classifieurs différents : forêt aléatoire, régression logistique et XGBoost. Vous avez maintenant le choix d’accéder par programmation aux résultats ou d’utiliser l’interface utilisateur (IU).
Pour l’option chemin d’accès de l’interface utilisateur, accédez à votre espace de travail et filtrez les modèles.
Sélectionnez des modèles individuels pour plus d’informations sur les performances du modèle.
Cet exemple montre comment accéder par programmation aux modèles via MLflow :
runs = {'random forest classifier': rfc_id,
'logistic regression classifier': lr_id,
'xgboost classifier': xgb_id}
# Create an empty DataFrame to hold the metrics
df_metrics = pd.DataFrame()
# Loop through the run IDs and retrieve the metrics for each run
for run_name, run_id in runs.items():
metrics = mlflow.get_run(run_id).data.metrics
metrics["run_name"] = run_name
df_metrics = df_metrics.append(metrics, ignore_index=True)
# Print the DataFrame
print(df_metrics)
Bien que XGBoost génère les meilleurs résultats sur le jeu d’entraînement, il s’exécute mal sur le jeu de données de test. Cette mauvaise performance indique un surajustement. Le classifieur de régression logistique s’exécute mal sur les jeux de données d’entraînement et de test. Dans l’ensemble, la forêt aléatoire atteint un bon équilibre entre les performances d’entraînement et l’évitement de surajustement.
Dans la section suivante, choisissez le modèle de forêt aléatoire inscrit et effectuez une prédiction avec la fonctionnalité PREDICT :
from synapse.ml.predict import MLFlowTransformer
model = MLFlowTransformer(
inputCols=list(X_test.columns),
outputCol='predictions',
modelName='machine_failure_model_rf',
modelVersion=1
)
Avec l’objet MLFlowTransformer
que vous avez créé pour charger le modèle pour l’inférence, utilisez l’API Transformer pour noter le modèle sur le jeu de données de test :
predictions = model.transform(spark.createDataFrame(X_test))
predictions.show()
Ce tableau affiche la sortie :
Type | Température_de_l'air_[K] | Température_de_processus_[K] | Vitesse_de_rotation_[rpm] | Torque_[Nm] | Usure_de_l'outil_[min] | Prédictions |
---|---|---|---|---|---|---|
0 | 300.6 | 309.7 | 1639.0 | 30.4 | 121.0 | 0 |
0 | 303.9 | 313.0 | 1551,0 | 36.8 | 140.0 | 0 |
1 | 299.1 | 308,6 | 1491.0 | 38.5 | 166.0 | 0 |
0 | 300.9 | 312.1 | 1359.0 | 51.7 | 146.0 | 1 |
0 | 303.7 | 312.6 | 1621.0 | 38.8 | 182.0 | 0 |
0 | 299.0 | 310,3 | 1868.0 | 24.0 | 221,0 | 1 |
2 | 297.8 | 307.5 | 1631.0 | 31.3 | 124.0 | 0 |
0 | 297,5 | 308.2 | 1327.0 | 56.5 | 189.0 | 1 |
0 | 301.3 | 310.3 | 1460.0 | 41.5 | 197.0 | 0 |
2 | 297.6 | 309.0 | 1413.0 | 40.2 | 51.0 | 0 |
1 | 300.9 | 309.4 | 1724.0 | 25,6 | 119.0 | 0 |
0 | 303.3 | 311.3 | 1389.0 | 53.9 | 39.0 | 0 |
0 | 298.4 | 307.9 | 1981.0 | 23.2 | 16.0 | 0 |
0 | 299.3 | 308.8 | 1636.0 | 29,9 | 201.0 | 0 |
1 | 298.1 | 309.2 | 1460.0 | 45.8 | 80.0 | 0 |
0 | 300.0 | 309,5 | 1728.0 | 26.0 | 37.0 | 0 |
2 | 299.0 | 308.7 | 1940.0 | 19.9 | 98.0 | 0 |
0 | 302.2 | 310.8 | 1383.0 | 46.9 | 45.0 | 0 |
0 | 300.2 | 309.2 | 1431.0 | 51.3 | 57.0 | 0 |
0 | 299,6 | 310.2 | 1468.0 | 48.0 | 9.0 | 0 |
Enregistrez les données dans la lakehouse. Les données sont ensuite disponibles pour les utilisations ultérieures, par exemple un tableau de bord Power BI.
# Save test data to the lakehouse for use in the next section.
table_name = "predictive_maintenance_test_with_predictions"
predictions.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")
Étape 6 : Afficher l’intelligence décisionnelle via des visualisations dans Power BI
Affichez les résultats dans un format hors connexion, avec un tableau de bord Power BI.
Le tableau de bord montre que Tool_wear
et Torque
créent une limite notable entre les cas échoués et réussis, comme prévu à partir de l’analyse de corrélation précédente à l’étape 2.